7ac69ab4fb
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>
73 lines
3.9 KiB
Markdown
73 lines
3.9 KiB
Markdown
---
|
|
name: stl_decompose
|
|
kind: function
|
|
lang: py
|
|
domain: datascience
|
|
version: "1.0.0"
|
|
purity: pure
|
|
signature: "def stl_decompose(values: list, period: int = None, robust: bool = True) -> dict"
|
|
description: "Descomposicion STL (Seasonal-Trend using Loess, statsmodels) de una serie temporal en tendencia, estacional y resto. Si period es None lo infiere por autocorrelacion. Devuelve las 3 componentes (o estadisticos si son largas), mas la fuerza de tendencia y de estacionalidad de Hyndman (1 - Var(resto)/Var(resto+componente)). Descarta None/NaN; serie corta (<2*period) -> nota."
|
|
tags: [statistics, timeseries, decomposition, stl, seasonality, trend, 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 de descomponer."
|
|
- name: period
|
|
desc: "periodo estacional (observaciones por ciclo, p.ej. 12 para mensual con estacionalidad anual). Si None se infiere por autocorrelacion; si no hay periodo claro devuelve nota."
|
|
- name: robust
|
|
desc: "si True (default) usa el ajuste robusto de STL, que reduce el efecto de outliers sobre tendencia y estacionalidad."
|
|
output: "dict con 'period' usado, 'period_inferred' (bool), 'trend'/'seasonal'/'resid' (cada uno min/max/mean/std + values si la serie es corta, si no None), 'trend_strength' y 'seasonal_strength' (medidas de Hyndman en [0,1]). Serie insuficiente o sin periodo inferible: dict con 'note' y strengths en None. Nunca lanza excepcion."
|
|
tested: true
|
|
tests: ["test_serie_con_tendencia_y_estacionalidad", "test_fuerza_estacional_alta_con_estacionalidad_fuerte", "test_infiere_periodo_si_none", "test_serie_corta_devuelve_nota", "test_muestra_insuficiente_devuelve_nota", "test_descarta_none_y_nan", "test_serie_larga_resume_sin_values"]
|
|
test_file_path: "python/functions/datascience/stl_decompose_test.py"
|
|
file_path: "python/functions/datascience/stl_decompose.py"
|
|
---
|
|
|
|
## Ejemplo
|
|
|
|
```python
|
|
from datascience import stl_decompose
|
|
import numpy as np
|
|
|
|
# Serie mensual = tendencia lineal + ciclo estacional anual (periodo 12) + ruido
|
|
rng = np.random.default_rng(0)
|
|
n = 120
|
|
serie = [0.3 * i + 10 * np.sin(2 * np.pi * i / 12) + rng.normal(0, 1) for i in range(n)]
|
|
|
|
res = stl_decompose(serie, period=12)
|
|
res["trend_strength"] # -> ~0.99 (tendencia clara)
|
|
res["seasonal_strength"] # -> ~0.98 (estacionalidad clara)
|
|
res["seasonal"]["values"][:3] # primeras 3 muestras de la componente estacional
|
|
|
|
# Sin pasar periodo: lo infiere por autocorrelacion
|
|
stl_decompose(serie)["period_inferred"] # -> True
|
|
```
|
|
|
|
## Cuando usarla
|
|
|
|
Cuando quieres separar una serie temporal en sus partes para entenderla o
|
|
prepararla para modelar: cuanta de su variacion es tendencia de fondo, cuanta es
|
|
ciclo estacional repetitivo y cuanta es ruido. Util en EDA para decidir si merece
|
|
la pena desestacionalizar antes de comparar periodos, para detectar un cambio de
|
|
tendencia, o para extraer features (las fuerzas de tendencia/estacionalidad de
|
|
Hyndman resumen la serie en dos numeros comparables entre series).
|
|
|
|
## Gotchas
|
|
|
|
- Es pura pero importa `statsmodels.tsa.seasonal.STL` y `numpy` (en `python/.venv`).
|
|
- STL exige al menos **dos ciclos completos**: con `n < 2*period` devuelve una
|
|
nota en vez de descomponer. Para datos mensuales con estacionalidad anual
|
|
(period=12) necesitas >= 24 meses.
|
|
- La inferencia automatica de `period` busca el pico de autocorrelacion; es
|
|
heuristica. Si conoces el periodo real (12 mensual, 7 diario-semanal, 24
|
|
horario-diario), pasalo explicito: es mas fiable.
|
|
- Las componentes largas (> 200 puntos) se resumen en estadisticos y `values`
|
|
queda en `None` para no inflar el payload; las cortas vienen completas.
|
|
- Las fuerzas estan en `[0,1]` por construccion (se recortan a 0 si la varianza
|
|
del resto supera la de resto+componente, lo que indica componente inexistente).
|