fix(eda): hallazgos de comportamiento del benchmark (H2,H3,H6,H7,H8,H10,H11)
Ronda 4 (verificada con re-corrida sobre los datasets afectados): - H2: stl_decompose deriva periodo de la frecuencia del indice (seattle period=365 seasonal_strength=0.84; fin del period=2 espurio) - H3+H10: infer_fk por senal de nombre (<X>Id->X.<X>Id) + excluir no-clave -> chinook 111->9 FK, todas reales, cero absurdas, 16-27x mas rapido; base intacta (flag off->111) - H6: association no computa eta2 si cardinalidad~=n (Ticket-Fare espurio fuera) - H7: id secuencial monotono excluido de correlacion y PCA/KMeans (PassengerId fuera) - H8: correlacion de series no estacionarias marcada espuria / sobre retornos - H11: distribution_type usa modos/cardinalidad/normalidad (quality->discrete) - 66 tests verdes Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -156,3 +156,65 @@ def test_bonferroni_method_is_accepted():
|
||||
assert result["multiple_testing"]["method"] == "bonferroni"
|
||||
pair = _find_pair(result["pairs"], "size", "price")
|
||||
assert pair["p_value_adjusted"] is not None
|
||||
|
||||
|
||||
# --- H6: correlation_ratio espurio por cardinalidad casi-unica ---------------
|
||||
|
||||
def test_h6_categorica_casi_unica_excluida():
|
||||
# Una categorica con cardinalidad ~ n (id/free-text como Ticket) hace que cada
|
||||
# grupo tenga un solo valor -> varianza intra-grupo ~= 0 -> correlation_ratio
|
||||
# = 1 trivial. No debe aparecer ni evaluado ni como par fuerte.
|
||||
n = 60
|
||||
columns = {
|
||||
"ticket": {"values": [f"T{i}" for i in range(n)], "type": "categorical"},
|
||||
"fare": {"values": [float(i) * 1.3 for i in range(n)], "type": "numeric"},
|
||||
}
|
||||
result = association_matrix(columns)
|
||||
assert _find_pair(result["pairs"], "ticket", "fare") is None
|
||||
assert _find_pair(result["strong"], "ticket", "fare") is None
|
||||
|
||||
|
||||
def test_h6_categorica_dispersa_con_nulos_excluida():
|
||||
# Categorica dispersa con muchos None (como Cabin: 147 distintos sobre 204
|
||||
# presentes): los pocos presentes son casi todos distintos -> grupos singleton.
|
||||
# Se mide sobre valores PRESENTES, no sobre n filas, para captarla.
|
||||
vals = [f"C{i}" if i % 4 == 0 else None for i in range(80)] # ~20 presentes, distintos
|
||||
columns = {
|
||||
"cabin": {"values": vals, "type": "categorical"},
|
||||
"fare": {"values": [float(i) for i in range(80)], "type": "numeric"},
|
||||
}
|
||||
result = association_matrix(columns)
|
||||
assert _find_pair(result["pairs"], "cabin", "fare") is None
|
||||
|
||||
|
||||
def test_h6_datetime_excluido_de_pares():
|
||||
# Datetime es indice unico-ish por fila -> correlation_ratio = 1 espurio contra
|
||||
# cualquier numerica. Se excluye de los pares de asociacion (las series se
|
||||
# analizan aparte, no aqui).
|
||||
columns = {
|
||||
"date": {
|
||||
"values": [f"2020-01-{i + 1:02d}" for i in range(10)],
|
||||
"type": "datetime",
|
||||
},
|
||||
"value": {"values": [float(i) for i in range(10)], "type": "numeric"},
|
||||
}
|
||||
result = association_matrix(columns)
|
||||
assert _find_pair(result["pairs"], "date", "value") is None
|
||||
|
||||
|
||||
def test_h6_categorica_legitima_se_conserva():
|
||||
# Edge anti-sobrefiltrado: una categorica de baja cardinalidad (grupos grandes,
|
||||
# tamano medio >= 1.5) SIGUE evaluandose y su asociacion fuerte se conserva.
|
||||
columns = {
|
||||
"region": {
|
||||
"values": ["N", "N", "S", "S", "E", "E", "W", "W"],
|
||||
"type": "categorical",
|
||||
},
|
||||
"score": {
|
||||
"values": [10.0, 11.0, 50.0, 49.0, 90.0, 91.0, 30.0, 31.0],
|
||||
"type": "numeric",
|
||||
},
|
||||
}
|
||||
result = association_matrix(columns)
|
||||
assert _find_pair(result["pairs"], "region", "score") is not None
|
||||
assert _find_pair(result["strong"], "region", "score") is not None
|
||||
|
||||
Reference in New Issue
Block a user