Files
semantica/docs/reference/deduplication.md
T
KaifAhmad1 37e640e7b4 docs: comprehensive audit and DX overhaul of all reference modules
llms.md:
- Only Groq/OpenAI/LiteLLM/HuggingFaceLLM are exported — remove non-exported
  Anthropic/Ollama/Gemini/DeepSeek/Novita as direct imports
- Rename HuggingFace -> HuggingFaceLLM (correct class name)
- Remove non-existent create_provider() — replace with LiteLLM provider/model pattern
- Add LiteLLM 100+ providers section with provider/model string examples
- Add Exported Classes table (class -> provider -> API key)
- Update Provider Comparison table to show correct import per provider

ontology.md:
- Remove non-existent OntologyManager — replace with OntologyEngine facade
- Remove non-existent start_explorer() — replace with CLI: semantica-explorer
- SHACLValidator -> OntologyValidator (correct exported name)
- OWLExporter -> OWLGenerator (correct exported name)
- Add Exported Classes block with all 15+ exported symbols
- Add LLMOntologyGenerator section, NamespaceManager section
- Add OntologyEvaluator section with coverage/completeness metrics
- Add ingest_ontology() section
- Add versioning moved-to note (change_management module)

kg.md:
- TemporalKnowledgeGraph does not exist — replace with TemporalGraphQuery
- DistanceCalculator does not exist — replace with SimilarityCalculator
- Add Exported Classes block with all 20+ exported symbols
- Fix temporal example to use TemporalGraphQuery + TemporalVersionManager correctly
- Add SimilarityCalculator section with NodeEmbedder integration example

provenance.md:
- ActivityTracker not exported — remove; ProvenanceManager handles tracking
- Fix track_entity() signature: add source_location, source_quote params
- Fix GraphBuilderWithProvenance import: from semantica.kg, not semantica.provenance
- Add Exported Classes block with storage backends and checksum utilities
- Add SourceReference section with DOI/page/quote fields
- Add tamper-evident checksum section (compute_checksum/verify_checksum)
- Add Enable Provenance in Extractors section
- Fix duplicate heading (W3C PROV-O Export appeared twice)

reasoning.md:
- Add Exported Classes block with all engines + data types + explanation types
- Add Quick Start section
- Add Choosing an Engine comparison table
- Add InferenceResult/Explanation/ReasoningStep type annotations in examples
- Add Tip: use DatalogReasoner for recursive rules

semantic_extract.md:
- Add Exported Classes block with NamedEntityRecognizer, EventDetector, Entity,
  Relation, Event, CoreferenceChain, EntityClassifier, TemporalEventProcessor
- Add Quick Start section (one-liner extraction pipeline)
- Rename EventExtractor -> EventDetector (correct exported name)
- Clarify NERExtractor vs NamedEntityRecognizer distinction
- Add return type annotations to EventDetector example

core.md:
- Add Exported Classes block
- Add When to Use Core vs. Individual Modules decision table
- Add Tip: LifecycleManager only for long-running apps
- Fix MethodRegistry example to import build_knowledge_base correctly

parse.md:
- Add Exported Classes block with all format-specific parsers + data types
- Add DoclingParser optional import note

utils.md:
- Add Exported Classes block with logging/validation/progress/helpers/exceptions

deduplication.md:
- Add Exported Classes block with PropertyMergeRule, MergeStrategyManager,
  method_registry, and all convenience functions

export.md:
- Add Exported Classes block with all exporters, NamespaceManager,
  SemanticNetworkYAMLExporter, and all convenience functions
2026-05-24 14:41:57 +05:30

7.1 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

semantica.deduplication detects and merges duplicate entities across sources to produce a clean, single-source-of-truth knowledge graph. v2 strategies (blocking_v2, hybrid_v2, semantic_v2) are up to 7x faster than v1 with fine-grained result control.

Exported Classes

from semantica.deduplication import (
    DuplicateDetector,      # pairwise + batch duplicate detection
    EntityMerger,           # merge duplicate groups with per-property policies
    SimilarityCalculator,   # Levenshtein, Jaro-Winkler, cosine, Jaccard, embedding
    ClusterBuilder,         # Union-Find + hierarchical clustering
    PropertyMergeRule,      # enum: KEEP_FIRST, KEEP_LONGEST, UNION, VOTING, ...
    MergeStrategyManager,   # manage and apply merge strategies
    # Convenience functions
    detect_duplicates,      # quick: detect_duplicates(entities, method="semantic_v2")
    merge_entities,         # quick: merge_entities(entities, duplicates, method="union")
    calculate_similarity,   # quick: calculate_similarity(a, b, method="hybrid_v2")
    # Registry
    method_registry,        # register custom similarity functions
)

What You Get

  • DuplicateDetector — pairwise and batch duplicate detection with configurable strategies
  • EntityMerger — merge duplicate groups with configurable property-level merge policies
  • SimilarityCalculator — multi-factor similarity: Levenshtein, Jaro-Winkler, cosine, Jaccard, embedding
  • ClusterBuilder — Union-Find and hierarchical clustering for large-scale batch deduplication
  • Convenience functionsdetect_duplicates, merge_entities, calculate_similarity

DuplicateDetector

Find duplicate entity pairs with configurable strategies and result filtering:

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 over strategy, thresholds, and result size:

duplicates = detector.detect_duplicates(
    entities,
    strategy="semantic_v2",    # see strategies table 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, preserving provenance:

from semantica.deduplication import EntityMerger

merger = EntityMerger()
merged_entities = merger.merge_duplicates(
    entities,
    strategy="keep_most_complete",  # see strategies table 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 per-property merge rules:

from semantica.deduplication import EntityMerger, PropertyMergeRule

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

SimilarityCalculator

Compute multi-factor similarity scores 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 string and vector 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 entity clusters for large-scale batch deduplication:

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} — cohesion: {cluster.cohesion:.2f}")

Blocking Strategies

Blocking reduces the O(n²) pairwise comparison problem to a manageable candidate set:

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

Custom Similarity Functions

Register domain-specific similarity logic:

from semantica.deduplication import method_registry

def drug_name_similarity(entity_a, entity_b):
    # Match drug names by active compound
    return score  # 0.0 to 1.0

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

detector = DuplicateDetector(similarity_method="drug_name")

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")
Detect value conflicts between non-duplicate entities. GraphBuilder uses deduplication during construction. Normalize entity names before deduplication. Track merged entity lineage.