caf8c25d99
- H1: render_eda_markdown ya no aplica doble x100 a outlier_pct (336% -> real) - H5: profile_database filtra base_tables_only (excluye VIEWs; sakila 21->16) - H12: suggest_reexpression salta columnas no-continuas - H13: to_returns/profile_table elige retornos (financiera) vs diferencias (fisica) - H14: test de regresion ATTACH sqlite via information_schema - +8 tests de las funciones eda nuevas (acf_pacf, adf_kpss, ...). 77 tests verdes - L/M (H2,H3,H4,H6,H7,H8,H9,H10,H11) quedan en issues 0174-0177 para revision Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
72 lines
1.9 KiB
Python
72 lines
1.9 KiB
Python
"""Tests para acf_pacf."""
|
|
|
|
import numpy as np
|
|
|
|
from acf_pacf import acf_pacf
|
|
|
|
|
|
def _ar1(phi: float, n: int, seed: int) -> list:
|
|
rng = np.random.default_rng(seed)
|
|
series = [0.0]
|
|
for _ in range(n):
|
|
series.append(phi * series[-1] + rng.normal(0, 1))
|
|
return series
|
|
|
|
|
|
def test_ruido_blanco_no_autocorrelado():
|
|
rng = np.random.default_rng(0)
|
|
ruido = rng.normal(0, 1, 500).tolist()
|
|
res = acf_pacf(ruido)
|
|
assert res["is_autocorrelated"] is False
|
|
|
|
|
|
def test_ar1_es_autocorrelado():
|
|
ar = _ar1(0.8, 500, seed=1)
|
|
res = acf_pacf(ar)
|
|
assert res["is_autocorrelated"] is True
|
|
|
|
|
|
def test_lag1_significativo_en_ar1():
|
|
# En un AR(1) la PACF corta tras el lag 1: lag 1 debe ser significativo.
|
|
ar = _ar1(0.8, 500, seed=2)
|
|
res = acf_pacf(ar)
|
|
assert 1 in res["significant_pacf_lags"]
|
|
assert 1 in res["significant_acf_lags"]
|
|
|
|
|
|
def test_muestra_insuficiente_devuelve_nota():
|
|
res = acf_pacf([1, 2, 3, 4, 5])
|
|
assert res["n"] == 5
|
|
assert res["note"] == "datos insuficientes"
|
|
assert res["is_autocorrelated"] is None
|
|
|
|
|
|
def test_descarta_none_y_nan():
|
|
rng = np.random.default_rng(3)
|
|
base = rng.normal(0, 1, 200).tolist()
|
|
sucio = []
|
|
for i, v in enumerate(base):
|
|
sucio.append(v)
|
|
if i % 25 == 0:
|
|
sucio.append(None)
|
|
sucio.append(float("nan"))
|
|
res = acf_pacf(sucio)
|
|
assert res["n"] == 200
|
|
|
|
|
|
def test_recorta_nlags_a_limites():
|
|
# Serie de 20 puntos con nlags=40: debe recortar a < n/2.
|
|
rng = np.random.default_rng(4)
|
|
serie = rng.normal(0, 1, 20).tolist()
|
|
res = acf_pacf(serie, nlags=40)
|
|
assert res["nlags"] < 20 // 2
|
|
assert len(res["acf"]) == res["nlags"] + 1
|
|
|
|
|
|
def test_acf_lag0_es_uno():
|
|
rng = np.random.default_rng(5)
|
|
serie = rng.normal(0, 1, 100).tolist()
|
|
res = acf_pacf(serie)
|
|
assert abs(res["acf"][0] - 1.0) < 1e-9
|
|
assert abs(res["pacf"][0] - 1.0) < 1e-9
|