feat: extraccion masiva footprint_aurgi (41 funcs + 4 types + stack Docker geo)
Extrae al registry funciones del proyecto interno footprint_aurgi: - core (6): slugify_ascii, normalize_for_join, cp_provincia_es, infer_provincia_from_cp, safe_read_csv_fallback, csv_to_parquet_duckdb - geo puras (7): haversine_km, point_in_ring, point_in_polygon, point_in_polygons_bbox, polygon_bbox, extent_with_padding, distance_bucket - geo I/O (4): load_geojson_polygons, load_boundary_gdf, add_basemap_osm, add_basemap_with_timeout - valhalla client (4): valhalla_route, valhalla_isochrone, valhalla_isochrones_async, valhalla_matrix_1_to_n - datascience stats (7): trimmed_mean, geometric_mean, detect_distribution_type, best_central_tendency, summary_stats, kde_density_levels, alpha_shape_concave_hull - datascience fuzzy (3): fuzzy_merge_adaptive (rapidfuzz), words_to_dataset, remove_words_from_column - datascience viz (2): plot_kde_2d, plot_heatmap_log - infra (4): compress_pdf_ghostscript, render_table_page_pdfpages, add_header_logo, osm2pgsql_ingest - pipelines (4): setup_geo_stack_docker, compute_centers_reachability, generate_isochrones_by_zone, count_points_per_zone - types geo (4): LonLat, BBox, IsochroneRequest, Centro Incluye: - apps/footprint_geo_stack/ (PostGIS + Martin + Valhalla via docker-compose) - 131/132 tests pasan (1 skip esperado: osm2pgsql en PATH) - Issue tracker dev/issues/0052-footprint-aurgi-extraction.md - Atribucion uniforme: source_repo internal:footprint_aurgi, source_license internal-aurgi - Build con 9 agentes en paralelo (8 wave 1 + 1 wave 2 pipelines) Tambien commitea trabajo previo no commiteado: aggregate_extraction_results, chunk_with_overlap, clean_pdf_text, merge_entity_aliases, extract_graph_gliner2, extract_relations_mrebel, extract_triples_spacy_es, gliner2/mrebel/marianmt/rebel/spacy_es load_model, parse_rebel_output, translate_es_to_en, issue 0050/0051. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
---
|
||||
name: extract_graph_gliner2
|
||||
kind: function
|
||||
lang: py
|
||||
domain: datascience
|
||||
version: "1.0.0"
|
||||
purity: impure
|
||||
signature: "def extract_graph_gliner2(text: str, entity_labels: list[str], relation_labels: list | dict, model: Any, threshold: float = 0.3, include_confidence: bool = False) -> dict"
|
||||
description: "Extrae entidades + relaciones en una sola pasada con GLiNER2. Wrapper de alto nivel: construye schema, ejecuta extraccion, normaliza a dict plano. No aplica post-filtrado ni coreference."
|
||||
tags: [gliner2, ner, relation-extraction, nlp, extraction, graph, zero-shot, datascience, python, apache2]
|
||||
uses_functions:
|
||||
- gliner2_load_model_py_datascience
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: "error_go_core"
|
||||
imports: [time, typing.Any]
|
||||
params:
|
||||
- name: text
|
||||
desc: "Texto a analizar. Recomendado hasta 1500 chars (pre-chunkeado con chunk_with_overlap). Textos mas largos degradan el recall de GLiNER2."
|
||||
- name: entity_labels
|
||||
desc: "Lista de strings con los tipos de entidad en minusculas snake_case. E.g. ['person', 'organization', 'location']. Labels en snake_case mejoran el recall segun notebook 08."
|
||||
- name: relation_labels
|
||||
desc: "Lista de strings o dict {label: description} con los tipos de relacion. E.g. ['works_at', 'ceo_of'] o {'works_at': 'person works at an organization'}."
|
||||
- name: model
|
||||
desc: "Instancia GLiNER2 cargada con gliner2_load_model. Inyectada por el caller (no se carga aqui)."
|
||||
- name: threshold
|
||||
desc: "Umbral de confianza entre 0 y 1. 0.3 validado empiricamente en notebook 04 (gliner_glirel_tuning). Valores mas bajos = mas recall, mas ruido."
|
||||
- name: include_confidence
|
||||
desc: "Si True, GLiNER2 devuelve scores internos por entidad y relacion. False por defecto para output mas limpio."
|
||||
output: "Dict con tres campos: 'entities' -> {type: [name, ...]}, 'relation_extraction' -> {rel_type: [(head, tail), ...]}, 'elapsed_s' -> float. Compatible con aggregate_extraction_results."
|
||||
tested: true
|
||||
tests:
|
||||
- "output tiene claves entities relation_extraction elapsed_s"
|
||||
- "stub model retorna shape correcto"
|
||||
test_file_path: "python/functions/datascience/tests/test_extract_graph_gliner2.py"
|
||||
file_path: "python/functions/datascience/extract_graph_gliner2.py"
|
||||
notes: |
|
||||
LICENSE: GLiNER2 (fastino/gliner2-large-v1) es Apache 2.0 — uso comercial OK.
|
||||
|
||||
impure: invoca inferencia del modelo (side effect computacional + tiempo variable).
|
||||
El model se inyecta externamente para permitir cache y reutilizacion entre llamadas.
|
||||
Para textos largos usar chunk_with_overlap antes y llamar esta funcion por chunk,
|
||||
luego agregar con aggregate_extraction_results.
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
from datascience.gliner2_load_model import gliner2_load_model
|
||||
from datascience.extract_graph_gliner2 import extract_graph_gliner2
|
||||
|
||||
model = gliner2_load_model(device="auto")
|
||||
|
||||
result = extract_graph_gliner2(
|
||||
text="Carlos Torres es presidente de BBVA, con sede en Bilbao.",
|
||||
entity_labels=["person", "organization", "location"],
|
||||
relation_labels=["president_of", "headquartered_in"],
|
||||
model=model,
|
||||
threshold=0.3,
|
||||
)
|
||||
# result["entities"] -> {"person": ["Carlos Torres"], ...}
|
||||
# result["relation_extraction"]-> {"president_of": [("Carlos Torres", "BBVA")]}
|
||||
# result["elapsed_s"] -> 0.234
|
||||
```
|
||||
Reference in New Issue
Block a user