--- 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.