---
id: "0177"
title: "EDA tipos: id secuencial fuera de correlación/PCA + η² espurio por cardinalidad + re-expresión no-continuas"
status: completado
type: bugfix
domain:
  - registry-quality
scope: registry-only
priority: media
depends: []
blocks: []
related: ["0173", "0174", "0175", "0176"]
created: 2026-06-29
updated: 2026-06-29
tags: [eda, datascience, profile_table, association_matrix, correlation_ratio, run_eda_models, suggest_reexpression, benchmark]
---
# 0177 — EDA tipos: id secuencial fuera de correlación/PCA + η² espurio

## Contexto

El benchmark `/eda` (29/06/2026, `temp/eda_benchmark/EVALUATION.md`) **refutó** el riesgo temido
(que el EDA excluyera columnas financieras `Open/Close/High/Low/Volume` por marcarlas id-like: NO
ocurre, aparecen en todo). Pero detectó el **problema inverso**: el flag `possible_id` es cosmético
y no excluye lo que sí debería (índices secuenciales), y la razón de correlación η² da artefactos
≈1 por cardinalidad.

Hallazgos cubiertos:

| Hallazgo | Severidad | Evidencia del benchmark |
|---|---|---|
| H7 — `possible_id` no excluye id secuencial (`PassengerId`) de correlación ni de PCA/KMeans | medio-alto | titanic `PassengerId–Cabin` η²=0.897 `sig=sí`; `models.pca.n_features=7` incluye `PassengerId`, `Survived`, `Pclass` |
| H6 — `correlation_ratio` (η²) ≈1 espurio cuando la categórica tiene cardinalidad ≈ n | alto | titanic `Ticket–Fare=1 sig=sí` (`Ticket` 681 distintos/891); aapl/btc/seattle/fred `Date–* =1` |
| H12 — `suggest_reexpression` sugiere fila para binarias/ordinales/ids (aunque sea `none`) | bajo | titanic `Survived` (0/1), `Pclass` (ordinal), `PassengerId` (id) listadas |

### Causa raíz (verificada en código, READ-ONLY)

- `python/functions/pipelines/profile_table.py:356-361` (`_skip_for_assoc`) excluye de la matriz de
  asociación las columnas id-like **categóricas/text** (`possible_id`/`high_cardinality`), pero **no**
  excluye numéricas secuenciales (`PassengerId` es numérica con `possible_id`) ni columnas datetime.
  El `assoc_input` resultante se pasa tal cual a `run_eda_models` (`:391`), así que el id secuencial,
  el target binario y el ordinal entran como features de PCA/KMeans.
- H6: `correlation_ratio.py` calcula η² sin guard de cardinalidad; cuando cada grupo tiene ~1
  observación (categórica de cardinalidad ≈ n), la varianza intra-grupo ≈0 → η²≈1 trivialmente. El
  FDR no protege (artefacto determinista, no azar).
- H12: `suggest_reexpression` (llamado en `profile_table.py:300` para toda numérica) no salta
  binarias/ordinales/ids.

## Tareas

1. **H7 — distinguir id secuencial de float continuo:** en la detección de tipos
   (`summarize_table_duckdb.py` / lógica de `possible_id`) o en `profile_table.py`, marcar
   "índice entero secuencial/monótono" distinto de "float continuo de alta cardinalidad". El primero
   se excluye de correlación y de PCA/KMeans; el segundo se mantiene (precios). **Nunca** excluir
   floats continuos.
2. **H7 — excluir no-features de los modelos:** en `_skip_for_assoc` (y/o en `run_eda_models.py`)
   excluir de PCA/KMeans los ids secuenciales, binarias, ordinales y el target evidente, además de
   las categóricas id-like que ya se excluyen.
3. **H6 — guard de cardinalidad en η²:** en `correlation_ratio.py` (y/o al construir los pares en
   `association_matrix.py`/`profile_table.py`), no computar η² si la categórica tiene cardinalidad
   cercana a `n` o tamaño de grupo medio ≈1; excluir columnas datetime/id de los pares categóricos.
4. **H12 — saltar no-continuas en re-expresión:** en `suggest_reexpression.py` (o en la llamada de
   `profile_table.py:300`), no emitir fila de re-expresión para binarias/ordinales/ids.
5. Tests: `correlation_ratio_test.py` (categórica cardinalidad≈n → no η²≈1 espurio);
   `run_eda_models_test.py` (id secuencial/target/ordinal no entran como features);
   `suggest_reexpression_test.py` (binaria/ordinal/id → sin sugerencia).

## Definition of Done

| Escenario | Tipo | Comando / evidencia | Resultado esperado |
|---|---|---|---|
| Golden: id secuencial fuera | e2e | re-correr `profile_table(run_models=True)` sobre titanic | `PassengerId` NO aparece en correlaciones ni en `models.pca.features`; floats continuos (precios en aapl/btc) SÍ se conservan |
| Golden: η² sin artefacto | e2e | re-correr sobre titanic | `Ticket–Fare` y `Date–*` NO aparecen como par fuerte η²=1 |
| Edge: float continuo | unit | `correlation_ratio_test.py` / detección de tipos | columna float de alta cardinalidad (precio) se mantiene en correlación |
| Edge: re-expresión | unit | `suggest_reexpression_test.py` con binaria/ordinal/id | sin fila de re-expresión |
| Error: solo numéricas | unit | `run_eda_models` con assoc_input vacío tras filtrar | sin crash; bloque models coherente |
| Mecánica | — | `./fn run correlation_ratio_py_datascience`, `./fn run run_eda_models_py_datascience`, `./fn run suggest_reexpression_py_datascience`; `fn index` | tests verdes; índice limpio |

Re-correr el benchmark sobre titanic (id secuencial + η² espurio) y sobre aapl/btc (confirmar que
los floats financieros NO se excluyen) y verificar ambos comportamientos.

## Notas

Issue derivado de `temp/eda_benchmark/EDA_ISSUES.md`. El warning "grave" del benchmark (excluir
columnas financieras) quedó **refutado**: este issue arregla el problema inverso real (no excluir
ids secuenciales) sin tocar el tratamiento correcto de los floats continuos. Hermanos: 0173, 0174,
0175, 0176.


## Resolucion (2026-06-29, sesion /ausente)
Resuelto y verificado con re-corrida del benchmark EDA. Commit principal: e142ef02. Detalle en reports/ausente-eda-benchmark-2026-06-29.md y temp/eda_benchmark/EVALUATION.md.
