Skip to content

Entity Alignment with StringSimilarityLinker

This aligns two small knowledge graphs from ToyEADataset describing the same three cities, but kg2's labels append the country name ("Paris" vs. "Paris, France"), so an exact label match would miss every pair. LabelOverlap blocking (character n-gram overlap) finds the candidates despite the mismatch, and StringSimilarityLinker picks the best one per source entity by Jaccard token overlap on the label field. LeskLinker (see the Lesk example) is a preconfigured instance of this same class (source_field="context", target_field="description", metric="word_overlap").

"""Entity Alignment baseline with StringSimilarityLinker.

Aligns two small knowledge graphs describing the same three cities, but
with slightly different labels (kg2 appends the country name), so an
exact label match would miss all three pairs. LabelOverlap blocking
(character n-gram overlap) finds the candidates despite the mismatch,
and StringSimilarityLinker picks the best one by Jaccard token overlap.

Run with: `uv run python examples/string_similarity_ea.py`
"""

from linkingtk.algorithms.string_similarity import StringSimilarityLinker
from linkingtk.blocking import LabelOverlap
from linkingtk.datasets import ToyEADataset
from linkingtk.eval import Evaluator


def main() -> None:
    kg1, kg2, ground_truth = ToyEADataset().load()

    linker = StringSimilarityLinker(source_field="label", target_field="label", metric="jaccard")
    results = linker.link(kg1, kg2, blocking=LabelOverlap(max_matches=3))

    for result in results:
        print(f"{result.source_id} -> {result.target_id} (score={result.score:.2f})")

    predictions = [(r.source_id, r.target_id) for r in results]
    report = Evaluator.evaluate(predictions=predictions, ground_truth=ground_truth)
    print("Metrics:", report.metrics)


if __name__ == "__main__":
    main()

Run with:

uv run python examples/string_similarity_ea.py
kg1:paris -> kg2:paris (score=0.50)
kg1:berlin -> kg2:berlin (score=0.50)
kg1:rome -> kg2:rome (score=0.50)
Metrics: {'precision@1': 1.0, 'recall': 1.0, 'f1': 1.0}