eaca41a532
Añade al capítulo `correlacion` del AutomaticEDA la visualización con scatters de los pares numérico-numérico más correlacionados (positiva y negativamente) y, para cada uno, la clasificación del tipo de relación: lineal, polinómica (grado 2/3), monótona no-lineal o débil/sin forma. Funciones nuevas del registry (dominio datascience, grupo eda): - classify_relationship_type_py_datascience (pura): dadas dos listas numéricas pareadas, cruza Pearson r (lineal), Spearman ρ (monótona) y ajustes polinómicos de grado 2 y 3 (numpy.polyfit + R² manual) para etiquetar la forma. Reusa pearson y spearman_corr del registry. Umbrales calibrados para datos reales discretos/ruidosos (orden: débil → monótona → polinómica → lineal). Devuelve los coeficientes del mejor modelo para pintar la curva. No-throw. - relationship_scatter_figure_py_datascience (impure): construye la Figure matplotlib del scatter de un par con su recta/curva de ajuste y una anotación del tipo + métricas (r, ρ, R²lin, R²poly). Backend Agg sin pyplot global, downsample determinista de los puntos dibujados, tendencia ordenada (binned / por valor) para el caso monótona sin polinomio. Defensiva ante vacío. Capítulo correlacion.py (1.0.0 → 1.1.0): nueva sección "Relaciones más fuertes (scatter)" tras la matriz + tablas top. Toma los top-K pares num↔num por |valor| de profile['correlations']['pairs'], obtiene los datos crudos de cada par desde ctx['raw_numeric'] y emite, por par, un Figure dentro de un Group keep-together junto a una nota de texto con el tipo de relación (extraíble por pdftotext). Solo num↔num: los pares cat↔cat (Cramér's V) y num↔cat (razón de correlación) no llevan scatter. Cuando no hay raw_numeric (perfil lite/agregado o ctx None) los scatters se omiten sin lanzar; la matriz + tablas siguen. Verificado: golden EDA de titanic (run_models) — el capítulo Correlación del PDF y PPTX incluye los scatters (pclass↔fare → monótona no-lineal, sibsp↔parch → lineal, …) con su ajuste y etiqueta de tipo en texto. Tests de clasificación sintética (lineal, y=x² → polinómica, y=exp(x) → monótona, ruido → débil) + tests del capítulo (golden con raw_numeric, edge sin raw, par sin columna). Suite automatic_eda + pipeline render_automatic_eda verde (141 passed). fn index sin error. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
7.4 KiB
7.4 KiB
id, name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, example, tested, tests, test_file_path, file_path, params, output
| id | name | kind | lang | domain | version | purity | signature | description | tags | uses_functions | uses_types | returns | returns_optional | error_type | imports | example | tested | tests | test_file_path | file_path | params | output | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| relationship_scatter_figure_py_datascience | relationship_scatter_figure | function | py | datascience | 1.0.0 | impure | def relationship_scatter_figure(xs: list, ys: list, x_label: str = "", y_label: str = "", classification: dict = None, max_points: int = 2000) -> "matplotlib.figure.Figure" | Construye una figura matplotlib scatter de un par de variables numéricas con su curva/recta de ajuste y una anotación del tipo de relación (lineal, polinómica grado 2/3, monótona no-lineal, etc.) más sus métricas (r, ρ, R²lin, R²poly). Consume el dict de classify_relationship_type; si es None lo calcula internamente reusando esa función. Devuelve un matplotlib.figure.Figure listo para rasterizar por el renderer del informe EDA (PDF/PPTX). Backend Agg sin pyplot global; downsample determinista de los puntos dibujados; defensivo ante vacío/None. |
|
|
false | error_go_core |
|
from relationship_scatter_figure import relationship_scatter_figure xs = [float(i) for i in range(100)] ys = [0.5 * x * x - x + 3 for x in xs] classification = { "tipo": "polinómica (grado 2)", "pearson": 0.97, "spearman": 0.99, "r2_linear": 0.92, "r2_poly2": 0.999, "r2_poly3": 0.999, "best_degree": 2, "coeffs": [0.5, -1.0, 3.0], } fig = relationship_scatter_figure(xs, ys, x_label="dosis", y_label="efecto", classification=classification) | true |
|
python/functions/datascience/relationship_scatter_figure_test.py | python/functions/datascience/relationship_scatter_figure.py |
|
Un matplotlib.figure.Figure (figsize 6.4x4.0, dpi 150) con un Axes scatter (puntos semitransparentes alpha 0.5, color #4C72B0), la curva/recta de ajuste (numpy.polyval sobre coeffs, color #C44E52) cuando hay un ajuste polinómico disponible, título "{x_label} ↔ {y_label}", labels de ejes y una caja de anotación en la esquina superior izquierda con el tipo de relación y las métricas disponibles (r, ρ, R²lin, R²poly; se omiten las None). Si tras la limpieza hay menos de 2 pares válidos, devuelve igualmente una Figure con un texto centrado "Sin datos suficientes para el scatter" (nunca lanza). El caller rasteriza/cierra la figura; la función no la muestra ni la guarda. |
Ejemplo
from relationship_scatter_figure import relationship_scatter_figure
# Par numérico con relación cuadrática y su clasificación (de
# classify_relationship_type). Pasándola explícita evitas recomputarla.
xs = [float(i) for i in range(100)]
ys = [0.5 * x * x - x + 3 for x in xs]
classification = {
"tipo": "polinómica (grado 2)",
"pearson": 0.97,
"spearman": 0.99,
"r2_linear": 0.92,
"r2_poly2": 0.999,
"r2_poly3": 0.999,
"best_degree": 2,
"coeffs": [0.5, -1.0, 3.0],
}
fig = relationship_scatter_figure(
xs, ys, x_label="dosis", y_label="efecto", classification=classification
)
# El renderer del informe lo rasteriza; aquí solo persistimos para inspección.
fig.savefig("/tmp/scatter_dosis_efecto.png")
# Con classification=None la función la calcula internamente (self-contained):
fig2 = relationship_scatter_figure(xs, ys, x_label="dosis", y_label="efecto")
Cuando usarla
Úsala dentro del informe EDA automático cuando quieras visualizar de un vistazo
la relación entre dos variables numéricas: la nube de puntos, la curva que mejor
la ajusta y una etiqueta legible del tipo de relación con sus métricas. Es la
pareja "vista humana" de classify_relationship_type: esa función decide el
tipo y los coeficientes; esta los pinta en una Figure que el renderer del
informe rasteriza a PDF/PPTX. Pásale el dict de clasificación si ya lo tienes
calculado (evitas recomputar el ajuste); si no, déjalo en None y la función lo
resuelve sola sobre los pares limpios. Pensada para móvil: anotación pequeña
(fontsize 8) y nube adelgazada por max_points para que el PDF no pese.
Gotchas
- Impura por matplotlib. Toca la maquinaria de render. Usa el backend
Aggy la API orientada a objetosFigure/add_subplot— NUNCApyplot.*aquí, para no tocar el estado global ni filtrar figuras entre llamadas.pyplotNO es thread-safe; esta función lo evita construyendo elFiguredirectamente, así que es segura de llamar en bucle desde el renderer. - El caller cierra la figura. Devuelve el
Figurepero no lo muestra ni lo guarda. Quien la consume debe rasterizarla y luego liberarla (matplotlib.pyplot.close(fig)) para no acumular memoria en lotes grandes de pares de columnas. - Downsample determinista, solo del dibujo. Cuando los pares limpios superan
max_points, la nube DIBUJADA se adelgaza por paso fijopairs[::step](reproducible, no aleatorio). La clasificación y el ajuste usan SIEMPRE todos los pares limpios; el downsample no altera las métricas ni la curva. classification=None⇒ se calcula sola. Importa y llama aclassify_relationship_typesobre los pares limpios. Si ese módulo hermano no está disponible (entorno incompleto), NO lanza: dibuja el scatter sin curva de ajuste ni anotación. Pasar la clasificación explícita es más barato (no recomputa el ajuste).- Sin curva para
monótona no-lineal. CuandocoeffsesNoneobest_degreeesNone(p.ej. tipo "monótona no-lineal"), no se pinta recta polinómica — solo la nube y la anotación. Tampoco se dibuja la curva si el rango de x es nulo (todos los x iguales). Nunca falla por esto. - Defensiva, nunca lanza.
xs=[],ys=[], menos de 2 pares válidos, endsNone/bool/NaN/infocoeffsmalformado se manejan sin error: en el peor caso devuelve unaFigurecon "Sin datos suficientes para el scatter". No envuelvas la llamada en try/except por miedo a un raise — no lo hay.