Auto.arima com dados diários: como capturar sazonalidade / periodicidade?

21

Estou ajustando um modelo ARIMA em uma série temporal diária. Os dados são coletados diariamente de 02-01-2010 a 30-07-2011 e são sobre vendas de jornais. Como um padrão semanal de vendas pode ser encontrado (a quantidade média diária de cópias vendidas é geralmente a mesma de segunda a sexta-feira e depois aumenta no sábado e domingo), estou tentando capturar essa "sazonalidade". Dados os dados de vendas "dados", crio a série temporal da seguinte maneira:

salests<-ts(data,start=c(2010,1),frequency=365)

e então uso a função auto.arima (.) para selecionar o melhor modelo ARIMA via critério AIC. O resultado é sempre um modelo ARIMA não sazonal, mas se eu tentar algum modelo SARIMAs com a seguinte sintaxe como exemplo:

sarima1<-arima(salests, order = c(2,1,2), seasonal = list(order = c(1, 0, 1), period = 7))

Eu posso obter melhores resultados. Existe algo errado na especificação ts command / arima? O padrão semanal é muito forte, então eu não esperaria tantas dificuldades em capturá-lo. Qualquer ajuda seria muito útil. Obrigado, Giulia Deppieri

Atualizar:

Eu já mudei alguns argumentos. Mais precisamente, o procedimento seleciona o ARIMA (4,1,3) como o melhor modelo quando eu defino D=7, mas a AIC e os outros bons índices de ajuste e previsões também não melhoram. Eu acho que há alguns erros devido à confusão entre sazonalidade e periodicidade ..?!

Chamada Auto.arima usada e saída obtida:

modArima<-auto.arima(salests,D=7,max.P = 5, max.Q = 5)



 ARIMA(2,1,2) with drift         : 1e+20
 ARIMA(0,1,0) with drift         : 5265.543
 ARIMA(1,1,0) with drift         : 5182.772
 ARIMA(0,1,1) with drift         : 1e+20
 ARIMA(2,1,0) with drift         : 5137.279
 ARIMA(2,1,1) with drift         : 1e+20
 ARIMA(3,1,1) with drift         : 1e+20
 ARIMA(2,1,0)                    : 5135.382
 ARIMA(1,1,0)                    : 5180.817
 ARIMA(3,1,0)                    : 5117.714
 ARIMA(3,1,1)                    : 1e+20
 ARIMA(4,1,1)                    : 5045.236
 ARIMA(4,1,1) with drift         : 5040.53
 ARIMA(5,1,1) with drift         : 1e+20
 ARIMA(4,1,0) with drift         : 5112.614
 ARIMA(4,1,2) with drift         : 4953.417
 ARIMA(5,1,3) with drift         : 1e+20
 ARIMA(4,1,2)                    : 4960.516
 ARIMA(3,1,2) with drift         : 1e+20
 ARIMA(5,1,2) with drift         : 1e+20
 ARIMA(4,1,3) with drift         : 4868.669
 ARIMA(5,1,4) with drift         : 1e+20
 ARIMA(4,1,3)                    : 4870.92
 ARIMA(3,1,3) with drift         : 1e+20
 ARIMA(4,1,4) with drift         : 4874.095

 Best model: ARIMA(4,1,3) with drift        

Então, eu assumo que a função arima deve ser usada como:

bestOrder <- cbind(modArima$arma[1],modArima$arma[5],modArima$arma[2])
sarima1<-arima(salests, order = c(4,1,3))

sem parâmetros de componentes sazonais e especificações de período. Os dados e a análise exploratória mostram que o mesmo padrão semanal pode ser considerado aproximadamente para cada semana, com a única exceção de agosto de 2010 (quando é registrado um aumento consistente nas vendas). Infelizmente, não tenho nenhum conhecimento em modelagem de séries temporais; na verdade, estou tentando esta abordagem para encontrar uma solução alternativa para outros modelos paramétricos e não paramétricos que tentei ajustar para esses dados problemáticos. Eu também tenho muitas variáveis ​​numéricas dependentes, mas elas mostraram baixo poder ao explicar a variável de resposta: sem dúvida, a parte mais difícil de modelar é o componente de tempo. Além disso, a construção de variáveis ​​fictícias para representar meses e dias da semana acabou por não ser uma solução robusta.

Giulia
fonte

Respostas:

28

Se houver sazonalidade semanal, defina o período sazonal para 7.

salests <- ts(data,start=2010,frequency=7) 
modArima <- auto.arima(salests)

Observe que a seleção da diferenciação sazonal não era muito boa auto.arima()até muito recentemente. Se você estiver usando a v2.xx do forecastpacote, defina D=1na chamada auto.arima()para forçar a diferença sazonal. Se você estiver usando a v3.xx do forecastpacote, a seleção automática de Dfunciona muito melhor (usando um teste OCSB em vez de um teste CH).

Não tente comparar o AIC para modelos com diferentes níveis de diferenciação. Eles não são diretamente comparáveis. Você só pode comparar com segurança o AIC com modelos com as mesmas ordens de diferenciação.

Você não precisa reajustar o modelo após ligar auto.arima(). Ele retornará um objeto Arima, como se você tivesse chamado arima()com a ordem de modelo selecionada.

Rob Hyndman
fonte
obrigado por apontar meu erro estúpido. Vou retirar minha resposta.
Mkttas
1
Do que você tanto por suas sugestões muito úteis. Como estou usando a versão 2.19 do pacote de previsões, segui seus conselhos e defina o parâmetro D igual a 1 na chamada auto.arima (). Agora, o melhor modelo selecionado para a série salests é um ARIMA (1,0,0) com média diferente de zero. Devo esperar a especificação da parte de sazonalidade para o melhor modelo retornado, quero dizer valores de P, D, Q ou pelo menos para D?
Giulia
2
Desde que seus dados tenham uma frequência diferente de 1, os modelos ARIMA sazonais serão considerados. Se um modelo não-sazonal está sendo devolvido, então ou a sazonalidade é muito fraco ou os dados não estão em um TS objeto com frequência> 1.
Rob Hyndman
15

O problema ao ajustar o ARIMA sazonal aos dados diários é que o "componente sazonal" pode operar apenas nos finais de semana ou talvez apenas nos dias da semana, portanto, no geral, existe um "componente sazonal" não significativo. Agora, o que você precisa fazer é aumentar seu conjunto de dados com 6 manequins representando os dias da semana e, talvez, indicadores mensais para representar efeitos anuais. Agora considere incorporar eventos como feriados e inclua qualquer efeito de chumbo, desprezo ou atraso em torno dessas variáveis ​​conhecidas. Não pode haver valores incomuns (pulsos) ou mudanças de nível ou tendências da hora local nos dados. Além disso, os efeitos do dia da semana podem ter mudado ao longo do tempo, por exemplo, não houve efeito de sábado nas primeiras 20 semanas, mas um efeito de sábado nas últimas 50 semanas.

IrishStat
fonte
Nesse caso (IrishStat), isso não seria uma técnica de modelagem mista, em vez de ARIMA. Os atrasos não são levados a lugar algum no ARIMA, exceto no teste Box Jlung. Auto.arima (recente) corrige tudo, incluindo dimensionamento de dados, flutuações de sazonalidade (é por isso que encontro os melhores parâmetros p, d, q).
Wackyanil
É chamada de Função de transferência e reflete uma abordagem sinérgica, consulte autobox.com/pdfs/capable.pd, começando no slide 42. O Auto.arima pode funcionar em casos simples, mas não é geral o suficiente na minha opinião. Se você tiver um conjunto de dados em mente, faça uma nova pergunta e inclua-a.
IrishStat
@IrishStat, você quis dizer ARIMA com intervenção? dia da semana sendo variáveis ​​fictícias? e variáveis ​​fictícias semelhantes para feriados?
Entusiasta
Sim ..que seria a minha abordagem para dados diários
IrishStat
0

Para determinar a ordem da sazonalidade em meus ts (dados diários ao longo de 3 anos), usei esse código no Matlab:

s = 0; min = 1e + 07; n = comprimento (x); para i = 1: 400 diff = x (i + 1: n) -x (1: ni); s (i) = soma (abs (diff)); se (s (i)

Isso me dá 365, o que é lógico.

nkabouche
fonte
1
Bem vindo ao site. Não está claro para mim como isso responde à pergunta original e não está claro para mim o que o código que você postou faz apenas olhando para ela. Talvez você possa expandir um pouco a resposta?
einar
1
Como sua solução lida com efeitos fixos do dia da semana, efeitos fixos do dia do mês, efeitos da semana do mês, efeitos do dia do mês, efeitos de lead e lag dos feriados , segunda-feira após um feriado de sexta-feira, sexta-feira antes de um feriado de segunda-feira, efeitos mensais, efeitos semanais, alterações nos efeitos do dia fora da semana ao longo do tempo, pulsos, mudanças de nível / etapa?
IrishStat
o código Matlab s = 0; min = 1e + 07; n = length (x); para i = 1: 400 diff = x (i + 1: n) -x (1: ni); s (i) = soma (abs (diff)); if (s (i) <min) min = s (i); i end end
nkabouche