feat(eda): series temporales + rigor anti-data-mining + PDF movil + /eda + benchmark issues
Bloque del grupo eda (sesion ausente EDA-benchmark): - 8 funciones nuevas: adf_kpss_stationarity, acf_pacf, stl_decompose, to_returns, fdr_correction, suggest_reexpression, exploratory_caveats, render_eda_pdf - integracion: profile_table (run_series, emit_pdf), association_matrix (FDR Benjamini-Hochberg), render_eda_markdown (secciones series/reexpresion/caveats) - slash commands /eda y /capitulos - issues 0173-0177: mejoras del /eda derivadas del benchmark sobre 12 datasets reales (outlier_pct x100, periodo estacional, FK inference, render models, tipos id-like) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
---
|
||||
name: adf_kpss_stationarity
|
||||
kind: function
|
||||
lang: py
|
||||
domain: datascience
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "def adf_kpss_stationarity(values: list, alpha: float = 0.05) -> dict"
|
||||
description: "Test de estacionariedad de una serie temporal combinando ADF (H0=raiz unitaria/no estacionaria) y KPSS (H0=estacionaria) de statsmodels. Devuelve por test estadistico, p_value, lags y conclusion, mas un veredicto de consenso ('stationary'|'non_stationary'|'inconclusive'). Avisa de correlacion espuria (Granger-Newbold) cuando la serie no es estacionaria. Descarta None/NaN/infinitos; <8 puntos validos -> nota 'datos insuficientes'."
|
||||
tags: [statistics, timeseries, stationarity, adf, kpss, unit-root, eda, forecasting, python]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: [math, warnings, statsmodels]
|
||||
params:
|
||||
- name: values
|
||||
desc: "serie temporal de valores numericos en orden cronologico. None/NaN/infinitos/no-numericos se descartan antes del test."
|
||||
- name: alpha
|
||||
desc: "nivel de significancia para ambos contrastes (default 0.05). p<alpha rechaza la hipotesis nula del test correspondiente."
|
||||
output: "dict con 'adf' y 'kpss' (cada uno: stat, p_value, lags, stationary bool, conclusion), un 'verdict' de consenso ('stationary'|'non_stationary'|'inconclusive'), y 'warning' (texto sobre correlacion espuria si el veredicto no es stationary, si no None). Con <8 puntos validos: {'n', 'note': 'datos insuficientes', 'verdict': None}. Nunca lanza excepcion."
|
||||
tested: true
|
||||
tests: ["test_random_walk_es_no_estacionario", "test_ruido_blanco_es_estacionario", "test_serie_con_tendencia_no_es_estacionaria", "test_muestra_insuficiente_devuelve_nota", "test_descarta_none_y_nan", "test_warning_presente_si_no_estacionaria", "test_estructura_basica_del_dict"]
|
||||
test_file_path: "python/functions/datascience/adf_kpss_stationarity_test.py"
|
||||
file_path: "python/functions/datascience/adf_kpss_stationarity.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
from datascience import adf_kpss_stationarity
|
||||
|
||||
# Ruido blanco: estacionario (ADF rechaza raiz unitaria, KPSS no rechaza estacionariedad)
|
||||
import numpy as np
|
||||
rng = np.random.default_rng(0)
|
||||
ruido = rng.normal(0, 1, 300).tolist()
|
||||
adf_kpss_stationarity(ruido)["verdict"] # -> "stationary"
|
||||
|
||||
# Random walk (suma acumulada): NO estacionario
|
||||
paseo = np.cumsum(rng.normal(0, 1, 300)).tolist()
|
||||
res = adf_kpss_stationarity(paseo)
|
||||
res["verdict"] # -> "non_stationary"
|
||||
res["warning"] # -> aviso de correlacion espuria
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Antes de correlacionar, regresionar o modelar (ARIMA, VAR) una serie temporal,
|
||||
para saber si es estacionaria. Es el primer paso obligatorio del analisis de
|
||||
series: una serie no estacionaria (con tendencia o raiz unitaria) rompe los
|
||||
supuestos de la regresion OLS clasica y, si la correlacionas con otra serie no
|
||||
estacionaria, obtienes una correlacion alta pero **espuria** (Granger-Newbold).
|
||||
Si el veredicto no es `"stationary"`, diferencia la serie o pasala a retornos
|
||||
(`to_returns`) y vuelve a testear.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Es pura pero importa `statsmodels.tsa.stattools` (instalado en `python/.venv`).
|
||||
- ADF y KPSS tienen hipotesis nulas OPUESTAS: en ADF `p<alpha` significa
|
||||
estacionaria; en KPSS `p<alpha` significa NO estacionaria. La funcion ya
|
||||
normaliza ambos a un campo `stationary` coherente — no inviertas tu la logica.
|
||||
- KPSS interpola el p-valor sobre una tabla acotada `[0.01, 0.10]`: si el
|
||||
estadistico cae fuera, statsmodels recorta el p-valor al extremo y lo marca en
|
||||
`kpss.p_value_clipped = True`. Un p recortado a 0.01 o 0.10 es un limite, no un
|
||||
valor exacto.
|
||||
- El veredicto `"inconclusive"` suele indicar serie estacionaria-en-tendencia o
|
||||
que necesita diferenciacion; no es un fallo, es informacion.
|
||||
- Necesita al menos 8 puntos validos tras limpiar; con menos devuelve una nota.
|
||||
Reference in New Issue
Block a user