Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 49 additions & 44 deletions docs/source/gettingstarted/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,25 @@ Introduction

.. raw:: html

<div align="center">
<img src="https://raw.githubusercontent.com/sciknoworg/OntoAligner/refs/heads/dev/docs/source/img/ontoaligner-pip.jpg" alt="OntoAligner Overview" width="90%"/>
</div>
<div align="center">
<img src="https://raw.githubusercontent.com/sciknoworg/OntoAligner/refs/heads/dev/docs/source/img/ontoaligner-pip.jpg" alt="OntoAligner Overview" width="90%"/>
</div>

OntoAligner is a modular, extensible, and efficient framework for ontology alignment that integrates classical heuristics, retrieval-based methods, and large language models (LLMs). It is designed to support a wide range of ontology alignment (OA) scenarios—from lightweight matching to advanced semantic reasoning—with built-in support for evaluation and export.


.. tab:: 🧩 Parser



The ``Parser`` module serves as the entry point of OntoAligner, handling ontology ingestion and alignment data loading. Key components include:

1) ``OntologyParser`` that supports loading ontologies and extracts class/property names, IRIs, hierarchies, synonyms, annotations, and any relevant informations.
1) ``OntologyParser`` that supports loading ontologies and extracts class/property names, IRIs, hierarchies, synonyms, annotations, and any relevant information.

2) ``AlignmentsParser`` for loading ground truth alignments used for evaluation. However, in cases where a specific dataset does not support references, this module may be ignored.

.. note::

🔧 Checkout parsers at `Developer Guide > Parsers <../developerguide/parsers.html>`_

::


Expand Down Expand Up @@ -109,63 +108,69 @@ Usage

pip install -U OntoAligner

See `installation <installation.html>`_ for further installation options.
.. note::

See `installation <installation.html>`_ for further installation options.

::


.. tab:: 🚀 Quickstart

See the `Quickstart <quickstart.html>`_ for more quick information on how to use OntoAligner.
Working with OntoAligner is straightforward:

::
.. code-block:: python

from ontoaligner.ontology import MaterialInformationMatOntoOMDataset
from ontoaligner.utils import metrics, xmlify
from ontoaligner.aligner import MistralLLMBERTRetrieverRAG
from ontoaligner.encoder import ConceptParentRAGEncoder
from ontoaligner.postprocess import rag_hybrid_postprocessor

Working with OntoAligner is straightforward:
# Step 1: Initialize the dataset object for MaterialInformation MatOnto dataset
task = MaterialInformationMatOntoOMDataset()
print("Test Task:", task)

.. code-block:: python
# Step 2: Load source and target ontologies along with reference matchings
dataset = task.collect(
source_ontology_path="assets/MI-MatOnto/mi_ontology.xml",
target_ontology_path="assets/MI-MatOnto/matonto_ontology.xml",
reference_matching_path="assets/MI-MatOnto/matchings.xml"
)

from ontoaligner.ontology import MaterialInformationMatOntoOMDataset
from ontoaligner.utils import metrics, xmlify
from ontoaligner.aligner import MistralLLMBERTRetrieverRAG
from ontoaligner.encoder import ConceptParentRAGEncoder
from ontoaligner.postprocess import rag_hybrid_postprocessor
# Step 3: Encode the source and target ontologies
encoder_model = ConceptParentRAGEncoder()
encoded_ontology = encoder_model(source=dataset['source'], target=dataset['target'])

# Step 1: Initialize the dataset object for MaterialInformation MatOnto dataset
task = MaterialInformationMatOntoOMDataset()
print("Test Task:", task)
# Step 4: Define configuration for retriever and LLM
retriever_config = {"device": 'cuda', "top_k": 5,}
llm_config = {"device": "cuda", "max_length": 300, "max_new_tokens": 10, "batch_size": 15}

# Step 2: Load source and target ontologies along with reference matchings
dataset = task.collect(
source_ontology_path="assets/MI-MatOnto/mi_ontology.xml",
target_ontology_path="assets/MI-MatOnto/matonto_ontology.xml",
reference_matching_path="assets/MI-MatOnto/matchings.xml"
)
# Step 5: Initialize Generate predictions using RAG-based ontology matcher
model = MistralLLMBERTRetrieverRAG(retriever_config=retriever_config, llm_config=llm_config)
model.load(llm_path = "mistralai/Mistral-7B-v0.3", ir_path="all-MiniLM-L6-v2")
predicts = model.generate(input_data=encoded_ontology)

# Step 3: Encode the source and target ontologies
encoder_model = ConceptParentRAGEncoder()
encoded_ontology = encoder_model(source=dataset['source'], target=dataset['target'])
# Step 6: Apply hybrid postprocessing
hybrid_matchings, hybrid_configs = rag_hybrid_postprocessor(predicts=predicts,
ir_score_threshold=0.1,
llm_confidence_th=0.8)

# Step 4: Define configuration for retriever and LLM
retriever_config = {"device": 'cuda', "top_k": 5,}
llm_config = {"device": "cuda", "max_length": 300, "max_new_tokens": 10, "batch_size": 15}
evaluation = metrics.evaluation_report(predicts=hybrid_matchings, references=dataset['reference'])
print("Hybrid Matching Evaluation Report:", evaluation)

# Step 5: Initialize Generate predictions using RAG-based ontology matcher
model = MistralLLMBERTRetrieverRAG(retriever_config=retriever_config, llm_config=llm_config)
model.load(llm_path = "mistralai/Mistral-7B-v0.3", ir_path="all-MiniLM-L6-v2")
predicts = model.generate(input_data=encoded_ontology)
# Step 7: Convert matchings to XML format and save the XML representation
xml_str = xmlify.xml_alignment_generator(matchings=hybrid_matchings)
open("matchings.xml", "w", encoding="utf-8").write(xml_str)

# Step 6: Apply hybrid postprocessing
hybrid_matchings, hybrid_configs = rag_hybrid_postprocessor(predicts=predicts,
ir_score_threshold=0.1,
llm_confidence_th=0.8)
.. note::

See the `Quickstart <quickstart.html>`_ for more quick information on how to use OntoAligner.


::

evaluation = metrics.evaluation_report(predicts=hybrid_matchings, references=dataset['reference'])
print("Hybrid Matching Evaluation Report:", evaluation)

# Step 7: Convert matchings to XML format and save the XML representation
xml_str = xmlify.xml_alignment_generator(matchings=hybrid_matchings)
open("matchings.xml", "w", encoding="utf-8").write(xml_str)

What is Next?
----------------
Expand Down
149 changes: 147 additions & 2 deletions ontoaligner/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
Ontology Alignment Pipeline. Various methods such as lightweight matching, retriever-based matching, LLM-based matching,
and RAG (Retriever-Augmented Generation) techniques has been applied.

AlignerPipeline runs user-provided encoder, aligner and optional postprocessor components over a collected ontology matching dataset. Unlike
AlignerPipeline runs user-provided encoder, aligner and optional postprocessor & reranker components over a collected ontology matching dataset. Unlike
OntoAlignerPipeline, it does not collect datasets, select methods, evaluate results, or save outputs.
"""
import json
Expand Down Expand Up @@ -53,7 +53,7 @@ class AlignerPipeline(BaseOMModel):

This class follows the standard OntoAligner flow for one aligner pipeline:
encode the ontology matching dataset, load the aligner if needed, generate predictions,
and optionally apply a postprocessor.
and optionally apply a reranker & postprocessor.
"""

def __init__(
Expand All @@ -65,6 +65,10 @@ def __init__(
llm_dataset_class: Dataset = None,
batch_size: int = 1,
shuffle: bool = False,
reranker: BaseOMModel = None,
reranker_load_params: Dict = None,
reranker_encoder: BaseEncoder = None,
reranker_om_dataset: Dict = None,
postprocessor: Any = None,
postprocessor_params: Dict = None,
include_reference: bool = False,
Expand All @@ -81,6 +85,10 @@ def __init__(
llm_dataset_class (Dataset, optional): Dataset class used to wrap LLM inputs. Defaults to None.
batch_size (int, optional): Batch size used for LLM dataset generation. Defaults to 1.
shuffle (bool, optional): Whether to shuffle LLM dataset batches. Defaults to False.
reranker (BaseOMModel, optional): Optional reranking model used to reorder candidate predictions. Defaults to None.
reranker_load_params (Dict, optional): Parameters forwarded to the reranker load method. Defaults to None.
reranker_encoder (BaseEncoder, optional): Optional encoder used to prepare source and target ontologies text for reranking. Defaults to None.
reranker_om_dataset (Dict, optional): Optional ontology matching dataset used by the reranker encoder. Defaults to None.
postprocessor (Any, optional): Optional postprocessor applied to predictions. Defaults to None.
postprocessor_params (Dict, optional): Optional parameters forwarded to the postprocessor. Defaults to None.
include_reference (bool, optional): Whether to pass reference matchings to the encoder. Defaults to False.
Expand All @@ -94,6 +102,10 @@ def __init__(
self.llm_dataset_class = llm_dataset_class
self.batch_size = batch_size
self.shuffle = shuffle
self.reranker = reranker
self.reranker_load_params = reranker_load_params or {}
self.reranker_encoder = reranker_encoder
self.reranker_om_dataset = reranker_om_dataset
self.postprocessor = postprocessor
self.postprocessor_params = postprocessor_params or {}
self.include_reference = include_reference
Expand Down Expand Up @@ -157,6 +169,132 @@ def _load_aligner(self) -> None:
if hasattr(self.aligner, "load") and self.load_params:
self.aligner.load(**self.load_params)

def _load_reranker(self) -> None:
"""
Loads the optional reranking model when reranker load parameters are provided.
"""
if self.reranker is not None and hasattr(self.reranker, "load") and self.reranker_load_params:
self.reranker.load(**self.reranker_load_params)

def _is_grouped_candidate_output(self, predictions: List) -> bool:
"""
Checks whether predictions are already in grouped candidate format.

Grouped candidate format:
[
{
"source": source_iri,
"target-cands": [...],
"score-cands": [...],
},
...
]
"""
if not isinstance(predictions, list) or not predictions:
return False

first_prediction = predictions[0]

return isinstance(first_prediction, dict) and all(
key in first_prediction
for key in ["source", "target-cands", "score-cands"]
)

def _group_predictions(self, predictions: List) -> List:
"""
Converts flat source-target-score predictions into grouped candidate format.

Parameters:
predictions (List): Flat alignment predictions generated by an aligner.

Returns:
List: Grouped candidate predictions that can be passed to a reranker.
"""
grouped_predictions = {}

for prediction in predictions:
source = prediction["source"]
target = prediction["target"]
score = prediction.get("score", 1.0)

if source not in grouped_predictions:
grouped_predictions[source] = {
"source": source,
"target-cands": [],
"score-cands": [],
}

grouped_predictions[source]["target-cands"].append(target)
grouped_predictions[source]["score-cands"].append(float(score))

return list(grouped_predictions.values())

def _encode_reranker(self, om_dataset: Dict, encoded_data: List) -> List:
"""
Encodes source and target ontologies for the optional reranker.

This is mostly used when the main pipeline encoder produces non-textual
representations, such as graph triples, while the reranker requires
source and target concept text.

Parameters:
om_dataset (Dict): The ontology matching dataset.
encoded_data (List): Encoded data produced by the main pipeline encoder.

Returns:
List: Source and target ontology representations used by the reranker.
"""
if self.reranker_encoder is None:
return encoded_data

reranker_om_dataset = self.reranker_om_dataset or om_dataset

return self.reranker_encoder(
source=reranker_om_dataset["source"],
target=reranker_om_dataset["target"],
)

def _apply_reranker(
self,
predictions: List,
encoded_data: List,
om_dataset: Dict,
) -> List:
"""
Applies the optional reranker to generated predictions.

Parameters:
predictions (List): Predictions generated by the aligner.
encoded_data (List): Encoded data produced by the main pipeline encoder.
om_dataset (Dict): The ontology matching dataset.

Returns:
List: Reranked predictions.
"""
if self.reranker is None:
return predictions

self._load_reranker()

if not self._is_grouped_candidate_output(predictions):
predictions = self._group_predictions(
predictions=predictions,
)

reranker_encoded_data = self._encode_reranker(
om_dataset=om_dataset,
encoded_data=encoded_data,
)

return self.reranker.generate(
input_data=[
reranker_encoded_data[0],
reranker_encoded_data[1],
predictions,
]
)


def _generate_llm_predictions(self, llm_dataset: Dataset) -> List:
"""
Generates LLM predictions from an LLM dataset using batched prompts.
Expand Down Expand Up @@ -245,6 +383,13 @@ def generate(self, input_data: Dict = None) -> List:
else:
predictions = self.aligner.generate(input_data=encoded_data)

if self.reranker is not None:
predictions = self._apply_reranker(
predictions=predictions,
encoded_data=encoded_data,
om_dataset=om_dataset,
)

if self.postprocessor is not None:
predictions = self._apply_postprocessor(
predictions=predictions,
Expand Down
Loading
Loading