Files
fn_registry/python/functions/datascience/deduplicate_entities.md
T
egutierrez 988e901066 docs: params/output semántico en 506 funciones para composabilidad
Añade campos params y output al frontmatter YAML de las 506 funciones del registry.
Cada parámetro tiene descripción semántica (qué representa, unidades, rango típico)
y cada función describe qué produce su output. Permite a agentes razonar sobre
cadenas de composición (ej: prices → log_return → sharpe_ratio) sin leer código.
2026-04-05 18:45:16 +02:00

4.9 KiB
Raw Blame History

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path
deduplicate_entities function py datascience 1.0.0 pure def deduplicate_entities(candidates: list[EntityCandidate], name_threshold: float = 0.85, same_type_only: bool = True) -> DeduplicationResult Agrupa entidades candidatas que refieren a la misma entidad real usando fuzzy matching de nombres (Levenshtein + Jaccard) y Union-Find para clusters transitivos. Retorna entidades mergeadas con mapas de resolucion de IDs y log de merges.
deduplication
entity
fuzzy
levenshtein
jaccard
union-find
knowledge-graph
nlp
fuzzygraph
datascience
normalize_entity_name_py_core
merge_entity_attributes_py_core
entity_candidate_py_datascience
deduplication_result_py_datascience
deduplication_result_py_datascience
false
uuid
name desc
candidates lista de EntityCandidate a deduplicar. Cada uno tiene name, type_ref, confidence.
name desc
name_threshold umbral de similitud para fuzzy matching de nombres en rango [0, 1] (tipico: 0.85). Mayor = mas estricto.
name desc
same_type_only si True, solo mergea candidatos con el mismo type_ref. Si False, mergea por similitud ignoring tipo.
DeduplicationResult con entidades mergeadas, mapas de resolucion de IDs (name_to_id) y log de merges realizados true
John Smith y Smith, John se mergean
Google y Google LLC se mergean
192.168.1.1 y 192.168.1.1 se mergean por matching exacto
John Smith (person) y John Smith (organization) NO se mergean
Clusters transitivos: A~B, B~C -> {A, B, C} en un solo cluster
Entidades sin duplicados pasan sin modificacion
Confidence toma el max del cluster; atributos se fusionan
Lista vacia retorna resultado vacio
name_to_id contiene todos los nombres originales del cluster
python/functions/datascience/deduplicate_entities_test.py python/functions/datascience/deduplicate_entities.py

Ejemplo

from python.types.datascience.entity_candidate import EntityCandidate
from python.functions.datascience.deduplicate_entities import deduplicate_entities

candidates = [
    EntityCandidate(name="John Smith", type_ref="person", confidence=0.9),
    EntityCandidate(name="Smith, John", type_ref="person", confidence=0.85),
    EntityCandidate(name="Google", type_ref="organization", confidence=0.95),
    EntityCandidate(name="Google LLC", type_ref="organization", confidence=0.88),
]

result = deduplicate_entities(candidates, name_threshold=0.85, same_type_only=True)
# result.total_before = 4
# result.total_after = 2
# result.merge_log = [
#   {"canonical": "John Smith", "merged": ["Smith, John"], "score": 0.91, "reason": "fuzzy_name"},
#   {"canonical": "Google", "merged": ["Google LLC"], "score": 0.89, "reason": "fuzzy_name"},
# ]

Algoritmo

  1. Normalizar nombres usando normalize_entity_name() sobre cada candidato segun su type_ref
  2. Comparacion pairwise dentro del mismo tipo (si same_type_only=True):
    • Para tipos tecnicos (ip, email, domain, crypto_wallet, phone): matching exacto normalizado
    • Para el resto: score = max(levenshtein_sim, jaccard_sim) + bonus por contencion (+0.3) y acronimos (+0.3)
  3. Union-Find para clusters transitivos: si AB y BC, entonces {A, B, C} forman un cluster
  4. Merge por cluster:
    • Nombre canonico: candidato con mayor confidence
    • Atributos: merge_entity_attributes() sobre todos los candidatos del cluster
    • Confidence: max del cluster
    • Source chunks: union de todos los candidatos
    • merged_from: union de todos los nombres originales

Heuristicas de similitud de nombres

Heuristica Efecto
Levenshtein 1 - (edit_distance / max_len)
Jaccard sobre tokens |A ∩ B| / |A B|
Score base max(lev_sim, jaccard_sim)
Contencion (a in b o b in a) +0.3 hasta max 1.0
Acronimo ("FBI" ~ "Federal Bureau of Investigation") +0.3 hasta max 1.0
Tipos exactos (ip/email/domain) solo matching exacto, ignora umbral

Complejidad

  • Pairwise: O(N^2) — aceptable para <1000 entidades (tipico por documento)
  • Union-Find con path compression: O(α(N)) amortizado por operacion
  • Para escalar a >1000: pre-filtrar por primera letra o n-gram index antes de comparar

Notas

Funcion pura. Implementa Levenshtein y Jaccard internamente para evitar dependencias externas a este modulo. Las funciones del registry levenshtein_distance_py_cybersecurity y jaccard_similarity_py_cybersecurity son equivalentes pero requieren imports adicionales — la implementacion inline mantiene la funcion sin dependencias de stdlib.

El name_to_id del resultado es el mapa de resolucion principal para la fase de deduplicacion de relaciones: permite resolver cualquier variante de nombre de una entidad a su ID canonico.