feat(browser): auto-commit con 178 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
"""Orquesta los modelos baratos del grupo `eda` en un solo bloque.
|
||||
|
||||
Compone las funciones puras de modelado del registry (PCA, KMeans, Isolation
|
||||
Forest, tests de normalidad) sobre el subconjunto de columnas numericas de un
|
||||
perfil de tabla y devuelve el bloque "models" canonico que consume el flag
|
||||
``--models`` de ``profile_table``. No reescribe logica: delega en cada funcion
|
||||
del registry. Es pura y determinista (todas las dependencias lo son).
|
||||
"""
|
||||
|
||||
from datascience import (
|
||||
isolation_forest_outliers,
|
||||
kmeans_segments,
|
||||
normality_tests,
|
||||
pca_explained,
|
||||
)
|
||||
|
||||
|
||||
def _to_numeric_subset(columns: dict) -> dict:
|
||||
"""Extrae las columnas numericas como {nombre: [float values]}.
|
||||
|
||||
Solo se quedan las columnas con ``type == "numeric"``. Para cada una, los
|
||||
valores se convierten a float cuando es posible y los que son None o no
|
||||
parseables se descartan (la lista resultante puede ser mas corta que la
|
||||
original). Mantiene el orden de aparicion de las columnas.
|
||||
|
||||
Args:
|
||||
columns: mapa {nombre_columna: {"values": list, "type": str}}.
|
||||
|
||||
Returns:
|
||||
dict {nombre_columna: [float, ...]} solo con columnas numericas.
|
||||
"""
|
||||
numeric: dict[str, list] = {}
|
||||
if not isinstance(columns, dict):
|
||||
return numeric
|
||||
for name, meta in columns.items():
|
||||
if not isinstance(meta, dict):
|
||||
continue
|
||||
if meta.get("type") != "numeric":
|
||||
continue
|
||||
values = meta.get("values")
|
||||
if not isinstance(values, (list, tuple)):
|
||||
continue
|
||||
parsed: list[float] = []
|
||||
for v in values:
|
||||
if v is None or isinstance(v, bool):
|
||||
continue
|
||||
try:
|
||||
parsed.append(float(v))
|
||||
except (TypeError, ValueError):
|
||||
continue
|
||||
numeric[name] = parsed
|
||||
return numeric
|
||||
|
||||
|
||||
def run_eda_models(
|
||||
columns: dict,
|
||||
run_pca: bool = True,
|
||||
run_kmeans: bool = True,
|
||||
run_isolation: bool = True,
|
||||
run_normality: bool = True,
|
||||
) -> dict:
|
||||
"""Ejecuta los modelos baratos del grupo `eda` sobre las columnas numericas.
|
||||
|
||||
Composicion canonica para el flag ``--models`` de ``profile_table``. Toma el
|
||||
mapa de columnas con el mismo shape que recibe ``association_matrix`` (cada
|
||||
columna con ``values`` y ``type``), extrae el subconjunto numerico, y corre
|
||||
los modelos pedidos sobre el. No reescribe ninguno: compone las funciones
|
||||
puras ``pca_explained``, ``kmeans_segments``, ``isolation_forest_outliers``
|
||||
y ``normality_tests`` del registry.
|
||||
|
||||
Los tests de normalidad se corren por columna numerica individual (basta 1
|
||||
columna). PCA, KMeans e Isolation Forest son multivariantes y necesitan al
|
||||
menos 2 columnas numericas; con menos, sus claves quedan en None y se
|
||||
devuelve una ``note`` explicativa. No lanza excepciones.
|
||||
|
||||
``trend_slope`` NO se ejecuta aqui: requiere un orden temporal explicito y
|
||||
queda disponible suelto en el registry.
|
||||
|
||||
Args:
|
||||
columns: mapa {nombre_columna: {"values": list, "type": str}}, mismo
|
||||
shape que recibe ``association_matrix``; listas alineadas por fila.
|
||||
run_pca: si True, ejecuta PCA sobre el subconjunto numerico.
|
||||
run_kmeans: si True, ejecuta KMeans con seleccion automatica de k.
|
||||
run_isolation: si True, ejecuta Isolation Forest multivariante.
|
||||
run_normality: si True, ejecuta tests de normalidad por columna.
|
||||
|
||||
Returns:
|
||||
dict con:
|
||||
n_numeric_cols: numero de columnas numericas detectadas.
|
||||
pca: salida de pca_explained o None (si run_pca False / <2 cols).
|
||||
kmeans: salida de kmeans_segments o None (si run_kmeans False / <2).
|
||||
outliers: salida de isolation_forest_outliers o None.
|
||||
normality: {col: salida de normality_tests} o None (si run_normality
|
||||
False o no hay columnas numericas).
|
||||
note: descripcion de por que faltan los multivariantes, si aplica.
|
||||
|
||||
Con menos de 2 columnas numericas devuelve los multivariantes en None y
|
||||
una ``note``; ``normality`` sigue poblandose si run_normality True y hay
|
||||
al menos 1 columna numerica.
|
||||
"""
|
||||
numeric = _to_numeric_subset(columns)
|
||||
n_numeric_cols = len(numeric)
|
||||
|
||||
# normality es univariante: basta una columna numerica.
|
||||
normality = None
|
||||
if run_normality and n_numeric_cols >= 1:
|
||||
normality = {name: normality_tests(values) for name, values in numeric.items()}
|
||||
|
||||
if n_numeric_cols < 2:
|
||||
return {
|
||||
"n_numeric_cols": n_numeric_cols,
|
||||
"pca": None,
|
||||
"kmeans": None,
|
||||
"outliers": None,
|
||||
"normality": normality,
|
||||
"note": "insuficientes columnas numericas para modelos multivariantes",
|
||||
}
|
||||
|
||||
pca = pca_explained(numeric) if run_pca else None
|
||||
kmeans = kmeans_segments(numeric) if run_kmeans else None
|
||||
outliers = isolation_forest_outliers(numeric) if run_isolation else None
|
||||
|
||||
return {
|
||||
"n_numeric_cols": n_numeric_cols,
|
||||
"pca": pca,
|
||||
"kmeans": kmeans,
|
||||
"outliers": outliers,
|
||||
"normality": normality,
|
||||
"note": "",
|
||||
}
|
||||
Reference in New Issue
Block a user