Skip to content

Commit

Permalink
WIP: refactoring due to KnowledgeBase changes
Browse files Browse the repository at this point in the history
  • Loading branch information
alkidbaci committed Jan 6, 2025
1 parent 55c1484 commit ad51e7d
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 85 deletions.
24 changes: 16 additions & 8 deletions ontolearn/abstracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@
import logging
from abc import ABCMeta, abstractmethod
from typing import Set, List, Tuple, Iterable, TypeVar, Generic, ClassVar, Optional
from collections import OrderedDict

from owlapy.class_expression import OWLClassExpression
from owlapy.abstracts import AbstractOWLOntology
from owlapy.owl_individual import OWLNamedIndividual
from owlapy.utils import iter_count

from .data_struct import Experience
from .utils import read_csv
from collections import OrderedDict


_N = TypeVar('_N') #:
_KB = TypeVar('_KB', bound='AbstractKnowledgeBase') #:
Expand Down Expand Up @@ -393,15 +397,19 @@ def individuals_set(self, *args, **kwargs) -> Set:
pass

@abstractmethod
def concept_len(self, ce: OWLClassExpression) -> int:
"""Calculate the length of a concept.
def individuals(self, concept: Optional[OWLClassExpression] = None, named_individuals: bool = False) -> Iterable[OWLNamedIndividual]:
pass

Args:
ce: The concept to measure the length for.
@abstractmethod
def abox(self, *args, **kwargs):
pass

Returns:
Length of concept.
"""
@abstractmethod
def tbox(self, *args, **kwargs):
pass

@abstractmethod
def triples(self, *args, **kwargs):
pass


Expand Down
51 changes: 23 additions & 28 deletions ontolearn/concept_learner.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,47 +24,48 @@

"""Concept learning algorithms of Ontolearn."""

import logging
import operator
import time
from datetime import datetime
from contextlib import contextmanager
from itertools import islice, chain
from typing import Any, Callable, Dict, FrozenSet, Set, List, Tuple, Iterable, Optional, Union

import pandas as pd
import numpy as np
import torch
import os
import json
import glob

from datetime import datetime
from itertools import chain
from typing import Any, Callable, Dict, FrozenSet, Set, List, Tuple, Iterable, Optional, Union
from sortedcontainers import SortedSet

from torch.utils.data import DataLoader
from torch.functional import F
from torch.nn.utils.rnn import pad_sequence
from deap import gp, tools, base, creator

from owlapy.class_expression import OWLClassExpression
from owlapy.owl_individual import OWLNamedIndividual
from owlapy.owl_literal import OWLLiteral
from owlapy.owl_property import OWLDataProperty
from owlapy.abstracts import AbstractOWLReasoner
from torch.utils.data import DataLoader
from torch.functional import F
from torch.nn.utils.rnn import pad_sequence
from deap import gp, tools, base, creator
from owlapy.utils import EvaluatedDescriptionSet, ConceptOperandSorter
from owlapy.parser import DLSyntaxParser

from ontolearn.knowledge_base import KnowledgeBase
from ontolearn.abstracts import AbstractFitness, AbstractScorer, BaseRefinement, \
AbstractHeuristic, EncodedPosNegLPStandardKind
from ontolearn.base_concept_learner import BaseConceptLearner, RefinementBasedConceptLearner
from owlapy.utils import EvaluatedDescriptionSet, ConceptOperandSorter, OperandSetTransform
from ontolearn.abstracts import AbstractFitness, AbstractScorer, BaseRefinement, AbstractHeuristic
from ontolearn.base_concept_learner import BaseConceptLearner
from ontolearn.data_struct import NCESDataLoader, NCESDataLoaderInference, CLIPDataLoader, CLIPDataLoaderInference
from ontolearn.ea_algorithms import AbstractEvolutionaryAlgorithm, EASimple
from ontolearn.ea_initialization import AbstractEAInitialization, EARandomInitialization, EARandomWalkInitialization
from ontolearn.ea_utils import PrimitiveFactory, OperatorVocabulary, ToolboxVocabulary, Tree, escape, ind_to_string, \
owlliteral_to_primitive_string
from ontolearn.fitness_functions import LinearPressureFitness
from ontolearn.heuristics import OCELHeuristic
from ontolearn.learning_problem import PosNegLPStandard, EncodedPosNegLPStandard
from ontolearn.metrics import Accuracy
from ontolearn.refinement_operators import ExpressRefinement
from ontolearn.search import EvoLearnerNode, NCESNode, HeuristicOrderedNode, LBLNode, OENode, TreeNode, \
LengthOrderedNode, \
QualityOrderedNode, EvaluatedConcept
from ontolearn.utils import oplogging
from ontolearn.utils.static_funcs import init_length_metric, compute_tp_fn_fp_tn, evaluate_concept
from ontolearn.search import EvoLearnerNode, NCESNode, OENode, TreeNode, QualityOrderedNode
from ontolearn.utils.static_funcs import init_length_metric, compute_tp_fn_fp_tn
from ontolearn.quality_funcs import evaluate_concept
from ontolearn.value_splitter import AbstractValueSplitter, BinningValueSplitter, EntropyValueSplitter
from ontolearn.base_nces import BaseNCES
from ontolearn.nces_architectures import LSTM, GRU, SetTransformer
Expand All @@ -73,18 +74,12 @@
from ontolearn.nces_trainer import NCESTrainer, before_pad
from ontolearn.clip_trainer import CLIPTrainer
from ontolearn.nces_utils import SimpleSolution
from owlapy.render import DLSyntaxObjectRenderer
from owlapy.parser import DLSyntaxParser
from owlapy.utils import OrderedOWLObject
from sortedcontainers import SortedSet
import os
import json
import glob
from ontolearn.lp_generator import LPGen
from .learners import CELOE
from ontolearn.learners import CELOE

_concept_operand_sorter = ConceptOperandSorter()


class EvoLearner(BaseConceptLearner):
"""An evolutionary approach to learn concepts in ALCQ(D).
Expand Down
8 changes: 5 additions & 3 deletions ontolearn/knowledge_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from collections import Counter
from typing import Iterable, Optional, Callable, Union, FrozenSet, Set, Dict, cast, Generator
import owlapy
from owlapy import OntologyManager
from owlapy.class_expression import OWLClassExpression, OWLClass, OWLObjectSomeValuesFrom, OWLObjectAllValuesFrom, \
OWLThing, OWLObjectMinCardinality, OWLObjectOneOf
from owlapy.iri import IRI
Expand All @@ -46,7 +47,7 @@
from .abstracts import AbstractKnowledgeBase
from .concept_generator import ConceptGenerator
from owlapy.owl_hierarchy import ClassHierarchy, ObjectPropertyHierarchy, DatatypePropertyHierarchy
from .utils.static_funcs import (init_hierarchy_instances, init_named_individuals, init_individuals_from_concepts)
from .utils.static_funcs import init_hierarchy_instances
from owlapy.class_expression import OWLDataSomeValuesFrom
from owlapy.owl_data_ranges import OWLDataRange
from owlapy.class_expression import OWLDataOneOf
Expand Down Expand Up @@ -108,6 +109,7 @@ def __init__(self, *,
self.manager = ontology.get_owl_ontology_manager()
self.ontology = ontology
else:
self.manager = OntologyManager()
self.ontology = self.manager.load_ontology(IRI.create('file://' + self.path))

reasoner: AbstractOWLReasoner
Expand Down Expand Up @@ -152,9 +154,9 @@ def individuals(self, concept: Optional[OWLClassExpression] = None, named_indivi
"""
# named_individuals check must be supported by the reasoner .instances method
if concept:
return self.reasoner.instances(concept)
return frozenset(self.reasoner.instances(concept))
else:
return self.ontology.individuals_in_signature()
return frozenset(self.ontology.individuals_in_signature())

def abox(self, individual: Union[OWLNamedIndividual, Iterable[OWLNamedIndividual]] = None, mode='native'): # pragma: no cover
"""
Expand Down
2 changes: 1 addition & 1 deletion ontolearn/learners/celoe.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from ..abstracts import AbstractScorer, BaseRefinement, AbstractHeuristic, EncodedPosNegLPStandardKind
from ..learning_problem import PosNegLPStandard
from ..quality_funcs import evaluate_concept
from ..search import OENode, TreeNode, EvaluatedConcept, HeuristicOrderedNode, QualityOrderedNode, LengthOrderedNode

from typing import Optional, Union, Iterable, Dict
Expand All @@ -17,7 +18,6 @@
from itertools import islice
from owlapy.render import DLSyntaxObjectRenderer

from ..utils.static_funcs import evaluate_concept

_concept_operand_sorter = ConceptOperandSorter()

Expand Down
2 changes: 1 addition & 1 deletion ontolearn/learning_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def __init__(self,
# def encode_kb(self, knowledge_base: 'KnowledgeBase') -> EncodedPosNegLPStandard:
# return knowledge_base.encode_learning_problem(self)

def encode_learning_problem(self, kb: 'KnowledgeBase') -> EncodedPosNegLPStandard:
def encode_kb(self, kb: 'KnowledgeBase') -> EncodedPosNegLPStandard:
"""
Provides the encoded learning problem (lp), i.e. the class containing the set of OWLNamedIndividuals
as follows:
Expand Down
27 changes: 27 additions & 0 deletions ontolearn/quality_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
# -----------------------------------------------------------------------------

from typing import Set
from owlapy.class_expression import OWLClassExpression
from ontolearn.abstracts import EncodedLearningProblem, AbstractScorer
from ontolearn.knowledge_base import KnowledgeBase
from ontolearn.search import EvaluatedConcept


def f1(*, individuals: Set, pos: Set, neg: Set):
Expand Down Expand Up @@ -64,3 +68,26 @@ def acc(*, individuals: Set, pos: Set, neg: Set):
fp = len(neg.intersection(individuals))
fn = len(pos.difference(individuals))
return (tp + tn) / (tp + tn + fp + fn)


def evaluate_concept(kb: KnowledgeBase, concept: OWLClassExpression, quality_func: AbstractScorer,
encoded_learning_problem: EncodedLearningProblem) -> EvaluatedConcept:
"""Evaluates a concept by using the encoded learning problem examples, in terms of Accuracy or F1-score.
Note:
This method is useful to tell the quality (e.q) of a generated concept by the concept learners, to get
the set of individuals (e.inds) that are classified by this concept and the amount of them (e.ic).
Args:
kb: The knowledge base where to evaluate the concept.
concept: The concept to be evaluated.
quality_func: Quality measurement in terms of Accuracy or F1-score.
encoded_learning_problem: The encoded learning problem.
Return:
The evaluated concept.
"""

e = EvaluatedConcept()
e.inds = kb.individuals_set(concept)
e.ic = len(e.inds)
_, e.q = quality_func.score_elp(e.inds, encoded_learning_problem)
return e
54 changes: 10 additions & 44 deletions ontolearn/utils/static_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,37 +21,25 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# -----------------------------------------------------------------------------
from itertools import chain
from typing import Optional, Callable, Tuple, Generator, List, Union, Final
import pandas
import matplotlib.pyplot as plt
import sklearn
import numpy as np
from owlapy.class_expression import OWLClass, OWLClassExpression
import traceback

from itertools import chain
from typing import Optional, Callable, Tuple, Generator, List, Union, Final
from tqdm import tqdm
from typing import Set, Iterable

from owlapy.iri import IRI
from owlapy.owl_axiom import OWLEquivalentClassesAxiom
from owlapy.abstracts import AbstractOWLOntology, AbstractOWLOntologyManager
from owlapy.owl_ontology_manager import OntologyManager
from owlapy.owl_hierarchy import ClassHierarchy, ObjectPropertyHierarchy, DatatypePropertyHierarchy
from owlapy.utils import OWLClassExpressionLengthMetric, LRUCache
import traceback
from tqdm import tqdm
from ontolearn.abstracts import EncodedLearningProblem, AbstractScorer
from ontolearn.search import EvaluatedConcept
from typing import Set, Iterable
from owlapy.class_expression import (
OWLQuantifiedObjectRestriction,
OWLObjectCardinalityRestriction,
)
from owlapy.class_expression import (
OWLObjectUnionOf,
OWLObjectIntersectionOf,
OWLObjectSomeValuesFrom,
OWLObjectAllValuesFrom,
OWLObjectMinCardinality,
OWLObjectMaxCardinality,
OWLObjectOneOf,
)
from owlapy.class_expression import OWLQuantifiedObjectRestriction, OWLObjectCardinalityRestriction, \
OWLObjectMinCardinality, OWLObjectMaxCardinality, OWLClass, OWLClassExpression


def f1_set_similarity(y: Set[str], yhat: Set[str]) -> float:
Expand Down Expand Up @@ -257,6 +245,7 @@ def compute_f1_score_from_confusion_matrix(confusion_matrix:dict)->float:
f_1 = 2 * ((precision * recall) / (precision + recall))
return f_1


def plot_umap_reduced_embeddings(X: pandas.DataFrame, y: List[float], name: str = "umap_visualization.pdf") -> None: # pragma: no cover
# TODO:AB: 'umap' is not part of the dependencies !?
import umap
Expand Down Expand Up @@ -414,26 +403,3 @@ def verbalize(predictions_file_path: str): # pragma: no cover
print("Image generated successfully!")
else:
print("Images generated successfully!")


def evaluate_concept(kb: 'KnowledgeBase', concept: OWLClassExpression, quality_func: AbstractScorer,
encoded_learning_problem: EncodedLearningProblem) -> EvaluatedConcept:
"""Evaluates a concept by using the encoded learning problem examples, in terms of Accuracy or F1-score.
Note:
This method is useful to tell the quality (e.q) of a generated concept by the concept learners, to get
the set of individuals (e.inds) that are classified by this concept and the amount of them (e.ic).
Args:
kb: The knowledge base where to evaluate the concept.
concept: The concept to be evaluated.
quality_func: Quality measurement in terms of Accuracy or F1-score.
encoded_learning_problem: The encoded learning problem.
Return:
The evaluated concept.
"""

e = EvaluatedConcept()
e.inds = kb.individuals_set(concept)
e.ic = len(e.inds)
_, e.q = quality_func.score_elp(e.inds, encoded_learning_problem)
return e

0 comments on commit ad51e7d

Please sign in to comment.