What Is Deduplication?
Deduplication is the process of identifying entities that refer to the same real-world object but appear as separate records in your data, then merging them into a single canonical representation. This process resolves aliases, spelling variations, and formatting differences that occur when data comes from multiple sources. Key deduplication concepts: Canonical entities are the single, authoritative representation of a real-world object after merging all duplicate records. The canonical entity becomes the node that all relationships point to in your knowledge graph. Aliases are alternative names or identifiers for the same entity. For example, “APT29”, “Cozy Bear”, and “Midnight Blizzard” are all aliases for the same threat actor. Entity resolution is the broader process of determining when different records refer to the same entity, including the similarity calculation, duplicate detection, and merging steps. Similarity algorithms:- Jaro-Winkler measures string similarity with higher scores for shared prefixes, ideal for names with common beginnings
- Levenshtein distance counts character edits needed to transform one string into another, good for catching typos and variations
Why Use Deduplication?
Data quality and consistency. Eliminate duplicate nodes that fragment relationships and create inconsistent query results across different names for the same entity. Accurate analytics and metrics. Get correct counts, centrality measures, and relationship analysis when entities aren’t artificially split across multiple nodes due to naming variations. Relationship consolidation. Merge scattered relationships onto single canonical entities, enabling complete analysis of connections and patterns that would be missed with fragmented data. Source integration. Seamlessly combine data from multiple feeds, systems, and databases where the same entities appear under different identifiers and naming conventions. Graph efficiency. Reduce graph size and improve query performance by eliminating redundant nodes while preserving all information through proper merging strategies. Provenance preservation. Maintain complete audit trails showing which source contributed each piece of information to the final canonical entity.When To Use / When Not To Use
Use deduplication for:- Multi-source data integration where entities appear under different names or identifiers
- Entity types prone to aliases and variations (organizations, people, products, geographic locations)
- Knowledge graphs where relationship accuracy depends on entity consolidation
- Data quality workflows requiring canonical entity management
- Analytics requiring accurate entity counts and relationship metrics
- Scenarios where the same real-world objects appear across multiple systems or databases
- Single-source data with consistent entity identifiers and naming conventions
- High-throughput streaming scenarios where deduplication latency is unacceptable
- Data with reliable primary keys where duplicates are impossible by design
- Cases where entity variations should be preserved as separate nodes (different product versions, time-based entity states)
- Simple exact-match scenarios where basic database constraints handle uniqueness
- Large datasets where O(n²) pairwise comparison becomes computationally expensive
- Fuzzy matching when deterministic primary keys (LEI, CVE-ID, ISIN) are available
- Very low similarity thresholds that may merge genuinely different entities
Typical Workflow
The deduplication workflow follows a systematic process from detection through merging: 1. Detect → Usedetect_duplicates() or DuplicateDetector to identify potential matches using multi-factor similarity scoring
2. Group → Apply clustering algorithms to collect transitively related duplicates into groups (A matches B, B matches C → group A,B,C)
3. Select Canonical → Choose representative entity for each group based on completeness, source authority, or confidence scores
4. Merge → Combine duplicate entities using strategies like keep_most_complete or merge_all while preserving provenance
5. Validate → Review merge results and adjust thresholds or strategies based on precision/recall analysis
6. Update Graph → Replace duplicate nodes with canonical entities and transfer all relationships
This pipeline transforms fragmented multi-source data into clean, consolidated knowledge graphs ready for analytics and reasoning.
API Patterns: Functional vs Class-Based
Semantica provides both simple functional wrappers and comprehensive class APIs for different use cases: Functional wrappers for simple workflows:detect_duplicates()— one-shot duplicate detection with minimal configurationcalculate_similarity()— compare two entities with detailed similarity breakdownmerge_entities()— convenience wrapper around merge_duplicates() for quick merging
DuplicateDetector— configurable duplicate detection with clustering, incremental processing, and advanced similarity optionsEntityMerger— sophisticated merging with multiple strategies, provenance tracking, and merge history
- Use
merge_duplicates()when you have a raw collection of entities and need automatic duplicate detection - Use
merge_entity_group()when you already know which entities are duplicates and just need to merge a pre-determined group - Don’t mix functional wrappers with class APIs in the same workflow—choose one approach and stick with it
Run deduplication after ingestion and before conflict resolution. Deduplication collapses duplicate nodes into one canonical entity. Conflict resolution then reconciles disagreeing property values on that canonical entity. The pipeline order matters: deduplicate first, then resolve conflicts, then validate with SHACL.
Finding your duplicates: the first scan
Start withdetect_duplicates() for straightforward duplicate detection on smaller datasets. Point it at your entities and let the pairwise algorithm compare every pair using multiple similarity signals.
Scaling consideration: For datasets of a few thousand nodes, this runs in seconds. The O(n²) pairwise comparison cost only becomes problematic above ten thousand entities—for larger sets, see the clustering section below.
"APT29" in their aliases list. “APT28” never appears in the results because it shares only the country field — not enough to cross the 0.6 threshold.
Understanding the candidate object
EachDuplicateCandidate carries the two entities, their similarity scores, and a detailed breakdown of which similarity algorithms contributed to the match. This provides full transparency for audit and threshold tuning:
aliases: ["APT29"], which creates an almost-definitive signal that these entities refer to the same threat actor. When you see a pattern like this — weak name similarity but strong property matching — you’re typically looking at a genuine alias relationship rather than a false positive.
Grouping duplicates before merging
For small datasets, you can merge candidate pairs directly. For larger graphs where the same entity might appear under six different names across twelve feeds, use duplicate grouping with Union-Find clustering. This ensures that if A matches B and B matches C, all three entities are grouped together even if A and C don’t directly meet the similarity threshold:representative field identifies the entity the merger will use as the base — typically the one with the most complete attribute set, in this case “APT29” from the MISP feed.
Merging: collapsing the group without losing data
Once you have identified duplicate groups, the merging process consolidates them into canonical entities. Thekeep_most_complete strategy selects the entity with the highest property count as the canonical node and enriches it with any missing fields from the other sources:
Reviewing merge history for audit
After batch merging operations, you can retrieve the complete history to review every decision made. This audit trail is essential for understanding merge decisions and explaining them to stakeholders:Streaming ingestion: incremental deduplication
When your pipeline processes continuous data streams — new threat intelligence arriving hourly — you don’t want to re-run pairwise comparison over the entire graph on every batch. Use incremental detection to compare only new entities against the existing canonical set:Scaling to large entity sets
For graphs above ten thousand nodes, pairwise comparison becomes computationally expensive due to its O(n²) complexity. Usebuild_clusters() to run more efficient vectorized batch comparison, then merge each resulting cluster:
Performance warning: Always profile your similarity operations on representative data sizes. What works for 1,000 entities may become unacceptably slow at 10,000+ entities without appropriate scaling strategies.
method="hierarchical" which uses agglomerative bottom-up clustering and scales to hundreds of thousands of entities at the cost of some precision.
A Simple Example: Customer Deduplication
Before exploring domain-specific cases, let’s walk through a straightforward customer deduplication scenario. A company’s CRM system has accumulated duplicate customer records from web signups, sales team entries, and support tickets:Common Pitfalls
Threshold tuning without validation. Setting thresholds too low creates false positive merges between genuinely different entities. Always manually review a sample of detected duplicates before running large-scale merging operations. Pairwise scaling problems. The O(n²) cost of comparing every entity pair becomes prohibitive above 10,000 entities. Use clustering methods (build_clusters) or switch to vectorized similarity for large datasets.
Using fuzzy matching when primary keys exist. If your entities have reliable unique identifiers (LEI codes, CVE IDs, ISBN numbers), use exact matching on those fields instead of computationally expensive similarity algorithms.
Mixing wrapper and class APIs inconsistently. Don’t call detect_duplicates() then manually instantiate EntityMerger—choose either the functional approach or class-based approach and use it consistently throughout your workflow.
Ignoring merge strategy implications. keep_first overwrites later records completely, merge_all can introduce conflicting values, and keep_most_complete may not respect source authority. Choose the strategy that matches your data quality requirements.
Skipping provenance tracking. Without preserve_provenance=True, you lose visibility into which source contributed each field in the canonical entity, making audit trails impossible.
Inadequate similarity algorithm selection. Pure string similarity fails for alias relationships (“APT29” vs “Cozy Bear”), while property matching may be too aggressive for entities with shared attributes but different identities.
Domain examples
- Defense — CTI/Threat
- Security — SOC/Incident
- Life Science — Clinical/Pharma
- Banking — Risk/Compliance
A threat intelligence platform ingests actor profiles from Mandiant, CrowdStrike, MITRE ATT&CK, and partner ISAC feeds. The same actors appear under vendor-specific names: “Cozy Bear” (CrowdStrike), “APT29” (MITRE), “Midnight Blizzard” (Microsoft), “The Dukes” (F-Secure). Before any analyst query runs, these aliases must collapse to a single canonical node so that relationships — malware used, infrastructure operated, campaigns attributed — all attach to one place.The alias field is the key signal here. Property-based similarity will fire strongly when any record carries the canonical name in its
aliases list. Setting a moderate threshold (0.6) catches alias-based matches that name similarity alone would miss.Choosing the right threshold
The similarity threshold controls sensitivity. Start at 0.7 and examine false positives before adjusting:- 0.95 and above — near-exact string matches only. Use for codes and IDs (LEI, CAS, CVE-ID) where name format is consistent across feeds.
- 0.80–0.95 — catches typographic variants: “Apple Inc.” vs “Apple, Inc.”, “BlackRock” vs “BlackRock Inc.”
- 0.65–0.80 — catches abbreviations and short forms. Necessary for organization names that appear in both long and short forms across feeds.
- 0.50–0.65 — semantic similarity territory. Requires property or embedding signals to compensate for weak name similarity. Use this range for alias-based matching where names may be completely different strings referring to the same entity.
Choosing a merge strategy
Related Guides
- Ingest Anything — multi-source ingestion creates the duplicates this module resolves
- Context Graphs — store deduplicated entities directly in the knowledge graph
- Conflict Resolution — after merging, reconcile disagreeing property values on the canonical entity
- Provenance — track merge lineage so every canonical entity traces back to its original sources
- Pipeline — chain ingest, deduplicate, and store as a
PipelineBuilderworkflow
