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:
Egutierrez
2026-06-29 03:34:01 +02:00
parent 02301aaed3
commit 7ac69ab4fb
33 changed files with 3995 additions and 51 deletions
+73
View File
@@ -0,0 +1,73 @@
---
name: acf_pacf
kind: function
lang: py
domain: datascience
version: "1.0.0"
purity: pure
signature: "def acf_pacf(values: list, nlags: int = 40, alpha: float = 0.05) -> dict"
description: "Autocorrelacion (ACF) y autocorrelacion parcial (PACF) de una serie temporal con sus bandas de confianza (statsmodels), mas el test Ljung-Box de autocorrelacion global. Devuelve listas acf/pacf, sus intervalos, los lags significativos y un flag is_autocorrelated. Clave: una serie autocorrelacionada viola IID, asi que los p-valores de una regresion OLS estandar sobre ella estan inflados (Lopez de Prado). Descarta None/NaN; <8 puntos validos -> nota."
tags: [statistics, timeseries, autocorrelation, acf, pacf, ljung-box, arima, eda, forecasting, python]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [math, numpy, statsmodels]
params:
- name: values
desc: "serie temporal de valores numericos en orden cronologico. None/NaN/infinitos/no-numericos se descartan antes del calculo."
- name: nlags
desc: "numero maximo de retardos a calcular (default 40). Se recorta a los limites de statsmodels: n-1 para ACF, (n//2)-1 para PACF."
- name: alpha
desc: "nivel de significancia para las bandas de confianza y el test de Ljung-Box (default 0.05)."
output: "dict con 'acf' y 'pacf' (listas, indice 0 = lag 0), 'acf_confint'/'pacf_confint' (banda por lag), 'significant_acf_lags'/'significant_pacf_lags' (lags >=1 fuera de banda), 'ljung_box' (stat, p_value, lags) e 'is_autocorrelated' (bool: Ljung-Box rechaza independencia). Con <8 puntos: {'n', 'note', 'is_autocorrelated': None}. Nunca lanza excepcion."
tested: true
tests: ["test_ruido_blanco_no_autocorrelado", "test_ar1_es_autocorrelado", "test_lag1_significativo_en_ar1", "test_muestra_insuficiente_devuelve_nota", "test_descarta_none_y_nan", "test_recorta_nlags_a_limites", "test_acf_lag0_es_uno"]
test_file_path: "python/functions/datascience/acf_pacf_test.py"
file_path: "python/functions/datascience/acf_pacf.py"
---
## Ejemplo
```python
from datascience import acf_pacf
import numpy as np
# Ruido blanco: sin autocorrelacion (Ljung-Box no rechaza independencia)
rng = np.random.default_rng(0)
ruido = rng.normal(0, 1, 500).tolist()
acf_pacf(ruido)["is_autocorrelated"] # -> False
# Proceso AR(1) fuerte: autocorrelado, lag 1 significativo en PACF
ar = [0.0]
for _ in range(500):
ar.append(0.8 * ar[-1] + rng.normal(0, 1))
res = acf_pacf(ar)
res["is_autocorrelated"] # -> True
res["significant_pacf_lags"][:1] # -> [1]
```
## Cuando usarla
Para diagnosticar la estructura de dependencia temporal de una serie: identificar
el orden de un modelo ARIMA (PACF corta en el orden AR, ACF corta en el orden MA),
o detectar estacionalidad (picos en lags estacionales). Y, critico para EDA: antes
de meter una variable temporal en una regresion, comprueba `is_autocorrelated`. Si
es `True`, la serie no es IID y los p-valores de OLS estandar estan inflados — hay
que usar errores estandar robustos (Newey-West) o modelar la dinamica
explicitamente (Lopez de Prado).
## Gotchas
- Es pura pero importa `statsmodels` y `numpy` (ambos en `python/.venv`).
- `acf[0]` y `pacf[0]` valen siempre 1.0 (autocorrelacion de la serie consigo
misma en lag 0). Los lags interesantes empiezan en el indice 1.
- `nlags` se recorta automaticamente: PACF exige `nlags < n/2`. Si pides 40 lags
sobre una serie de 30 puntos, `nlags` efectivo baja — mira el campo `nlags`
del resultado para saber cuantos se calcularon.
- Las bandas de confianza asumen ruido blanco bajo H0; en una serie con
tendencia muchos lags saldran "significativos" por la propia tendencia, no por
estructura ARMA. Estaciona primero (ver adf_kpss_stationarity / to_returns).
- Ljung-Box es un test global (todos los lags juntos); los lags individuales
significativos te dicen DONDE esta la autocorrelacion.