= arima.sim(n=100, model = list(ar = c(0.5,0.4)))
arima_10
par(mfrow = c(1, 2))
|> acf()
arima_10 |> pacf() arima_10
LASSO, AdaLASSO e WLAdaLASSO em Séries Temporais
1 Séries Temporais e Seleção de Ordem de Parâmetros
Um aspecto crucial na análise de séries temporais é a seleção de ordem de parâmetros. A ordem dos parâmetros refere-se aos diferentes componentes que um modelo de série temporal deve considerar para capturar as dinâmicas subjacentes dos dados. Por exemplo, em um modelo AutoRegressive Integrated Moving Average (ARIMA), a ordem dos parâmetros determina quantos valores passados (lags) e quantos erros passados devem ser incluídos no modelo.
A seleção de ordem de parâmetros é um passo fundamental, pois influencia diretamente a capacidade do modelo de prever corretamente valores futuros. A escolha inadequada dos parâmetros pode levar a modelos que superajustam os dados históricos, capturando o ruído em vez do sinal real, ou a modelos que subajustam, ignorando padrões importantes.
Tradicionalmente, métodos como análise de Função Auto-Correlação (FAC) e Função Auto-Correlação Parcial (FACP) são utilizados para determinar a ordem dos parâmetros. Contudo, esses métodos podem ser lentos e exigentes em termos de computação, especialmente quando aplicados a conjuntos de dados grandes ou a múltiplas séries temporais, como em análises que envolvem diferentes estados ou regiões geográficas.
Nos últimos anos, técnicas automatizadas de seleção de ordem de parâmetros têm ganhado popularidade. Propostas por pesquisadores como Hyndman e Khandakar, essas técnicas empregam abordagens stepwise para otimizar a seleção de parâmetros de forma mais eficiente. Embora métodos stepwise sejam computacionalmente mais rápidos e frequentemente eficazes, eles também têm suas limitações, incluindo a possibilidade de resultados ambíguos e a necessidade de estimar vários modelos até encontrar o melhor.
Com o avanço contínuo da ciência de dados, novas metodologias, como regularização e aprendizado de máquina, estão emergindo como alternativas promissoras. Essas abordagens podem lidar com a crescente complexidade e volume de dados de maneira mais robusta, oferecendo soluções mais precisas e eficientes para a seleção de ordem de parâmetros em séries temporais.
OBS É importante fixar que nesse estudo trabalharemos apenas com o modelo ARIMA, onde métodos de regularização foram utilizados para seleção de ordem de parâmetros
1.1 Método Usual
O principal e mais simples método para seleção de ordem de coeficientes para um modelo de séries temporias consiste na avalição das funções de Autocorrelação e Autocorrelação Parcial, chamadas de FAC e FACP respectivamente
Apesar de sua simplicidade, tal método é totalmente dependente do nível de sensibilidade do pesquisador em captar dacaimentos e trucamentos na FAC e FACP e portanto pode ser considerado um método em certo grau subjeitvo, dependendo do grau de complexidade dos dados estudados.
Além disse, é um método lento para dados que demandam rápida estimação, como por exemplo estimar modelos para cada estado do Brasil, onde seria necessária a análise 27 FACs e 27 FACPs.
- FAC e FACP de um ARMA(1,0)
- FAC e FACP de um ARMA(2,2)
= arima.sim(n=100, model = list(ar = c(0.5,0.4), ma = c(0.5, 0.4)))
arima_22
par(mfrow = c(1, 2))
|> acf()
arima_22 |> pacf() arima_22
- FAC E FACP de Dados Reais
- Ações da APPLE
::gafa_stock |>
tsibbledatafilter(Symbol == 'AAPL') |>
mutate(High = difference(High)) |>
gg_tsdisplay(y = High, plot_type = 'partial')
- Consumo de Animais na Austrália
::aus_livestock |>
tsibbledatafilter(Animal == 'Bulls, bullocks and steers',
== 'Australian Capital Territory',
State < lubridate::ymd("1993-03-01")) |>
Month gg_tsdisplay(plot_type = 'partial')
Dentro do contexto apresentado, Hyndman e Khandakar (2008), foram um dos primeiros a sugerirem formas automáticas de seleção de ordem de parâmetro para modelos de séries temporais
1.2 Stepwise
O método proposto por Hyndman e Khandakar se baseia em um stepwise para séries temporais Apesar do método ser satisfatório em inúmeros casos, como todo método stepwise ele apresenta um baixo desempenho computacional, onde diversos modelos devem ser estimados até encontrar aquele desejado.
Nesse contexto, trabalhos mais recentes utilizam uma abordagem um pouco: a estimação de apenas 1 modelo, onde esse deve ser o modelo ótimo
1.3 Regularização
Dentro do contexto de regressão e aprendizado de máquina, os métodos de regularização se destacam por sua eficiência na seleção de modelos e na prevenção de overfitting. Eles oferecem uma maneira robusta de lidar com alta dimensionalidade e multicolinearidade nas variáveis, proporcionando modelos mais simples e interpretáveis.
Os mais conhecidos são:
Ridge _ Também chamada de regularização L2, é utilizado para estimação em alta dimensionalidade onde deseja-se minizar certas estimativas, sem necessariamente zerar coeficientes
LASSO
- Também chamada de regularização L1. Pode ser utilizada como método para seleção de variáveis, dado que sua construção possibilita a estimação de \(\beta = 0\)
2 Ajustando melhores ordens AR E MA via LASSO
O ajuste de um LASSO para séries temporais se divide em 2 etapas:
- Procura da ordem AR
- Como o próprio nome diz, a parte autorregresiva equivale a uma regressão, onde as variável resposta é o valor da série em um dado tempo \(t\), ou seja \(y_t\), e suas covariáveis são seus lags, ou seja \(y_{t-1}, y_{t-2}, ..., y_{t-p_0}\). Para a execução da LASSO, uma matrix é construida, onde a primeira coluna representa os \(y_t\) e as demais colunas representam \(y_{t-1}, y_{t-2}, ..., y_{t-p_0}\), onde \(p_0\) é o grau máximo autorregressivo definido pelo usuário. Dado as estimativas da LASSO, observa-se o último lag significativo, armazenado a ordem \(p_L\) (Autorregressiva via LASSO)
- Procura da ordem MA
Alguns métodos distintos são propostos para a procura da ordem de médias móveis. Tal parcela busca modelar o erro do modelo a cada lag e portanto depende de um modelo inicial para sua estimação, diferente da parcela AR, que depende apenas dos próprios valores da série.
Dado um modelo inicial AR\((p_L)\), é possível calcular o erro a cada lag, e portanto é possível definir os termos \(e_{t-1}, e_{t-2}, ... e_{t-q}\). A partir disso, uma nova regressão LASSO é rodada, onde observa-se o último lag diferente de 0, assim como na etapa 1, onde é retornada a ordem \(q_L\) (Médias Móveis via LASSO)
- Estimação do Modelo Final Tais etapas buscam apenas selecionar as ordens \((p, q)\) e não necessariamente os valores de cada parâmetro. Assim, dado o encontro das ordens de cada parâmetro via LASSO, sendo chamadas de ordens \((p_{L}, q_{L})\), deve-se estimar da maneira usual (mínimos quadrados), os valores de cada parâmetro
3 Simulação
Tal etapa buscou estudar com dados simulados a capacidade de acertar o verdadeiro modelo da ambos os métodos de seleção de ordens de parâmetros
Para a procura de modelos ARIMA via LASSO, a seguinte função foi definida
= function(tsbl_data, init_lags){
arima_lasso
= tsbl_data |>
ar_lags ::as_tibble() |>
tibble::select(x)
dplyr
= lapply(1:init_lags,
ar_lags function(i){
lead(ar_lags, i)
|>
}) bind_cols() |>
mutate(
across(everything(),
~ case_when(is.na(.) ~ 0,
TRUE ~ .)
)
)
= glmnet::glmnet(y = tsbl_data[, 1] |> as.matrix(),
lasso_model x = ar_lags |> as.matrix(),
alpha = 1, intercept = F)
= lasso_model |>
ar_lasso_coef coef(s = 0.1) |>
as.vector()
= which(ar_lasso_coef == 0)[2] - 2
ar_lasso_coef
= tsbl_data |>
ma_model model(ma_init_model =
ARIMA(x ~ 0 + pdq(ar_lasso_coef, 0, 5-ar_lasso_coef) + PDQ(0,0,0)))
= ma_model |>
ma_lags residuals() |>
as_tibble() |>
select(.resid)
= lapply(1:(5-ar_lasso_coef),
ma_lags function(i){
lead(ma_lags, i)
|>
}) bind_cols() |>
mutate(
across(everything(),
~ case_when(is.na(.) ~ 0,
TRUE ~ .)
)
)
= glmnet::glmnet(y = tsbl_data[, 1] |> as.matrix(),
lasso_model x = ma_lags |> as.matrix(),
alpha = 1, intercept = F)
= lasso_model |>
ma_lasso_coef coef(s = 0.1)|>
as.vector()
= which(ma_lasso_coef == 0)[2] - 2
ma_lasso_coef
= tsbl_data |>
ret model(ma_init_model = ARIMA(x ~ 0 + pdq(ar_lasso_coef, 0, ma_lasso_coef) + PDQ(0,0,0)))
return(ret)
}
3.1 Modelo ARMA(1,0) com alta autocorrelação
library(fpp3)
set.seed(4390)
= replicate(100, arima.sim(n = 100, model = list(ar = 0.8))) arima_model_sim
- Stepwise
= arima_model_sim |>
stepwise_arima100 apply(2, function(i){
|>
i as_tibble() |>
mutate(index = lubridate::dseconds(1:100)) |>
as_tsibble(index = index) |>
model(ar = ARIMA(value))
})
=
step_acertos |>
stepwise_arima100 lapply(function(model){
= model |>
coef tidy() |>
pull(term) |>
unique() |>
paste0(collapse = "")
= ifelse(coef == 'ar1', 1, 0)
ret return(ret)
|>
}) unlist()
sum(step_acertos)/100
[1] 0.26
Via LASSO (default Lambda tunning)
::registerDoParallel()
doParallel
= arima_model_sim[,1:50]|>
lasso_arima100 apply(2, function(i){
|>
i as_tibble() |>
mutate(index = lubridate::dseconds(1:100)) |>
as_tsibble(index = index) |>
rename(x = value) |>
arima_lasso(4)
})
=
lasso_acertos |>
lasso_arima100 lapply(function(model){
= model |>
coef tidy() |>
pull(term) |>
unique() |>
paste0(collapse = "")
= ifelse(coef == 'ar1', 1, 0)
ret return(ret)
|>
}) unlist()
sum(lasso_acertos)/100
[1] 0.66
3.2 Modelo ARMA(1,0) com baixa autocorrelação
= replicate(100, arima.sim(n = 100, model = list(ar = 0.2))) arima_model_sim
- Stepwise
= arima_model_sim |>
stepwise_arima100 apply(2, function(i){
|>
i as_tibble() |>
mutate(index = lubridate::dseconds(1:100)) |>
as_tsibble(index = index) |>
model(ar = ARIMA(value))
})
=
step_acertos |>
stepwise_arima100 lapply(function(model){
= model |>
coef tidy() |>
pull(term) |>
unique() |>
paste0(collapse = "")
= ifelse(coef == 'ar1', 1, 0)
ret return(ret)
|>
}) unlist()
sum(step_acertos)/100
[1] 0.26
Via LASSO (default Lambda tunning)
::registerDoParallel()
doParallel
= arima_model_sim[,1:50]|>
lasso_arima100 apply(2, function(i){
|>
i as_tibble() |>
mutate(index = lubridate::dseconds(1:100)) |>
as_tsibble(index = index) |>
rename(x = value) |>
arima_lasso(4)
})
=
lasso_acertos |>
lasso_arima100 lapply(function(model){
= model |>
coef tidy() |>
pull(term) |>
unique() |>
paste0(collapse = "")
= ifelse(coef == 'ar1', 1, 0)
ret return(ret)
|>
}) unlist()
sum(lasso_acertos)/100
[1] 0.68
3.3 Modelo ARMA(2,2)
= replicate(100,
arima_model_sim arima.sim(n = 100,
model = list(ar = c(0.6, 0.3),
ma = c(0.3, 0.4)
)
) )
= arima_model_sim |>
stepwise_arima202 apply(2, function(i){
|>
i as_tibble() |>
mutate(index = lubridate::dseconds(1:100)) |>
as_tsibble(index = index) |>
model(ar = ARIMA(value))
})
=
step_acertos |>
stepwise_arima202 lapply(function(model){
= model |>
coef tidy() |>
pull(term) |>
unique() |>
paste0(collapse = "")
= ifelse(coef == 'ar1ar2ma1ma2', 1, 0)
ret return(ret)
|>
}) unlist()
sum(step_acertos)/100
[1] 0.11
::registerDoParallel()
doParallel
= arima_model_sim[,1:50]|>
lasso_arima202 apply(2, function(i){
|>
i as_tibble() |>
mutate(index = lubridate::dseconds(1:100)) |>
as_tsibble(index = index) |>
rename(x = value) |>
arima_lasso(4)
})
=
lasso_acertos |>
lasso_arima202 lapply(function(model){
= model |>
coef tidy() |>
pull(term) |>
unique() |>
paste0(collapse = "")
= ifelse(coef == 'ar1ar2ma1ma2', 1, 0)
ret return(ret)
|>
}) unlist()
sum(lasso_acertos)/50
[1] 0.32
3.4 Hyperparâmetro - Tuning
library(tidymodels)
# glmnet::glmnet(y = tbl_ar_lags[,1] |> as.matrix(),
# x = tbl_ar_lags[,2:6] |> as.matrix(),
# alpha = 1, intercept = F,
# lambda =
# grid_regular(penalty(range = c(0,10)),
# levels = 100) |>
# as.vector()
# )
=function(fit, k){
BICAICglm#tLL = fit$null.deviance - deviance(fit)
= -deviance(fit) # 2*log-likelihood
tLL = nobs(fit)
n = -tLL+2*k+2*k*(k+1)/(n-k-1)
AICc = -tLL+2*k
AIC_
=log(n)*k - tLL
BIC=c(AIC_, BIC, AICc)
resnames(res)=c("AIC", "BIC", "AICc")
return(res)
}
= function(tsbl_data,
lambda_tuning lags_number = 5,
lambda_range = c(0,10) ,
lambda_n_size = 100){
= tsbl_data |>
tbl_ar_lags ::as_tibble() |>
tibble::select(x) |>
dplyr::mutate(lag1 = dplyr::lead(x),
dplyrlag2 = dplyr::lead(x, 2),
lag3 = dplyr::lead(x, 3),
lag4 = dplyr::lead(x, 4),
lag5 = dplyr::lead(x, 5)) |>
::mutate(
dplyracross(c(1:6),
~dplyr::case_when(is.na(.) ~ 0, .default = .)
)
)
=
lambda_grid grid_regular(penalty(range = lambda_range),
levels = lambda_n_size)
=
IC_lasso_list lapply(1:nrow(lambda_grid),
function(i){
= glmnet::glmnet(y = tbl_ar_lags[,1] |> as.matrix(),
loop_model x = tbl_ar_lags[,2:6] |> as.matrix(),
alpha = 1,
intercept = F,
lambda = lambda_grid$penalty[i])
= loop_model |>
loop_IC BICAICglm(k = loop_model |>
coef(s = 0.1) |>
dim(x)[1] - 1}())
{\(x) return(loop_IC)
})
return(IC_lasso_list)
}
4 AdaLASSO e WLAdaLASSO
O surgimento de ambos os métodos se originam de uma condição de métodos de estimação e seleção de variáveis, chamado de Propriedade de Oráculo(Oracle Properties). Tal característica se baseia em 2 pontos principais
- Consistência na estimação e seleção de variáveis
- Normalidade Assintótica
Apesar de ser um método poderoso para seleção de variáveis, a LASSO não possui as propriedades de oráculo.
Buscando contornar tal problema, Zou (2006) propõe uma nova metodologia chamada Adaptive LASSO (AdaLASSO), a fim de evitar deficiências do LASSO, resultando em um método que aproveita as propriedades de oráculo.
O adaLASSO é uma versão ponderada do LASSO que atribui pesos diferentes para diferentes coeficientes no termo de penalidade LASSO. A penalidade é dada por
\[p(.) = \lambda\sum^q_{j=1}\omega_j|b_j|,\] onde \(\omega_j = |\beta_j^*|^{-t}\) e \(\beta_j^*|^{-\tau}\) é o chute inicial da estimação e \(\tau\) é outro hiperparâmetro que deve ser tunado
O estimador completo é dado por
\[\hat\beta_{AdaLASSO} = argmin[RSS(b_o, ..., b_q)+p(.)]\]
No contexto de séries temporais, algumas modificações devem ser realizadas na AdaLASSO. Konzen and Ziegelmann (2016) propõem um método para séries, onde os lags, que entram como variáveis explicativas para o método, possuem pesos menores para valores altos. Ou seja, lags mais altos possuem estimações que se aproximam de 0 enquanto lags menores possuem pesos que buscam minimzar estimação igual a 0
Tal método é chamado de Weighted Lag Adaptative LASSO(WLAdaLASSO). O termo de penalidade é dado por
\[p(.) = \lambda\sum^q_{j=1}\omega_j^*|b_j|\] O estimador completo é dado por
\[\hat\beta_{WLAdaLASSO} = argmin[RSS(b_o, ..., b_q)+p(.)],\] onde \(\omega_j^* = (|\hat\beta_j^*|e^{-\alpha l_j})^{-\tau}\). \(\alpha\) é outro hiperparâmetro que deve ser tunado, onde os autores sugerem a utilização do BIC para isso.
5 Qualidadade do Ar - Santos
Para análise de dados reais, dados da CETESB foram coletados via plataforma QUALAR, onde buscou-se modelar a taxa de partículas não inálaveis (MP-10) da cidade de Santos entre os anos de 2014 a 2024
A CETESB disponibiliza dois pontos de coleta na cidade, unidade centro e unidade ponta da praia. A unidade ponta da praia foi utilizada, pois esta capta com mais precisão níveis elevados de MP-10 resultantes do porto
Os dados são disponibilizados por hora, mas foram agrupados por dia para facilitar a análise
5.1 Análise Exploratória
= readr::read_csv2('./mp10_santos.csv', locale = locale(encoding = "latin1")) |>
tbl_mp10 ::remove_empty(which = c('rows')) |>
janitor::clean_names() |>
janitorrename(media_hora = 3) |>
filter(is.na(hora) == F) |>
filter(is.na(media_hora) == F)
= tbl_mp10 |>
tsbl_mp10 mutate(data = lubridate::dmy(data),
media_hora = media_hora |> as.numeric()) |>
group_by(data) |>
::summarise(media_hora = mean(media_hora, na.rm = T)) |>
dplyr::filter(is.na(data) == F) |>
dplyras_tsibble(index = data)
|>
tsbl_mp10 fill_gaps() |>
as_tibble() |>
mutate(year = lubridate::year(data)) |>
group_by(year) |>
summarise(data = data,
scl_media_hora = scale(media_hora)) |>
as_tsibble(index = data) |>
gg_season(scl_media_hora, labels = "both") +
theme_minimal()
|>
tsbl_mp10 fill_gaps() |>
as_tibble() |>
mutate(year = lubridate::year(data)) |>
group_by(year) |>
summarise(data = data,
scl_media_hora = scale(media_hora)) |>
as_tsibble(index = data) |>
gg_season(scl_media_hora, period = "week") +
theme_minimal()
|>
tsbl_mp10 fill_gaps() |>
as_tibble() |>
mutate(year = lubridate::year(data)) |>
group_by(year) |>
summarise(data = data,
scl_media_hora = scale(media_hora)) |>
as_tsibble(index = data) |>
gg_season(scl_media_hora, period = "year") +
theme_minimal()
Entender os dados é uam tarefa complexa por conta do número de anos analisados com indice de atualização diária
= tsbl_mp10 |>
tsbl_mp10_semana fill_gaps() |>
as_tibble() |>
mutate(semana_ano = tsibble::yearweek(data)) |>
group_by(semana_ano) |>
summarise(media_semana = mean(media_hora, na.rm = T)) |>
as_tsibble(index = semana_ano)
|>
tsbl_mp10 as_tibble() |>
mutate(mes_ano = tsibble::yearmonth(data)) |>
group_by(mes_ano) |>
summarise(media_ano = mean(media_hora, na.rm = T)) |>
as_tsibble(index = mes_ano) |>
fill_gaps() |>
gg_subseries()
= tsbl_mp10_semana |>
tsbl_mp10_2022 fill_gaps() |>
::fill(media_semana) |>
tidyrfilter(semana_ano>lubridate::ymd('2022-01-01'))
5.2 Modelagem
|>
tsbl_mp10_2022 pull(media_semana) |>
::adf.test(k = 12) tseries
Augmented Dickey-Fuller Test
data: pull(tsbl_mp10_2022, media_semana)
Dickey-Fuller = -2.6745, Lag order = 12, p-value = 0.2961
alternative hypothesis: stationary
|>
tsbl_mp10_2022 pull(media_semana) |>
::kpss.test() tseries
KPSS Test for Level Stationarity
data: pull(tsbl_mp10_2022, media_semana)
KPSS Level = 0.31067, Truncation lag parameter = 4, p-value = 0.1
|>
tsbl_mp10_2022 mutate(media_semana = difference(media_semana)) |>
filter(is.na(media_semana) == F) |>
pull(media_semana) |>
::adf.test() tseries
Augmented Dickey-Fuller Test
data: pull(filter(mutate(tsbl_mp10_2022, media_semana = difference(media_semana)), is.na(media_semana) == F), media_semana)
Dickey-Fuller = -6.467, Lag order = 5, p-value = 0.01
alternative hypothesis: stationary
= function(tsbl_data, init_lags, ma_init = 5, constant = 0){
arima_lasso
= tsbl_data |>
ar_lags ::as_tibble() |>
tibble::select(x)
dplyr
= lapply(1:init_lags,
ar_lags function(i){
lead(ar_lags, i)
|>
}) bind_cols() |>
mutate(
across(everything(),
~ case_when(is.na(.) ~ 0,
TRUE ~ .)
)
)
= glmnet::glmnet(y = tsbl_data[, 1] |> as.matrix(),
lasso_model x = ar_lags |> as.matrix(),
alpha = 1, intercept = F)
= lasso_model |>
ar_lasso_coef coef(s = 0.1) |>
as.vector()
|> print()
ar_lasso_coef
= which(ar_lasso_coef == 0)[2] - 2
ar_lasso_coef
|> print()
ar_lasso_coef = tsbl_data |>
ma_model model(ma_init_model =
ARIMA(x ~ 1 +
pdq(ar_lasso_coef, 0, ma_init-ar_lasso_coef) +
PDQ(0,0,0)
)
)
|> print()
ma_model
= ma_model |>
ma_lags residuals() |>
as_tibble() |>
select(.resid)
= lapply(1:(ma_init-ar_lasso_coef),
ma_lags function(i){
lead(ma_lags, i)
|>
}) bind_cols() |>
mutate(
across(everything(),
~ case_when(is.na(.) ~ 0,
TRUE ~ .)
)
)
= glmnet::glmnet(y = tsbl_data[, 1] |> as.matrix(),
lasso_model x = ma_lags |> as.matrix(),
alpha = 1, intercept = F)
= lasso_model |>
ma_lasso_coef coef(s = 0.1)|>
as.vector()
= which(ma_lasso_coef == 0)[2] - 2
ma_lasso_coef
= tsbl_data |>
ret model(lasso_arima_model = ARIMA(x ~ 1 + pdq(ar_lasso_coef, 0, ma_lasso_coef) + PDQ(0,0,0)))
return(ret)
}
= tsbl_mp10_2022 |>
tsbl_mp10_2022_diff mutate(media_semana = difference(media_semana)) |>
filter(is.na(media_semana) == F) |>
rename(x = media_semana) |>
relocate(x, .before = semana_ano)
= tsbl_mp10_2022_diff |>
arima_lasso_model arima_lasso(8, ma_init = 5, constant = 1)
[1] 0.00000000 -0.57385506 -0.21261682 -0.20405351 -0.16740936 -0.03367358
[7] 0.00000000 0.04865704 0.00000000
[1] 5
# A mable: 1 x 1
ma_init_model
<model>
1 <ARIMA(5,0,0) w/ mean>
= tsbl_mp10_2022_diff |>
arima_step_model model(ar = ARIMA(x ~ pdq(,0,)))
|> report() arima_lasso_model
Series: x
Model: ARIMA(5,0,0) w/ mean
Coefficients:
ar1 ar2 ar3 ar4 ar5 constant
-0.7133 -0.4095 -0.3993 -0.3251 -0.0919 0.4624
s.e. 0.0919 0.1119 0.1131 0.1120 0.0942 0.6090
sigma^2 estimated as 48.1: log likelihood=-423.5
AIC=860.99 AICc=861.94 BIC=880.9
|> report() arima_step_model
Series: x
Model: ARIMA(0,0,1)
Coefficients:
ma1
-0.6969
s.e. 0.0668
sigma^2 estimated as 48.13: log likelihood=-426.03
AIC=856.06 AICc=856.16 BIC=861.75
5.2.1 Poder de Previsão
= tsbl_mp10_2022_diff |>
tsbl_mp10_2022_diff_train filter(semana_ano<lubridate::ymd('2024-05-01'))
= tsbl_mp10_2022_diff |>
tsbl_mp10_2022_diff_test filter(semana_ano>=lubridate::ymd('2024-05-01'))
= tsbl_mp10_2022_diff_train |>
models_train model(arima_lasso = ARIMA(x ~ 1 + pdq(5,0,0) + PDQ(0,0,0)),
arima_step = ARIMA(x ~ 1 + pdq(0,0,1) + PDQ(0,0,0)))
|>
models_train forecast(h = 6) |>
::accuracy(tsbl_mp10_2022_diff_test) |>
fabletools::flextable() flextable
.model | .type | ME | RMSE | MAE | MPE | MAPE | MASE | RMSSE | ACF1 |
---|---|---|---|---|---|---|---|---|---|
arima_lasso | Test | 3.419905 | 13.77506 | 10.95363 | 105.1311 | 105.1311 | -0.1793111 | ||
arima_step | Test | 3.739521 | 13.76408 | 11.13139 | 109.5116 | 109.5116 | -0.1754061 |
6 Conclusão
“Yep, we are unlikely to build support for stepwise variable selection in tidymodels itself. If you are looking for variable selection, you might consider lasso regularization instead” - Julia Silge https://stackoverflow.com/questions/66651033/stepwise-algorithm-in-tidymodels
“Tidymodels does not currently support forward and backward stepwise selection methods, and it unlikely to include it in the near future.” https://emilhvitfeldt.github.io/ISLR-tidymodels-labs/
A resposta de uma das autoras do framework tidymodels sobre a adição de metódos stepwise para os modelos disponibilizados no pacote representam muito bem a visão geral da comunidade de ciência de dados e aprendizado de máquina em relação a utilização de métodos stepwise para seleção de variáveis no contexto de regressão. Tendo um baixo desempenho computacional, taxas inferiores de acertos em relação a outros métodos e podendo apresentar resultados ambíguos entre suas diferentes abordagens (backward e forward), o stepwise é uma possui uma idéia bacana de testar vários modelos na busca do melhor, porém em um área de estudo na qual o número de features disponibilizadas está cada vez maior, seus problemas se tornam cada vez mais evidentes. A abordagem stepwise pode ser inadequada, pois não escala bem com o aumento do número de variáveis, e a seleção de variáveis pode não ser tão robusta quanto outros métodos modernos, como técnicas de regularização (ridge, lasso) ou modelos baseados em árvore (random forest, gradient boosting). Por essas razões, a comunidade tem se voltado cada vez mais para métodos que possam lidar com grandes volumes de dados de forma eficiente e precisa.
Nesse contexto os métodos de Shrinkage, como a LASSO, vem se tornado cada vez mais populares, onde sua construção possibilita a estimação de coeficiente iguais a 0
A seleção de variáveis ainda é um assunto recente nos campos de séries temporais, onde o principal método utilizado ainda é o stepwise. Como visto durante o trabalho, a modernização dessa abordagem já demonstra o interesse de alguns autores, onde extensões da LASSO, como AdaLASSO e WLAdaLASSO são propostos
Para o estudo do método 2 etapas foram desenvolvidas: Simulação e Aplicação em dados Reais
Na parte da simulação, foi visto que o método LASSO acertou em maiores proporções o verdadeiro modelo em relação ao Stepwise, indenpendente da complexidade de modelo, onde diversos modelos ARIMA foram testados
Na parte de análise de dados reais, foi estudado o poluição por materiais não inaláveis (MP-10) na cidade de Santos durante os anos de 2014 a 2024. Uma análise exploratória foi realizada para primeiramente entender o comportamento dos dados. Via AED, vimos uma possível sazonalidade anual nos dados, e uma mudança de comportamento na tendência pós pandemia
Para a modelagem, os métodos Stepwise e LASSO foram utilizados, onde um modelo ARIMA\((0,1,1)\) foi selecionado via Stepwise e um modelo ARIMA\((5,1,0)\) foi selecionado via LASSO
Apesar o modelo via stepwise apresnetar valores de AIC E BIC melhores, quando estudado o poder de previsão de ambos, vimos que o modelo via LASSO apresentou melhores métricas de avaliação
Assim, o trabalho teve sucesso em demonstrar a superioridade da LASSO em relação ao Stepwise tanto para dados simulados tanto para dados reais, apresentando também um menor tempo de execução computacinal(tópico não mostrado no trabalho)
7 Referências
AHRENS, A.; AITKEN, C.; DITZEN, J.; ERSOY, E.; KOHNS, D.; SCHAFFER, M. E. A theory-based Lasso for time-series data. In: NGOC THACH, N.; KREINOVICH, V.; TRUNG, N. D. (Ed.). Data science for financial econometrics. Cham: Springer, 2021. (Studies in Computational Intelligence, v. 898). p. 3-36. Proceedings of the 3rd International Econometric Conference of Vietnam 2020, Ho Chi Minh City, Vietnam, 14 jan. 2020. Disponível em: https://doi.org/10.1007/978-3-030-48853-6_1.
KONZEN, Evandro. Penalizações tipo lasso na seleção de covariáveis em séries temporais. 2014. 110 f. Dissertação (Mestrado em Economia) – Universidade Federal do Rio Grande do Sul, Faculdade de Ciências Econômicas, Programa de Pós-Graduação em Economia, Porto Alegre, 2014. Disponível em: http://hdl.handle.net/10183/103896.
BOESCH, Klaus; ZIEGELMANN, Flavio A. Machine learning methods and time series: a thorough comparison study via simulation and U.S. inflation forecasting. Porto Alegre: Universidade Federal do Rio Grande do Sul, Departamento de Estatística, 26 jul. 2023. Disponível em: https://sbe.org.br/anais/45EBE/econometria/45_EBE_paper_82.pdf.