ontolearn.lp_generator

Submodules

Classes

LPGen

KB2Data

This class takes an owl file, loads it into a knowledge base using ontolearn.knowledge_base.KnowledgeBase.

ComplexityProfile

A named point (or curriculum step) in the space of "how complex should the target be".

DLConstruct

DL constructors a ComplexityProfile can allow/forbid.

GeneratedLearningProblem

A goal-directed learning problem: a sampled target concept plus its (E+, E-).

GoalDirectedLPGenerator

Samples target concepts from an explicit DL-construct grammar and turns them into LPs.

Functions

save_benchmark(→ None)

Serialize a benchmark (as returned by GoalDirectedLPGenerator.generate_benchmark())

Package Contents

class ontolearn.lp_generator.LPGen(kb_path=None, kb=None, storage_path=None, max_num_lps=1000, beyond_alc=False, depth=3, max_child_length=20, refinement_expressivity=0.2, downsample_refinements=True, sample_fillers_count=10, num_sub_roots=50, min_num_pos_examples=1, max_pos_neg_examples_per_lp=None, random_seed=None)[source]
lp_gen
generate()[source]
class ontolearn.lp_generator.KB2Data(path=None, storage_path=None, max_num_lps=1000, beyond_alc=False, depth=3, max_child_length=20, refinement_expressivity=0.2, downsample_refinements=True, sample_fillers_count=10, num_sub_roots=50, min_num_pos_examples=1, knowledge_base=None, max_pos_neg_examples_per_lp=None, random_seed=None)[source]

This class takes an owl file, loads it into a knowledge base using ontolearn.knowledge_base.KnowledgeBase. A refinement operator is used to generate a large number of concepts, from which we filter and retain the shortest non-redundant concepts. We export each concept and its instances (eventually positive and negative examples) into a json file.

rnd
max_num_lps = 1000
beyond_alc = False
dl_syntax_renderer
knowledge_base = None
min_num_pos_examples = 1
atomic_concept_names
lp_gen
find_optimal_number_of_examples()[source]
generate_descriptions()[source]
sample_examples(pos, neg)[source]
save_data()[source]
class ontolearn.lp_generator.ComplexityProfile[source]

A named point (or curriculum step) in the space of “how complex should the target be”.

Parameters:
  • name – identifier used to tag generated problems and group benchmark results.

  • allowed_constructs – DL constructors GoalDirectedLPGenerator.generate() may use when sampling a target concept. Relation-based constructs (∃/∀/cardinality/has-value) are silently unavailable on a knowledge base exposing no object properties.

  • min_length/max_length – bounds on concept_len of the (NNF) target.

  • min_depth/max_depth – bounds on restriction-nesting depth (see GoalDirectedLPGenerator.concept_depth()); a bare named class has depth 0.

  • max_arity – maximum number of operands sampled under one intersection/union.

  • card_limit – cardinality restrictions sample n uniformly from [1, card_limit].

  • use_inverse_roles – if True, restrictions may use r- in place of r.

  • min_pos/min_neg – an LP is discarded unless the target has at least this many positive and negative instances in the knowledge base.

  • max_examples_per_side – positives/negatives are subsampled down to this cap.

  • max_baseline_f1 – an LP is discarded if the best of a pool of “cheap” one-step hypotheses (an atomic class, its negation, or a bare exists r.Top) already reaches this F1 – i.e. it is trivially solvable without the constructs being tested.

  • min_difficulty – an LP is discarded if its DifficultyWeights-weighted score falls below this bar. 0.0 (default) disables this filter.

  • oversample_factor – GoalDirectedLPGenerator.generate() collects up to num_lps * oversample_factor passing candidates (subject to max_attempts) before ranking by difficulty and keeping the hardest num_lps – i.e. it actively searches for hard problems instead of returning the first ones found.

  • hard_negative_ratio – fraction of the sampled negatives drawn from the near-miss pool (when one exists) rather than arbitrary non-instances.

  • difficulty_weights – see DifficultyWeights.

name: str
allowed_constructs: FrozenSet[DLConstruct]
min_length: int = 1
max_length: int = 10
min_depth: int = 0
max_depth: int = 3
max_arity: int = 3
card_limit: int = 5
use_inverse_roles: bool = False
min_pos: int = 3
min_neg: int = 3
max_examples_per_side: int = 200
max_baseline_f1: float = 0.9
min_difficulty: float = 0.0
oversample_factor: int = 4
hard_negative_ratio: float = 0.5
difficulty_weights: DifficultyWeights
class ontolearn.lp_generator.DLConstruct(*args, **kwds)[source]

Bases: enum.Enum

DL constructors a ComplexityProfile can allow/forbid.

ATOMIC = 'atomic'
NEGATION = 'negation'
INTERSECTION = 'intersection'
UNION = 'union'
EXISTENTIAL = 'existential'
UNIVERSAL = 'universal'
MIN_CARDINALITY = 'min_cardinality'
MAX_CARDINALITY = 'max_cardinality'
EXACT_CARDINALITY = 'exact_cardinality'
HAS_VALUE = 'has_value'
class ontolearn.lp_generator.GeneratedLearningProblem[source]

A goal-directed learning problem: a sampled target concept plus its (E+, E-).

profile_name: str
target_concept: owlapy.class_expression.OWLClassExpression
dl: str
pos: Individuals
neg: Individuals
length: int
depth: int
construct_histogram: Dict[str, int]
baseline_f1: float
difficulty: float
num_near_miss_negatives: int
to_lp() → PosNegLPStandard[source]

Build the PosNegLPStandard consumed by Ontolearn learners (e.g. TDL).

class ontolearn.lp_generator.GoalDirectedLPGenerator(knowledge_base: KnowledgeBase, seed: int | None = None, probe_cap: int = 300)[source]

Samples target concepts from an explicit DL-construct grammar and turns them into LPs.

Usage:

kb = KnowledgeBase(path="KGs/Family/family-benchmark_rich_background.owl")
gen = GoalDirectedLPGenerator(kb, seed=1)
profile = ComplexityProfile(
    name="nested-existential",
    allowed_constructs=frozenset({DLConstruct.EXISTENTIAL, DLConstruct.INTERSECTION}),
    max_length=8, max_depth=3,
)
lps = gen.generate(profile, num_lps=10)
model = TDL(kb).fit(lps[0].to_lp())
kb
rng
all_individuals: Individuals
atomic_classes: List[owlapy.class_expression.OWLClass]
object_properties: List[owlapy.owl_property.OWLObjectProperty]
baseline_f1(pos: Individuals, neg: Individuals) → float[source]

Best F1 any single “cheap” one-step hypothesis reaches on (pos, neg).

near_miss_negatives(target: owlapy.class_expression.OWLClassExpression, pos: Individuals) → Individuals[source]

Individuals satisfying target with exactly one top-level conjunct dropped, minus pos.

E.g. for C = Compound ⊓ (∃ hasChild.Father) these are individuals that are a Compound but whose child (if any) isn’t a Father, or that have a Father child but aren’t a Compound – the negatives one ablated conjunct away from being positive, which is exactly what trips up a greedy top-down learner.

static difficulty_score(profile: ComplexityProfile, length: int, depth: int, base_f1: float, pos: Individuals, near_miss: Individuals) → float[source]

Combine length/depth/baseline-hardness/near-miss-density into one score in [0, 1].

static concept_depth(ce: owlapy.class_expression.OWLClassExpression) → int[source]

Restriction-nesting depth: a named class or has value atom has depth 0.

sample_target(profile: ComplexityProfile) → Tuple[owlapy.class_expression.OWLClassExpression, collections.Counter][source]

Sample one target concept (in NNF) respecting profile, plus its construct histogram.

generate(profile: ComplexityProfile, num_lps: int, max_attempts: int = 3000) → List[GeneratedLearningProblem][source]

Sample the num_lps hardest distinct, non-trivial learning problems matching profile: up to num_lps * profile.oversample_factor passing candidates are collected (subject to max_attempts sampling attempts total), ranked by difficulty_score() and the top num_lps are kept.

generate_benchmark(profiles: Sequence[ComplexityProfile], num_lps_per_profile: int = 5, max_attempts_per_profile: int = 3000) → Dict[str, List[GeneratedLearningProblem]][source]

Run generate() for each profile in a curriculum; returns {profile.name: […]}.

ontolearn.lp_generator.save_benchmark(benchmark: Dict[str, List[GeneratedLearningProblem]], path: str) → None[source]

Serialize a benchmark (as returned by GoalDirectedLPGenerator.generate_benchmark()) to JSON: {dl_string: {“profile”, “positive_examples”, “negative_examples”, “length”, “depth”, “construct_histogram”, “baseline_f1”, “difficulty”, “num_near_miss_negatives”}}, individuals kept as full IRIs.