--- id: run_eda_models_py_datascience name: run_eda_models kind: function lang: py domain: datascience version: "1.0.0" purity: pure signature: "def run_eda_models(columns: dict, run_pca: bool = True, run_kmeans: bool = True, run_isolation: bool = True, run_normality: bool = True) -> dict" description: "Orquesta los modelos baratos del grupo eda (PCA, KMeans, Isolation Forest, normalidad) sobre las columnas numericas de un perfil de tabla y devuelve el bloque models de un TableProfile. Composicion canonica del flag --models de profile_table. Compone funciones puras del registry, no reescribe logica." tags: [eda, models, datascience, profiling, pca, kmeans, isolation-forest, normality, multivariate, composition] uses_functions: - pca_explained_py_datascience - kmeans_segments_py_datascience - isolation_forest_outliers_py_datascience - normality_tests_py_datascience uses_types: [] returns: [] returns_optional: false error_type: "" imports: [datascience] example: | from run_eda_models import run_eda_models cols = { "x": {"values": [1.0, 2.0, 3.0, 4.0], "type": "numeric"}, "y": {"values": [2.0, 4.0, 6.0, 8.0], "type": "numeric"}, "z": {"values": [5.0, 4.0, 6.0, 5.5], "type": "numeric"}, } block = run_eda_models(cols) # block["n_numeric_cols"] == 3; block["pca"], block["kmeans"], block["normality"] poblados tested: true tests: - "test_three_numeric_columns_runs_all_models" - "test_single_numeric_column_note_and_normality_only" - "test_flags_disable_models" - "test_no_numeric_columns_returns_note_and_no_normality" test_file_path: "python/functions/datascience/run_eda_models_test.py" file_path: "python/functions/datascience/run_eda_models.py" params: - name: columns desc: "Mapa {nombre_columna: {values: list, type: 'numeric'|'categorical'|'datetime'|...}}. Mismo shape que recibe association_matrix; listas alineadas por fila. Solo las columnas con type=='numeric' alimentan los modelos." - name: run_pca desc: "Si True, ejecuta pca_explained sobre el subconjunto numerico (estructura latente / varianza explicada). Default True." - name: run_kmeans desc: "Si True, ejecuta kmeans_segments con seleccion automatica de k por silhouette (segmentos naturales). Default True." - name: run_isolation desc: "Si True, ejecuta isolation_forest_outliers (anomalias multivariante). Default True." - name: run_normality desc: "Si True, ejecuta normality_tests por cada columna numerica. Es univariante: basta 1 columna. Default True." output: > dict con {n_numeric_cols, pca, kmeans, outliers, normality, note}. pca/kmeans/outliers son la salida de su funcion del registry o None (flag desactivado o <2 columnas numericas). normality es {col: salida de normality_tests} o None (flag desactivado o sin columnas numericas). Con <2 columnas numericas los multivariantes quedan en None y note = "insuficientes columnas numericas para modelos multivariantes" (normality sigue poblandose si hay >=1 columna numerica). Con >=2 columnas y todo activado, note = "". Nunca lanza excepcion. --- ## Ejemplo ```python from run_eda_models import run_eda_models import numpy as np rng = np.random.default_rng(0) n = 120 x = rng.normal(0, 1, n) y = x * 2 + rng.normal(0, 0.3, n) # correlacionada con x z = rng.normal(5, 1, n) # ruido independiente cols = { "x": {"values": x.tolist(), "type": "numeric"}, "y": {"values": y.tolist(), "type": "numeric"}, "z": {"values": z.tolist(), "type": "numeric"}, } models = run_eda_models(cols) models["n_numeric_cols"] # 3 models["pca"]["explained_variance_ratio"] # PC1 concentra la varianza de x/y models["kmeans"]["best_k"] # k elegido por silhouette models["outliers"]["n_outliers"] # filas anomalas multivariante models["normality"]["z"]["is_normal"] # True (z es normal) models["note"] # "" # Una sola columna numerica: solo normalidad, multivariantes en None solo = {"v": {"values": x.tolist(), "type": "numeric"}} run_eda_models(solo)["note"] # "insuficientes columnas numericas para modelos multivariantes" ``` ## Cuando usarla Es la capa `--models` de un EDA: cuando ya tienes el perfil de columnas de una tabla (mismo shape que alimenta `association_matrix`) y quieres, de un solo golpe, la estructura latente (PCA), los segmentos naturales (KMeans), las anomalias multivariante (Isolation Forest) y la normalidad de cada columna numerica. En vez de llamar a las cuatro funciones por separado y montar el bloque a mano, esta las compone y devuelve el bloque `models` listo para incrustar en un `TableProfile`. Usa los flags `run_*` para apagar los modelos que no necesites. ## Gotchas - PCA, KMeans e Isolation Forest son multivariantes y necesitan **>=2 columnas numericas**; con menos, sus claves quedan en `None` y se devuelve `note`. La normalidad es univariante y se corre con 1 columna. - Cada modelo subyacente tiene su propio umbral minimo de filas validas y puede devolver `{"note": "datos insuficientes"}` (PCA: >=3 filas; KMeans: >=k_min*2; Isolation Forest: >=10 filas; normalidad: >=8 tras limpiar). Esta funcion los propaga tal cual dentro del bloque, sin petar. - Solo se usan columnas con `type == "numeric"`. Los valores se convierten a `float` cuando es posible; None, booleanos y no parseables se descartan por columna, asi que la longitud efectiva puede ser menor que la lista original. - `trend_slope` NO se ejecuta aqui: requiere un orden temporal explicito y queda disponible suelto en el registry. - Aunque compone funciones impuras-en-apariencia (sklearn/scipy), todas son deterministas (`random_state=0`), por lo que el resultado es reproducible para una misma entrada.