Files
fn_registry/.claude/commands/eda.md
T
egutierrez 3be188a921 feat(eda): profile_level (lite/standard/full) en render_automatic_eda
Añade el parámetro profile_level a render_automatic_eda como preset de
consumo CPU/LLM que mapea a los flags existentes (run_models, run_series,
run_llm, sample). Tres niveles:

- lite (bajo consumo): run_llm=False, run_series=False, sample=2000 y modelos
  limitados a PCA + normalidad, SIN KMeans ni IsolationForest (lo caro en CPU).
  Para un vistazo rápido y barato.
- standard (default): comportamiento histórico — modelos completos, serie,
  sin LLM.
- full: standard + narrativa LLM por capítulo.

Precedencia: un flag explícito del caller (run_llm=..., run_models=..., etc.)
siempre prima sobre el default que fija el preset; el preset solo aplica al
parámetro que se deja en None.

Cableado del modo lite sin tocar profile_table (lo tocan otros agentes en
paralelo): profile_table NO corre los modelos (evita pagar KMeans +
IsolationForest); este pipeline los corre con run_eda_models(run_kmeans=False,
run_isolation=False) reusando ctx['raw_numeric'], y quita raw_numeric del ctx
para que el capítulo modelos no reproyecte clusters KMeans en vivo
(project_clusters_2d). geo_points ya queda derivado, así que geospatial no se
afecta.

Cambio aditivo y retro-compatible: sin profile_level el comportamiento es
idéntico al de v1.0.0 (standard). Tests nuevos cubren lite/standard, la
precedencia flag-sobre-preset, y la equivalencia del default con el histórico.
Bump 1.0.0 -> 1.1.0 + growth log en el .md. Skill /eda documenta --lite/--full.

Verificación: golden lite/standard/full sobre titanic — lite 4.8s (PCA+norm,
sin KMeans/iso/LLM/serie), standard 7.8s (modelos completos), full 38.3s
(+LLM). Suite render_automatic_eda + automatic_eda: 96 passed. fn index sin
error.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 18:20:17 +02:00

8.3 KiB

description
description
EDA (exploratory data analysis) de una tabla o de una base entera con el grupo `eda` del registry. Perfila, escribe el report (JSON + Markdown + PDF móvil) y monta un analysis Jupyter lanzado en el navegador colaborativo y ejecutado en vivo por Claude.

/eda — Exploratory Data Analysis con el grupo eda

Cuando Enmanuel pide un EDA ("hazme un EDA de X", "analiza esta tabla", "qué hay en estos datos"), no escribas análisis inline: usa el grupo de capacidad eda del registry, escribe los reports y monta el analysis Jupyter en su navegador colaborativo, ejecutando las celdas tú mismo en vivo. Respeta la memoria eda-workflow-registry y la regla .claude/rules/notebook_collaboration.md.

Página madre del grupo: docs/capabilities/eda.md (léela primero para cargar el cluster entero).

Uso

/eda /ruta/datos.duckdb tabla                  # EDA de una tabla DuckDB
/eda /ruta/datos.csv                           # CSV/Parquet → cargar a DuckDB y perfilar
/eda postgresql://user:pass@host:5432/db tabla # EDA de una tabla PostgreSQL (backend="postgres")
/eda /ruta/datos.duckdb --all                  # EDA de TODA la base (todas las tablas + FK + join graph)
/eda /ruta/datos.duckdb ventas --series --pdf  # con análisis de serie temporal + PDF móvil

$ARGUMENTS lleva la fuente y, opcionalmente, la tabla y flags. Interpreta:

  • Fuente: ruta a .duckdb/.csv/.parquet, o un DSN PostgreSQL (postgresql://... o postgres://...).
  • Tabla: nombre de la tabla. Si no se da y la fuente es un único archivo CSV/Parquet, usa su nombre base. Si se pide "toda la base" / --all, usa profile_database.
  • Flags (actívalos según lo que pida el usuario; pregunta solo si es ambiguo y costoso):
    • --modelsrun_models=True (PCA/KMeans/IsolationForest/normalidad).
    • --llmrun_llm=True (1 call LLM sobre el perfil agregado).
    • --seriesrun_series=True (estacionariedad ADF+KPSS, ACF/PACF, STL, retornos por columna numérica).
    • --pdfemit_pdf=True (PDF A5 legacy de render_eda_pdf, legible en móvil).
    • --legacy-only → emite SOLO el PDF legacy (sin AutomaticEDA), para casos en que solo se quiera el PDF rápido.
    • --lite / --bajo-consumorender_automatic_eda(profile_level="lite"): EDA barato y rápido (CI, vistazo previo, máquina sin GPU/red). Apaga LLM y serie temporal y limita los modelos a PCA + normalidad (sin KMeans ni IsolationForest, lo caro en CPU), con sample reducido. --fullprofile_level="full" (standard + narrativa LLM). Por defecto profile_level="standard" (comportamiento histórico). Un flag explícito (--llm, --models, ...) prima sobre el preset.

Por defecto, un EDA completo emite SIEMPRE el informe AutomaticEDA en sus dos formatos: PDF (A5 móvil) Y PPTX (16:9 para compartir) con los 11 capítulos poblados (portada, overview, distribuciones, calidad, correlaciones, modelos, series, geoespacial, agregación, interpretación LLM). Usa el pipeline render_automatic_eda (o profile_table(emit_automatic=True)), que activa run_models y run_series para que los capítulos de modelos/series/geoespacial/agregación salgan poblados. Deja run_llm para cuando el usuario lo pida o interese la interpretación semántica + narrativa por capítulo (es la única parte que gasta tokens del modelo).

Reglas duras

  1. Registry-first: invoca las funciones del grupo eda, no reescribas lógica de perfilado ni de gráficos inline (regla registry_first.md).
  2. CSV/Parquet/Excel entran cargándolos antes a DuckDB (read_csv_auto/read_parquet/read_xlsx) — DuckDB es el motor por defecto. No traigas la tabla entera a RAM.
  3. Secretos: si la fuente es un DSN PostgreSQL con credenciales, NO las imprimas en los reports ni en el notebook; resuélvelas vía resolve_pg_dsn/pass cuando aplique.
  4. El report es un artefacto local: vive en reports/ (gitignored), no se sube a Gitea ni se versiona. Compartir = pasar la ruta (regla reports.md).
  5. Entrega las salidas: el informe AutomaticEDA PDF + PPTX (siempre, con render_automatic_eda / emit_automatic=True) + (opcional) JSON sidecar + Markdown + PDF legacy + notebook Jupyter colaborativo ejecutado en vivo. Comparte las rutas de PDF y PPTX.

Paso 1 — Perfilar y escribir los reports

Una tabla (caso normal):

PYTHONPATH=python/functions python/.venv/bin/python3 - <<'PYEOF'
from pipelines.render_automatic_eda import render_automatic_eda
# Informe AutomaticEDA COMPLETO one-shot: perfil + ctx (datos crudos) + PDF + PPTX
# con los 11 capítulos poblados (clusters pintados, evolución temporal, mapa,
# tablas de agregación). run_llm=True añade la narrativa LLM por capítulo.
r = render_automatic_eda(
    "/ruta/datos.duckdb", "ventas",
    profile_level="standard",  # "lite" = bajo consumo CPU/LLM; "full" = + narrativa LLM
    out_dir="reports",
)
print("status:", r["status"])
print("pdf:   ", r["pdf_path"], "(", r["n_pages"], "págs )")
print("pptx:  ", r["pptx_path"], "(", r["n_slides"], "slides )")
print("manifest:", r["manifest_path"])
PYEOF

Si además quieres el report Markdown + JSON sidecar y/o el PDF legacy junto al AutomaticEDA, usa profile_table(emit_automatic=True, emit_pdf=True, write_report=True): emite todo a la vez (report_md_path, report_json_path, pdf_path legacy, aeda_pdf_path, aeda_pptx_path, aeda_manifest_path).

Una base entera (todas las tablas + relaciones FK):

PYTHONPATH=python/functions python/.venv/bin/python3 - <<'PYEOF'
from pipelines.profile_database import profile_database
r = profile_database("/ruta/datos.duckdb")
print(r["db_profile"]["join_graph"]["mermaid"])
PYEOF

Lee el Markdown resultante y resume a Enmanuel lo esencial: forma, calidad, correlaciones fuertes (ya corregidas por FDR), series no estacionarias, transformaciones sugeridas y avisos exploratorios.

Paso 2 — Notebook Jupyter colaborativo, ejecutado en vivo por Claude

Sigue la memoria eda-workflow-registry y la regla notebook_collaboration.md:

  1. Genera el notebook con build_eda_notebook (mismo perfil de la tabla):

    PYTHONPATH=python/functions python/.venv/bin/python3 - <<'PYEOF'
    from datascience import build_eda_notebook
    build_eda_notebook("/ruta/datos.duckdb", "ventas",
                       "analysis/eda_ventas/notebooks/01_eda.ipynb", run_models=True)
    PYEOF
    

    (o crea un analysis dedicado con fn run init_jupyter_analysis eda_ventas duckdb y escribe el notebook dentro de notebooks/).

  2. Confirma que hay Jupyter colaborativo activo con jupyter_discover (o lánzalo con el run-jupyter-lab.sh del analysis) y ábrelo en el navegador colaborativo para que Enmanuel lo vea en vivo.

  3. Ejecuta tú las celdas (no se las dejes para que las corra él): usa las funciones del dominio notebook (jupyter_exec append+execute / jupyter_read) descritas en notebook_collaboration.md, o el MCP jupyter si está conectado en la sesión del analysis. Ejecuta de arriba a abajo, comenta cada bloque relevante y deja el notebook navegable.

Notas

  • El TableProfile lleva ahora, además del perfilado base y las correlaciones con FDR: series (por columna numérica, con run_series), reexpression por columna numérica (escalera de Tukey) y caveats (siempre, avisos exploratorios). El Markdown y el PDF renderizan estas secciones automáticamente cuando están presentes.
  • El informe AutomaticEDA (render_automatic_eda / emit_automatic=True) emite el MISMO documento por capítulos a PDF (A5 móvil) y PPTX (16:9) con garantía de no-corte (texto envuelto, tablas partidas repitiendo cabecera, figuras escaladas) y negrita real (**texto**). Escribe automatic_eda_manifest.json con la versión de cada capítulo. Los capítulos modelos/series/geoespacial/agregación se pueblan con los datos crudos que build_eda_render_ctx muestrea de la base (no se traen tablas enteras a RAM).
  • El PDF legacy (emit_pdf, render_eda_pdf) sigue disponible y es independiente del AutomaticEDA (A5 vertical, gráficos Tufte). Se escribe junto al Markdown en reports/.
  • run_series ordena por la primera columna datetime si existe; si no, por el orden físico de filas. Necesita ≥8 puntos válidos por columna.
  • Fuentes: DuckDB (CSV/Parquet/Excel cargados antes) y PostgreSQL (backend="postgres"). profile_database (multi-tabla + FK) es solo DuckDB por ahora.