Files
semantica/docs/reference/deduplication.md
T
KaifAhmad1 3b637ea140 docs(reference): fix class names and expand API coverage across 8 modules
- normalize: replace non-existent DataNormalizer with correct classes (TextNormalizer, EntityNormalizer, DateNormalizer, NumberNormalizer, DataCleaner)
- deduplication: replace non-existent EntityResolver with correct API (DuplicateDetector, EntityMerger, SimilarityCalculator, ClusterBuilder)
- reasoning: replace non-existent ReasoningEngine/DeductiveEngine/AbductiveEngine with correct classes (Reasoner, GraphReasoner, ReteEngine, SPARQLReasoner, DatalogReasoner, TemporalReasoningEngine, ExplanationGenerator)
- export: fix ArangoExporter->ArangoAQLExporter, GraphMLExporter->GraphExporter; add ArrowExporter, DistanceExporter, ReportGenerator
- conflicts: fix ResolutionStrategy enum values and add SourceTracker, ConflictAnalyzer, InvestigationGuideGenerator
- change_management: add OntologyVersionManager, VersionStorage backends, compute_checksum/verify_checksum
- embeddings: add TextEmbedder, GraphEmbeddingManager, VectorEmbeddingManager, all provider stores, all pooling strategies
- visualization: fix broken See Also href from evals to explorer
2026-05-22 22:03:30 +05:30

6.5 KiB
Raw Blame History

title, description, icon
title description icon
Deduplication Module Entity deduplication v1/v2 — similarity scoring, blocking, merging, and cluster-based batch processing. copy

Identify and merge duplicate entities across sources for a clean, single-source-of-truth knowledge graph.


Overview

The Deduplication Module detects and merges duplicate entities using similarity scoring, blocking strategies, and configurable merge policies. v2 strategies (blocking_v2, hybrid_v2, semantic_v2) are up to 7x faster than v1 and support fine-grained result control.

Pairwise and batch duplicate detection with similarity scoring. Merge duplicate groups using configurable strategies with provenance preservation. Multi-factor similarity: Levenshtein, Jaro-Winkler, cosine, Jaccard, embedding. Union-Find and hierarchical clustering for batch deduplication at scale.

DuplicateDetector

The primary class for finding duplicate entity pairs:

from semantica.deduplication import DuplicateDetector

detector = DuplicateDetector(similarity_threshold=0.85)
duplicates = detector.detect_duplicates(entities)

for dup in duplicates:
    print(f"{dup.entity_a}{dup.entity_b}  ({dup.similarity:.2f})")

Fine-grained control:

duplicates = detector.detect_duplicates(
    entities,
    strategy="semantic_v2",    # see strategies below
    min_similarity=0.85,       # minimum score to consider a match
    top_k_per_entity=3,        # max candidates per entity
    max_results=100,           # total result cap
    sort_by="similarity",      # "similarity" | "entity_id" | "cluster_size"
)

Detection strategies:

Strategy Algorithm Speed Accuracy
jaro_winkler String similarity (v1) Fast Medium
blocking_v2 Blocking + Jaro-Winkler (v2) Very fast Medium
hybrid_v2 Blocking + semantic + string (v2) Fast High
semantic_v2 Embedding similarity (v2) Medium Highest
**v0.5.0 fix:** `DuplicateDetector` no longer produces duplicate definition errors when the same entity appears in multiple sources with identical definitions.

EntityMerger

Merges detected duplicate groups into canonical entities:

from semantica.deduplication import EntityMerger

merger = EntityMerger()
merged_entities = merger.merge_duplicates(
    entities,
    strategy="keep_most_complete",  # see strategies below
    preserve_provenance=True,        # keep source references after merge
)

Merge strategies:

Strategy Behavior
keep_first Keep the first entity in each duplicate group
keep_last Keep the most recently seen entity
keep_most_complete Keep the entity with the most non-null properties
union Merge all properties — non-conflicting fields combined
voting Most common property value wins
# Fine-grained merge with custom property rules
from semantica.deduplication import PropertyMergeRule

merger = EntityMerger(
    property_rules={
        "name": PropertyMergeRule.KEEP_FIRST,
        "aliases": PropertyMergeRule.UNION,
        "description": PropertyMergeRule.KEEP_LONGEST,
    }
)

SimilarityCalculator

Compute multi-factor similarity between entity pairs:

from semantica.deduplication import SimilarityCalculator

calc = SimilarityCalculator()

score = calc.calculate_similarity(entity_a, entity_b)
# → SimilarityResult(score=0.91, components={...})

print(score.score)                   # overall score 0.01.0
print(score.components["label"])     # label similarity
print(score.components["embedding"]) # semantic similarity
print(score.components["property"])  # property overlap

Individual metrics:

from semantica.deduplication import SimilarityCalculator

calc = SimilarityCalculator()

# String metrics
lev   = calc.levenshtein("Apple Inc.", "Apple Inc")
jaro  = calc.jaro_winkler("Steve Jobs", "Steven Jobs")
cos   = calc.cosine_similarity(embedding_a, embedding_b)
jacc  = calc.jaccard({"founded", "tech"}, {"founded", "technology"})

ClusterBuilder

Build clusters from detected duplicate groups for large-scale batch processing:

from semantica.deduplication import ClusterBuilder

builder = ClusterBuilder(algorithm="union_find")  # or "hierarchical"
result = builder.build_clusters(entities, similarity_threshold=0.85)

print(f"Clusters: {len(result.clusters)}")
for cluster in result.clusters:
    print(f"  [{cluster.id}] {cluster.members} — quality: {cluster.cohesion:.2f}")

Convenience Functions

from semantica.deduplication import detect_duplicates, merge_entities, calculate_similarity

# Quick detection
duplicates = detect_duplicates(entities, method="semantic_v2", similarity_threshold=0.85)

# Quick merge
merged = merge_entities(entities, duplicates, method="keep_most_complete")

# Quick similarity
score = calculate_similarity(entity_a, entity_b, method="hybrid_v2")

Blocking Strategies

Blocking reduces the O(n²) pairwise comparison to a manageable subset:

from semantica.deduplication import DuplicateDetector

detector = DuplicateDetector(
    blocking_strategy="token",        # "token" | "phonetic" | "ngram"
    blocking_threshold=0.6,
    similarity_threshold=0.85
)

Custom Similarity Functions

from semantica.deduplication import MethodRegistry, method_registry

def domain_similarity(entity_a, entity_b):
    # e.g., match drug names by active compound
    return score  # 0.0 to 1.0

method_registry.register("similarity", "drug_name", domain_similarity)

detector = DuplicateDetector(similarity_method="drug_name")

See Also

Detect value conflicts between non-duplicate entities. GraphBuilder uses deduplication during construction. Normalize entity names before deduplication. Track merged entity lineage.