From 497be832841950d1380c60592dbe6828a42142fa Mon Sep 17 00:00:00 2001 From: Caglar Demir Date: Fri, 1 Dec 2023 19:58:58 +0100 Subject: [PATCH] Example of learning dl concepts and using them added --- README.md | 62 ++++++++++++++++++++++++++++++- ontolearn/base_concept_learner.py | 6 ++- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f490d770..03b69cf0 100644 --- a/README.md +++ b/README.md @@ -29,9 +29,66 @@ python -m pytest tests pytest -p no:warnings -x # Runs > tests leading to > 15 mins ``` +## Description Logic Concept Learning +```python +from ontolearn.concept_learner import CELOE +from ontolearn.knowledge_base import KnowledgeBase +from ontolearn.learning_problem import PosNegLPStandard +from ontolearn.search import EvoLearnerNode +from owlapy.model import OWLClass, OWLClassAssertionAxiom, OWLNamedIndividual, IRI, OWLObjectProperty, OWLObjectPropertyAssertionAxiom +from owlapy.render import DLSyntaxObjectRenderer +# (1) Load a knowledge graph. +kb = KnowledgeBase(path='KGs/father.owl') +# (2) Initialize a learner. +model = CELOE(knowledge_base=kb) +# (3) Define a description logic concept learning problem. +lp = PosNegLPStandard(pos={OWLNamedIndividual(IRI.create("http://example.com/father#stefan")), + OWLNamedIndividual(IRI.create("http://example.com/father#markus")), + OWLNamedIndividual(IRI.create("http://example.com/father#martin"))}, + neg={OWLNamedIndividual(IRI.create("http://example.com/father#heinz")), + OWLNamedIndividual(IRI.create("http://example.com/father#anna")), + OWLNamedIndividual(IRI.create("http://example.com/father#michelle"))}) +# (4) Learn description logic concepts best fitting (3). +dl_classifiers=model.fit(learning_problem=lp).best_hypotheses(2) + +# (5) Inference over unseen individuals +namespace = 'http://example.com/father#' +# (6) New Individuals +julia = OWLNamedIndividual(IRI.create(namespace, 'julia')) +julian = OWLNamedIndividual(IRI.create(namespace, 'julian')) +thomas = OWLNamedIndividual(IRI.create(namespace, 'thomas')) +# (7) OWLClassAssertionAxiom about (6) +male = OWLClass(IRI.create(namespace, 'male')) +female = OWLClass(IRI.create(namespace, 'female')) +axiom1 = OWLClassAssertionAxiom(individual=julia, class_expression=female) +axiom2 = OWLClassAssertionAxiom(individual=julian, class_expression=male) +axiom3 = OWLClassAssertionAxiom(individual=thomas, class_expression=male) +# (8) OWLObjectPropertyAssertionAxiom about (6) +has_child = OWLObjectProperty(IRI.create(namespace, 'hasChild')) +# Existing Individuals +anna = OWLNamedIndividual(IRI.create(namespace, 'anna')) +markus = OWLNamedIndividual(IRI.create(namespace, 'markus')) +michelle = OWLNamedIndividual(IRI.create(namespace, 'michelle')) +axiom4 = OWLObjectPropertyAssertionAxiom(subject=thomas, property_=has_child, object_=julian) +axiom5 = OWLObjectPropertyAssertionAxiom(subject=julia, property_=has_child, object_=julian) + +# 4. Use loaded class expressions for predictions +predictions = model.predict(individuals=[julia, julian, thomas, anna, markus, michelle], + axioms=[axiom1, axiom2, axiom3, axiom4, axiom5], + hypotheses=dl_classifiers) +print(predictions) +""" + (¬female) ⊓ (∃ hasChild.⊤) male +julia 0.0 0.0 +julian 0.0 1.0 +thomas 1.0 1.0 +anna 0.0 0.0 +markus 1.0 1.0 +michelle 0.0 0.0 +""" +``` - -## Learning Description Logic Concept +We have already many algorithms ready to use ```python from ontolearn.knowledge_base import KnowledgeBase from ontolearn.concept_learner import CELOE, OCEL, EvoLearner, Drill @@ -64,6 +121,7 @@ print(f"OCEL:{preds_ocel[0]}") print(f"DL-CELOE:{preds_dl_celoe[0]}") ``` + Fore more please refer to the [examples](https://github.com/dice-group/Ontolearn/tree/develop/examples) folder. diff --git a/ontolearn/base_concept_learner.py b/ontolearn/base_concept_learner.py index b74c0ac6..58901952 100644 --- a/ontolearn/base_concept_learner.py +++ b/ontolearn/base_concept_learner.py @@ -233,7 +233,7 @@ def _assign_labels_to_individuals(self, individuals: List[OWLNamedIndividual], return labels def predict(self, individuals: List[OWLNamedIndividual], - hypotheses: Optional[List[Union[_N, OWLClassExpression]]] = None, + hypotheses: Optional[ Union[OWLClassExpression, List[Union[_N, OWLClassExpression]]]] = None, axioms: Optional[List[OWLAxiom]] = None, n: int = 10) -> pd.DataFrame: """Creates a binary data frame showing for each individual whether it is entailed in the given hypotheses @@ -273,8 +273,10 @@ def predict(self, individuals: List[OWLNamedIndividual], if hypotheses is None: hypotheses = [hyp.concept for hyp in self.best_hypotheses(n)] + elif isinstance(hypotheses,list): + hypotheses = [(hyp.concept if isinstance(hyp, AbstractConceptNode) else hyp) for hyp in hypotheses] else: - hypotheses = [(hyp.concept if isinstance(hyp, AbstractConceptNode) else hyp) for hyp in hypotheses] + hypotheses=[hypotheses] renderer = DLSyntaxObjectRenderer() predictions = pd.DataFrame(data=self._assign_labels_to_individuals(individuals, hypotheses, reasoner),