G4: Edinaldo de Alencar / Igor Freire / Ramon Araújo / Ricardo Ribeiro
11 de novembro de 2014
dataset_mensal
é a base com os valores de fluxo mensais de 1992 a 2009.
# Frequency --> número de observações por unidade de tempo
# define a unidade de tempo (e.g. 12: unidade de tempo = ano)
tsMensal <- ts(dataset_mensal, frequency=12, start=1992)
dataset_diario
é a base com valores de fluxos diários de 2002 a 2009.
tsDiario <- msts(dataset_diario, start=c(2002,1,1), seasonal.periods=c(7, 365.25))
Nota: é importante observar os anos bissextos, 2004 e 2008.
Observar a influência dos feriados (outliers). Exemplo, 12 de outubro foi uma quinta-feira em 2006.
Pode-se observar que as séries são:
acf(dataset_diario, col="red")
pacf(dataset_diario, col="red")
partial_autocorr <- pacf(dataset_diario, col="red", lag.max = 600, plot = FALSE)
which((abs(partial_autocorr$acf) > 0.08) == TRUE)
## [1] 1 3 4 5 6 7 8 13 14 15 20 21 22 29 35 36 49
## [18] 56 365 366
Realizar prospecções de curto, médio e longo prazo.
Para curto prazo, será utilizada a série temporal com dados diários (tsDiario
).
Para médio e longo prazo, será utilizada a série temporal com dados mensais (tsMensal
).
Separação das séries temporais em conjuntos de treinamento e de testes.
tsDiario
)tsDiarioTrain <- window(tsDiario, end=c(2008,183)) # até 30/06/2008
# De 01/07/2008 a 30/07/2008
tsDiarioTest30Days <- window(tsDiario, start=c(2008,184), end=c(2008,213))
# 45 dias a partir De 1/1/2008
tsDiarioTest45Days <- window(tsDiario, start=c(2008,184), end=c(2008,228))
tsMensal
)tsMensalTrain <- window(tsMensal, end=c(2007, 12)) # De Jan 1992 a Dez 2007
tsMensalTest4mth <- window(tsMensal, start=2008, end=c(2008, 4)) # De Jan 2006 a Mar 2006
tsMensalTest6mth <- window(tsMensal, start=2008, end=c(2008, 6)) # De Jan 2006 a Jun 2006
tsMensalTest1yr <- window(tsMensal, start=2008, end=c(2008, 12)) # De Jan 2006 a Jan 2007
tsMensalTest2yr <- window(tsMensal, start=2008, end=c(2009, 12)) # De Jan 2006 a Jan 2008
É possível observar um fator multiplicativo na componente sazonal. Por isso, a transformação Box-Cox será utilizada em alguns dos métodos apresentados na sequência.
plot(tsMensalTrain, xlab="Anos", ylab="Fluxo Mensal")
Calcula-se o fator \(\lambda\) para a transformação:
lam <- BoxCox.lambda(tsMensalTrain)
lam
## [1] -0.06928
Série Resultante:
tsMensalBoxCox <- BoxCox(x = tsMensalTrain, lam)
plot(tsMensalBoxCox, col="red")
ver (R. J. Hyndman 2014) e (Leek 2014):
library(forecast)
library(nnet)
ARIMA (Autoregressive Integrated Moving Average)
Método ARMA, acrescido da etapa de integração (I).
Caso a série temporal seja estacionária, o método se reduz ao ARMA.
\[y(t) = \sum_{i=1}^{p}\varphi_iy(t-i) + \sum_{j=1}^{q}\theta_j\epsilon(t-j)\]
\(ARIMA(p,d,q)\), onde:
p = número de valores passados da variável (AR)
d = número de diferenças não-sazonais (I)
q = número de erros de predição passados (MA)
auto.arima
no RA função auto.arima
ajusta o melhor modelo ARIMA à série temporal, com base no menor parâmetro AIC.
Protótipo com os principais parâmetros:
auto.arima(x, max.p=\(5\), max.d=\(2\), max.q=\(5\), stationary=\(FALSE\), seasonal=\(TRUE\), approximation=\(TRUE\), xreg=\(NULL\))
auto.arima
forneceu predições ruins.Aumentar o número de termos na equação de regressão do modelo ARIMA.
Adicionar ao modelo informações que possuem alta correlação com a série temporal em questão.
Regressor que pode assumir \(12\) categorias possíveis: janeiro, fevereiro, …, dezembro.
Base dataset_diario_1992-2009.csv
, com as datas diárias de Jan de 1992 a Dez de 2009.
# datas diárias do conjunto de treinamento, de Jan 1992 a Dez 2007
datasDiarioTrain_Mensal <- window(index(dataset_diario_full), end=5844)
# Série contendo as datas do conjunto de treinamento, de Jan 1992 a Dez 2007
datasMensalTrain <- dataset_mensal[1:192]
# Indica quais são os meses (janeiro, ..., dezembro) do conjunto de treinamento
meses <- getMonths( format(index(datasMensalTrain),"%m") )
# conta quantas segundas,...,domingos há em cada mês do conjunto de treinamento
diasSemanasMes_treino <- countWeekdaysPerMonth(datasDiarioTrain_Mensal)
arima_model_mensal <- auto.arima(tsMensalTrain, approximation=FALSE, lambda=BoxCox.lambda(tsMensalTrain), xreg=cbind(meses,diasSemanasMes_treino))
mesesAPrever <- 4
# Série contendo as datas do conjunto de testes, de Jan 2008 a Abr 2008
datasMensal4mth <- dataset_mensal[193:196]
# Indica quais são os meses (janeiro, ..., dezembro) do conjunto de testes
mesesFuturo4 <- getMonths( format(index(datasMensal4mth),"%m") )
# datas diárias do conjunto de teste (4 meses)
datasDiarioTeste4mth_Mensal <- window(index(dataset_diario), start=2192, end=2312)
# conta quantas segundas,...,domingos há em cada mês do conjunto de teste (4 meses)
diasSemanasMes_futuro_4mth <- countWeekdaysPerMonth(datasDiarioTeste4mth_Mensal)
Predição:
fcast_arima_4mth <- forecast(arima_model_mensal, xreg=cbind(mesesFuturo4,diasSemanasMes_futuro_4mth), h=mesesAPrever)
plot(fcast_arima_4mth, xlab="Anos", ylab="Fluxo Mensal", include=36)
lines(tsMensalTest4mth, col="red")
Acurácia:
accuracy(fcast_arima_4mth, tsMensalTest4mth)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set -15.24 8727 6389 -0.005435 1.256 0.1598 -0.0472 NA
## Test set -7837.87 9728 8071 -0.980798 1.012 0.2019 -0.5471 0.162
mesesAPrever <- 6
Predição:
datasMensal6mth <- window(index(dataset_mensal), start=193, end=198)
mesesFuturo6 <- getMonths( format(datasMensal6mth,"%m") )
# quantas segundas, tercas, ..., domingos há em cada mês do conjunto de teste (6 meses)
datasDiarioTeste6mth_Mensal <- window(index(dataset_diario), start=2192, end=2373)
# conta quantas segundas,...,domingos há em cada mês do conjunto de teste (6 meses)
diasSemanasMes_futuro_6mth <- countWeekdaysPerMonth(datasDiarioTeste6mth_Mensal)
Predição:
fcast_arima_6mth <- forecast(arima_model_mensal, xreg=cbind(mesesFuturo6,diasSemanasMes_futuro_6mth), h=mesesAPrever)
plot(fcast_arima_6mth, xlab="Anos", ylab="Fluxo Mensal", include=36)
lines(tsMensalTest6mth, col="red")
Acurácia:
accuracy(fcast_arima_6mth, tsMensalTest6mth)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set -15.24 8727 6389 -0.005435 1.2559 0.1598 -0.0472 NA
## Test set -7345.11 9042 7501 -0.908452 0.9291 0.1876 -0.5392 0.184
Ver (R. J. Hyndman and Athanasopoulos 2013). O autor possui um livro exclusivamente sobre o assunto em (R. Hyndman et al. 2008).
Para cada um dos 15 métodos, há dois modelos possíveis: com erro aditivo e com erro multiplicativo.
ets(ts)
sem argumentos além da série temporal ts
determina automaticamente o método apropriado.ets
apresenta o modelo escolhido e o AIC resultante.ets
não trabalha com séries de sazonalidade superior a 24 unidades temporais. Portanto, será utilizada somente para prospecções realizadas com dados mensais (sazonalidade = 12).ets
parametrizado automaticamente deve fornecer resultados muito precisos para prospecções de poucos pontos (por exemplo, 4 pontos).mesesAPrever <- 6
Modelo:
etsMensal <- ets(tsMensalTrain)
Prospecção:
fcastMensal6mth <- forecast(etsMensal, h=mesesAPrever)
Comparar predição com valores reais do conjunto de teste:
plot(fcastMensal6mth, xlab="Anos", ylab="Fluxo Mensal", include = 36);
lines(tsMensalTest6mth, col="red")
legend("topleft",legend=c("Real"),col=2,lty=1)
Acurácia:
accuracy(fcastMensal6mth, tsMensalTest6mth)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set 856.7 9849 7308 0.13394 1.442 0.1828 -0.02704 NA
## Test set -755.7 10937 8653 -0.06425 1.104 0.2164 -0.63165 0.2848
Prospecção com decomposição sazonal de Loess (STL)
Rede Neural
mesesAPrever <- 24
Dados com sazonalidade removida:
tsMensal.stl <- stl(tsMensalTrain[,1], s.window=12)
# Seasonally adjusted data constructed by removing the seasonal component.
plot(seasadj(tsMensal.stl))
stlf_model <- stlf(tsMensalTrain[,1], lambda = lam)
stlf_fcast <- forecast(stlf_model, h=mesesAPrever)
plot(stlf_fcast, xlab="Anos", ylab="Fluxo Mensal")
lines(tsMensalTest2yr, col="red")
Acurácia:
accuracy(stlf_fcast, tsMensalTest1yr)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set -25.42 8186 6175 -0.01584 1.238 0.1544 -0.02348 NA
## Test set 8132.24 17138 13696 0.92760 1.619 0.3425 -0.11417 0.4831
require(quantmod)
require(nnet)
partial_autocorr <- pacf(dataset_diario, col="red", lag.max = 600, plot = FALSE)
which((abs(partial_autocorr$acf) > 0.1) == TRUE)
## [1] 1 3 4 5 6 7 8 13 14 15 21 22 29 35 36 366
dat <- data.frame( y=dataset,
Lag(dataset,1),
Lag(dataset,3),
Lag(dataset,4),
Lag(dataset,7),
Lag(dataset,14),
Lag(dataset,15),
Lag(dataset,35),
Lag(dataset,364),
month=as.numeric(format(index(dataset), "%m")),
year=(as.numeric(format(index(dataset), "%y")) - 1),
holiday=isHoliday(dataset))
model <- nnet(y ~ ., data = datTrain, repeats=50, size=10, decay=0.127, linout=TRUE, trace=FALSE,
maxit=10000)
model
## a 11-10-1 network with 131 weights
## inputs: Lag.1 Lag.3 Lag.4 Lag.7 Lag.14 Lag.15 Lag.35 Lag.364 month year holidayTRUE
## output(s): y
## options were - linear output units decay=0.127
mape(datTest$y[1:nPredict], fcast)*100
## [1] 0.963
mape(datTest$y[1:nPredict], fcast)*100
## [1] 1.786
Técnica recente, publicada em 2011 (De Livera, Hyndman, and Snyder 2011).
A sigla TBATS é composta das iniciais das técnicas utilizadas: Trigonométrica, transformação Box-cox, correção de erro pela técnica ARMA, e componentes Trend e Sazonal.
Desenvolvido para séries temporais com características especiais de sazonalidade.
tbats_model <- tbats(tsDiarioTrain,
use.box.cox = TRUE,
use.trend = TRUE,
use.damped.trend = FALSE,
seasonal.periods = c(7, 365.25),
use.arma.errors = TRUE)
O método TBATS é indicado para a previsão do fluxo diário, pois:
Sazonalidades múltiplas: semanal e anual
Sazonalidade semanal é de alta frequência
diasAPrever <- 30
Predição:
tbats_fc30Days <- forecast(tbats_model, h=diasAPrever)
Acurácia:
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set 7.641 750.8 426.2 -0.07899 2.041 0.2136 -0.01679 NA
## Test set -198.853 502.6 358.1 -0.75395 1.311 0.1795 0.71247 0.258
diasAPrever <- 45
Predição:
tbats_fc45Days <- forecast(tbats_model, h=diasAPrever)
Acurácia:
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set 7.641 750.8 426.2 -0.07899 2.041 0.2136 -0.01679 NA
## Test set -99.500 499.1 371.6 -0.41877 1.331 0.1862 0.69601 0.2385
## Training.set Test..30d. Test..45d.
## Mean 14.656 22.506 23.334
## Näive 6.214 4.674 5.004
## N-Sazonal 8.720 9.066 9.304
## Drift 6.216 4.788 4.993
## Regressao 5.868 7.383 7.777
## ARIMA 5.330 5.415 6.111
## TBATS 2.036 1.339 1.327
## Training.set Test..4mths. Test..6mths. Test..1yr. Test..2yr.
## Mean 25.582 35.295 36.430 39.867 41.232
## Näive 4.440 5.639 3.982 5.708 6.801
## N-Sazonal 7.680 6.051 5.902 6.898 9.046
## Drift 4.470 6.542 5.016 4.722 5.210
## Regressao 4.741 6.894 7.387 10.023 10.398
## ETS 1.442 1.447 1.104 2.603 2.964
## Arima 1.625 1.933 1.539 1.841 2.390
De Livera, Alysha M, Rob J Hyndman, and Ralph D Snyder. 2011. “Forecasting Time Series with Complex Seasonal Patterns Using Exponential Smoothing.” Journal of the American Statistical Association 106 (496): 1513–1527.
Hyndman, Rob J. 2014. “Forecasting Time Series Using R.” http://robjhyndman.com/talks/MelbourneRUG.pdf.
Hyndman, Rob J, and George Athanasopoulos. 2013. Forecasting: principles and Practice. OTexts.
Hyndman, Rob, Anne B. Koehler, J. Keith Ord, and Ralph D. Snyder. 2008. Forecasting with Exponential Smoothing: The State Space Approach (Springer Series in Statistics). 2008th ed. Springer. http://amazon.com/o/ASIN/3540719164/.
Leek, Jeffrey. 2014. “Practical Machine Learning - Lecture 27 - Forecasting.” Johns Hopkins Bloomberg School of Public Health. https://d396qusza40orc.cloudfront.net/predmachlearn/027forecasting.pdf.