← Catálogo · Capítulo 12

T12_mST_Script_MachineLearning.R

Ver crudo
# ══════════════════════════════════════════════════
# T12 · Series Temporales — Aprendizaje Automático para Series Temporales
# Abre primero mSeriesTemporales.Rproj en RStudio
# ══════════════════════════════════════════════════

library(tidyverse)
library(timetk)
library(modeltime)
library(parsnip)
library(rsample)
library(workflows)
library(recipes)

pausa <- function(msg = "\n  [Pulsa ENTER para continuar...]") {
  if (interactive()) { cat(msg); invisible(readline()) }
}

set.seed(2026)

# ── 1. SERIE SIMULADA CON TENDENCIA Y ESTACIONALIDAD ─
n <- 200
t_idx <- 1:n
serie <- tibble(
  fecha = seq(as.Date("2009-01-01"), by = "month", length.out = n),
  y = 100 + 0.3 * t_idx + 5 * sin(2 * pi * t_idx / 12) + rnorm(n, sd = 1)
)
plot(serie$fecha, serie$y, type = "l", main = "Serie simulada: tendencia + estacionalidad + ruido")
pausa()

# ── 2. INGENIERIA DE CARACTERISTICAS ──────────────
serie_feat <- serie |>
  tk_augment_lags(y, .lags = c(1, 12)) |>
  tk_augment_slidify(y_lag1, .f = mean, .period = 3, .align = "right", .partial = TRUE, .names = "roll3") |>
  drop_na()
cat("Primeras filas de la tabla de caracteristicas:\n")
print(head(serie_feat))
pausa()

# ── 3. XGBOOST SOBRE EL NIVEL: EL PROBLEMA DE EXTRAPOLAR ─
split <- time_series_split(serie_feat, date_var = fecha, assess = "24 months", cumulative = TRUE)
rec <- recipe(y ~ fecha + y_lag1 + y_lag12 + roll3, data = training(split)) |>
  step_timeseries_signature(fecha) |>
  step_rm(matches("(iso$)|(xts$)|(hour)|(minute)|(second)|(am.pm)|(lbl)")) |>
  step_normalize(matches("(index.num)|(year)")) |>
  step_rm(fecha)
wflow <- workflow() |> add_model(boost_tree(mode = "regression") |> set_engine("xgboost")) |> add_recipe(rec)
m_xgb <- recursive(
  fit(wflow, data = training(split)),
  transform = function(data) data |> tk_augment_lags(y, .lags = c(1, 12)) |>
    tk_augment_slidify(y_lag1, .f = mean, .period = 3, .align = "right", .partial = TRUE, .names = "roll3"),
  train_tail = tail(training(split), 13)
)
fc <- predict(m_xgb, testing(split))$.pred
real <- testing(split)$y
cat(sprintf("Rango entrenamiento: [%.1f, %.1f]  |  Rango predicciones: [%.1f, %.1f]\n",
            min(training(split)$y), max(training(split)$y), min(fc), max(fc)))
cat(sprintf("RECM = %.3f\n", sqrt(mean((real - fc)^2))))
cat("Nota: si la tendencia simulada es fuerte, las predicciones quedan por debajo del nivel real,\n")
cat("      pegadas al limite superior de los valores vistos en entrenamiento.\n")

# === FIN Script T12 — Aprendizaje Automático para Series Temporales ===