5f4f1f7508
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.
77 lines
3.3 KiB
Markdown
77 lines
3.3 KiB
Markdown
---
|
|
name: merge_graphs
|
|
kind: function
|
|
lang: py
|
|
domain: datascience
|
|
version: "1.0.0"
|
|
purity: pure
|
|
signature: "def merge_graphs(graphs: list[dict], entity_key: str = 'name', similarity_threshold: float = 0.85) -> dict"
|
|
description: "Mergea multiples grafos de conocimiento en uno deduplicando entities por similitud de nombre (Levenshtein normalizado). Relaciones se re-apuntan a las entities canonicas. Atributos se combinan por union."
|
|
tags: [graph, merge, deduplication, knowledge-graph, levenshtein, similarity, datascience]
|
|
uses_functions: [levenshtein_distance_py_cybersecurity]
|
|
uses_types: []
|
|
returns: []
|
|
returns_optional: false
|
|
error_type: ""
|
|
imports: [sys, os]
|
|
params:
|
|
- name: graphs
|
|
desc: "lista de grafos, cada uno con estructura {entities: [...], relations: [...]}"
|
|
- name: entity_key
|
|
desc: "campo de entity que se usa para fuzzy matching (defecto: 'name'). Determina similitud."
|
|
- name: similarity_threshold
|
|
desc: "umbral de similitud Levenshtein normalizado [0, 1] para mergear (tipico: 0.85). Mayor = mas estricto."
|
|
output: "dict con estructura {entities: [...], relations: [...], merge_log: [...]}, grafo mergeado y deduplicado"
|
|
tested: true
|
|
tests:
|
|
- "dos grafos con entity duplicada → merge"
|
|
- "entities similares pero bajo threshold → no merge"
|
|
- "relaciones re-apuntadas correctamente"
|
|
- "merge log registra cada merge"
|
|
- "tres grafos → merge transitivo"
|
|
- "grafos sin overlap → concatenacion simple"
|
|
test_file_path: "python/functions/datascience/merge_graphs_test.py"
|
|
file_path: "python/functions/datascience/merge_graphs.py"
|
|
---
|
|
|
|
## Ejemplo
|
|
|
|
```python
|
|
g1 = {
|
|
"entities": [
|
|
{"id": "1", "name": "Alice Corp", "type": "company"},
|
|
{"id": "2", "name": "Bob", "type": "person"},
|
|
],
|
|
"relations": [
|
|
{"source_id": "2", "target_id": "1", "relation_type": "works_at"},
|
|
],
|
|
}
|
|
g2 = {
|
|
"entities": [
|
|
{"id": "3", "name": "Alice Corp.", "type": "company", "country": "US"},
|
|
],
|
|
"relations": [],
|
|
}
|
|
|
|
result = merge_graphs([g1, g2], similarity_threshold=0.85)
|
|
# result["entities"] -> 2 entities (Alice Corp mergeada, Bob)
|
|
# result["merge_log"] -> [{"merged": ["3", "1"], "into": "1", "similarity": 0.909}]
|
|
# "Alice Corp." mergeada en "Alice Corp" porque similitud > 0.85
|
|
```
|
|
|
|
## Notas
|
|
|
|
Funcion pura. Reutiliza `levenshtein_distance_py_cybersecurity` para calcular similitud normalizada entre nombres.
|
|
|
|
**Algoritmo de merge transitivo**: si A~B y B~C, entonces A, B, C se mergean en uno solo. Se implementa via union-find (path compression simple).
|
|
|
|
**Eleccion de canonical**: la entity con mas campos no-null gana. En caso de empate, la primera encontrada en el par.
|
|
|
|
**Conflictos de atributos**: si ambas entities tienen un campo con valor, el canonical conserva el suyo (primero gana). Solo se copian campos que el canonical no tiene o tiene null.
|
|
|
|
**Deduplicacion de relaciones**: por (source_id, target_id, relation_type). Si dos relaciones son identicas tras re-apuntar los IDs, se conserva la primera encontrada.
|
|
|
|
**Complejidad**: O(n^2) en numero de entities por la comparacion de pares. Adecuado para grafos de knowledge tipicos (< 10K entities). Para grafos muy grandes, usar indexado por prefijo antes de comparar.
|
|
|
|
**Importacion**: intenta importar `levenshtein_distance` desde el paquete `cybersecurity` del registry. Si no esta disponible, usa una reimplementacion inline equivalente.
|