Se \(W_t\) representa a temperatura global observada no mês \(t\) (média mensal, em graus Celsius) e \(\mu\) denota uma temepratura média global constante, o arquivo \(\verb|TempGlobal.csv|\) encontrado no Aprender contém as séries históricas dos desvios \(X_t = Y_t - \mu\), registradas pela NASA (Agência Espacial Norte-Americana) e pela NOAA (Administração Atmosférica e Oceânica Nacional), desde 1980. Para a NASA, o período base para a estomativa da média \(\mu\) compreende o período de 1951 a 1980. Para a NOAA, o período base refere-se ao séc. XX.
Dados brutos antes do tratamento:
Após removermos a coluna de índices dos dados diretamente no Excel, temos:
# ----- leitura e carregamento
library(tibbletime)
library(dplyr)
library(ggplot2)
library(readr)
library(lubridate)
library(reshape2)
temp.loc <- "/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/TempGlobal_alt.csv"
temp <- read_csv(temp.loc)
# ----- data preparation
# eliminando os NA's
# e formatando Data para tibbletime
temp2 <- temp %>%
na.omit() %>%
dplyr::mutate(Date = lubridate::ymd(Date)) %>% # usando ymd do lubridate
as_tbl_time(index = Date)
# head(matter3)
temp2
Nosso interesse é obter o melhor modelo em termos técnicos, ou seja, obter um modelo ARIMA com o melhor desempenho de predição. Por isso, nossa estratégia não será a de testar a estacionariedade da série, mas sim ajustar modelos com a série sem diferenciar e com a série diferenciada e verificar seus resultados em termos do Mean Absolute Percentage Error (MAPE) na predição de um passo.
Inicialmente, procedemos a uma análise de ordem exploratória nos dados para termos uma ideia do comportamento da série.
Começamos pela plotagem das séries.
Gráficos das séries mensais:
# crinado as ts
X.NOAA_ts <- ts(temp2 %>% dplyr::select(X.NOAA), start = c(1880,1), end =c(2016,12), frequency = 12)
# o fato de ser todo dia 15 nessas series nao importa -- a frequencia indica que sao 12 medicoes ao ano
X.NASA_ts <- ts(temp2 %>% dplyr::select(X.NASA), start = c(1880,1), end = c(2016,12), frequency = 12)
library(forecast)
library(highcharter)
library(ggplot2)
plotly_palette <- c('#1F77B4', '#FF7F0E', '#2CA02C', '#D62728', "#9467bd", "#8c564b")
temp2_ts <- cbind(X.NOAA_ts, X.NASA_ts)
hchart(temp2_ts) %>%
hc_colors(plotly_palette[1:2]) %>%
hc_title(text = "Série Histórica Mensal dos Desvios de Temperatura (1880 - 2016)",
margin = 20, align = "center",
style = list(color = "black", useHTML = TRUE))
Faremos também o plot das séries anuais conforme segue.
Gráficos das séries anuais:
# ----- plots serie:
plotly_palette <- c('#1F77B4', '#FF7F0E', '#2CA02C', '#D62728')
# --- serie:
# highcharts:
temp_ano <- temp2 %>%
as_period("1 y") # haverah uma linha para cada ano
# crinado as ts
X.NOAA_ano_ts <- ts(temp_ano %>% dplyr::select(X.NOAA), start = 1880, end = 2016, frequency = 1)
X.NASA_ano_ts <- ts(temp_ano %>% dplyr::select(X.NASA), start = 1880, end = 2016, frequency = 1)
temp_ano_ts <- cbind(X.NOAA_ano_ts, X.NASA_ano_ts)
hchart(temp_ano_ts) %>%
hc_colors(plotly_palette[1:2]) %>%
hc_title(text = "Série Histórica Anual dos Desvios de Temperatura (1880 - 2016)",
margin = 20, align = "center",
style = list(color = "black", useHTML = TRUE))
Finalizando nossa análise exploratória, fazemos os plots da Função de Autocorrelação (FAC) e da Função de Autocorrelação Parcial (FACP).
Plots da FAC e FACP:
# funcoes para plotar ACF e PACF nos moldes do ggplot2
# adaptado de: https://stackoverflow.com/questions/42753017/adding-confidence-intervals-to-plotted-acf-in-ggplot2
gg_acf <- function(ts, title="FAC", lag=1, lag.max=50){
ts_acf <- acf(ts, lag = lag, lag.max = lag.max, na.action = na.pass, plot=FALSE)
conf_lims <- c(-1,1)*qnorm(0.975)/sqrt(ts_acf$n.used)
ts_acf$acf %>%
# tibble::as_tibble() %>% dplyr::mutate(lags = 0:(n()-1)) %>% # acf começa em zero e termina em n-1
tibble::as_tibble() %>% dplyr::mutate(lags = 0:(lag.max)) %>% # acf começa em zero e termina em lag.max
ggplot2::ggplot(aes(x=lags, y = V1)) + ggplot2::scale_x_continuous(breaks=seq(0,lag.max,lag.max/10)) +
ggplot2::geom_hline(yintercept=conf_lims, lty=2, col='red', size=0.3) +
ggplot2::labs(y="Autocorrelations", x="Lag", title=title) +
ggplot2::geom_segment(aes(xend=lags, yend=0)) + theme_minimal()
#+ ggplot2::geom_point()
}
gg_pacf <- function(ts, title="FACP", lag=1, lag.max=50){
# ts = temp[,c("Date", "X.NASA")]
ts_pacf <- pacf(ts, lag = lag, lag.max = lag.max, na.action = na.pass, plot=FALSE)
# corrigindo no zero:
ts_pacf$acf <- c("0"=1, ts_pacf$acf)
conf_lims <- c(-1,1)*qnorm(0.975)/sqrt(ts_pacf$n.used)
ts_pacf$acf %>% # tb eh acf o objeto dentro do output de pacf
# tibble::as_tibble() %>% dplyr::mutate(lags = 1:n()) %>% # pacf começa em 1 e termina em n
tibble::as_tibble() %>% magrittr::set_colnames(c("V1")) %>% # para funcionar apos a inclusao do zero
dplyr::mutate(lags = 0:(lag.max)) %>% # acf começa em zero e termina em lag.max
ggplot2::ggplot(aes(x=lags, y = V1)) + ggplot2::scale_x_continuous(breaks=seq(0,lag.max,lag.max/10)) +
ggplot2::geom_hline(yintercept=conf_lims, lty=2, col='red', size=0.3) +
ggplot2::labs(y="Partial Autocorrelations", x="Lag", title=title) +
ggplot2::geom_segment(aes(xend=lags, yend=0)) + theme_minimal()
#+ ggplot2::geom_point()
}
library(gridExtra)
grid.arrange(gg_acf(temp[,c("X.NOAA")], title = "FAC - NOAA", lag.max=12*5), gg_pacf(temp[,c("X.NOAA")], title = "FACP - NOAA", lag.max=12*5), ncol=2)
library(gridExtra)
grid.arrange(gg_acf(temp[,c("X.NASA")], title = "FAC - NASA", lag.max=12*5), gg_pacf(temp[,c("X.NASA")], title = "FACP - NASA", lag.max=12*5), ncol=2)
Fica claro que ambas as séries não aparentam ter estacionariedade, o que é reforçado por uma possível tendência nos gráficos mensais e anuais. Por outro lado, não há evidências de sazonalidade, indicando a adequabilidade de um modelo ARIMA não-sazonal para o caso. Como nosso objetivo é obter o modelo com base na abordagem empírica de performance na predição, deixaremos que eventuais restrições relacionadas a não estacionariedade reflitam nos resultados ao selecionarmos os melhores modelos. Utilizaremos o Mean Absolute Percentage Error (MAPE) de um passo a frente como critério de otimalidade, tomando como base os últimos 12 meses, para confeccionar um grid que nos apontará os modelos candidatos.
# -----------------------------------------------------------------------
# Identificao da ordem do processo
# com base no erro de previsao 1 passo a frente
# relativo as ultimas 12 observacoes
# -----------------------------------------------------------------------
X.0 <- temp[,c("X.NOAA"), drop=TRUE] # extrair somente os valores como vetor mesmo
N <- nrow(temp[,c("X.NOAA")])
X.0 <- temp[,c("X.NASA"), drop=TRUE]
N <- nrow(temp[,c("X.NASA")])
p.max = 7
q.max = 3
MAPE <- matrix(0, p.max+1, q.max+1)
for (p in 0:p.max){
for (q in 0:q.max){
previsto <- NULL
observado <- NULL
for (t in 0:11){
X <- X.0[1:(N-12+t)]
n <- length(X)
# fit <- arima(X, order=c(p, 1, q),xreg=1:n) #Certo
fit <- arima(X, order=c(p, 0, q),xreg=1:n) #Certo
prev <- predict(fit, n.ahead = 1, newxreg=(n+1))
obs <- X.0[N-12+t+1]
previsto[t+1] <- prev$pred
observado[t+1] <- obs
}
MAPE[(p+1),(q+1)] <- 100*(mean(abs((previsto-observado)/observado)))
}
}
MAPE_nodiff_NOAA <- MAPE
MAPE_nodiff_NASA <- MAPE
readr::write_tsv(as.data.frame(MAPE_nodiff_NOAA), path="/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/MAPE_nodiff_NOAA.txt")
readr::write_tsv(as.data.frame(MAPE_nodiff_NASA), path="/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/MAPE_nodiff_NASA.txt")
Temos os seguintes grids resultantes do algoritmo de otimização:
MAPE_nodiff_NOAA <- readr::read_tsv("/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/MAPE_nodiff_NOAA.txt") %>%
magrittr::set_colnames(paste0("q=", 0:3)) %>%
as.data.frame() %>%
round(., 4) %>%
`rownames<-`(paste0("p=", 0:7))
MAPE_nodiff_NASA <- readr::read_tsv("/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/MAPE_nodiff_NASA.txt") %>%
magrittr::set_colnames(paste0("q=", 0:3)) %>%
as.data.frame() %>%
round(.,4) %>%
`rownames<-`(paste0("p=", 0:7))
Para cada série analisada, elencamos os 3 melhores modelo, os quais são destacados nos respectivos grids.
library(kableExtra)
library(knitr)
MAPE_nodiff_NOAA %>%
dplyr::mutate(
`q=1` = cell_spec(`q=1`,
background = ifelse(`q=1` == 7.9136, plotly_palette[3],
ifelse(`q=1` < 8.03 & `q=1` != 7.9136, plotly_palette[1], "white")),
color = dplyr::if_else(`q=1` < 8.03, "white", "black")),
# `q=0` = cell_spec(`q=0`,
# background = ifelse(`q=0` < 8.03, plotly_palette[1], "white"),
# color = dplyr::if_else(`q=0` < 8.03, "white", "black")),
ordem = rownames(.),
ordem = cell_spec(ordem, color = "black")) %>%
dplyr::select(ordem, paste0("q=", 0:3)) %>%
kable(format="html", escape=F, digits = 4, caption="grid NOAA") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = F) #%>%
ordem | q=0 | q=1 | q=2 | q=3 |
---|---|---|---|---|
p=0 | 44.3026 | 26.5005 | 19.4825 | 15.9024 |
p=1 | 8.8955 | 8.3984 | 8.3997 | 8.4257 |
p=2 | 8.0871 | 8.4045 | 8.0565 | 8.0970 |
p=3 | 8.0230 | 8.4283 | 8.4320 | 8.2356 |
p=4 | 8.2474 | 7.9136 | 8.2910 | 8.2295 |
p=5 | 8.0991 | 8.0262 | 8.1548 | 8.5262 |
p=6 | 8.2188 | 8.0145 | 8.0457 | 8.1854 |
p=7 | 8.5408 | 8.1308 | 8.1822 | 8.2348 |
MAPE_nodiff_NASA %>%
dplyr::mutate(
`q=1` = cell_spec(`q=1`,
background = ifelse(`q=1` == 11.2289, plotly_palette[3],
ifelse(`q=1` < 11.3 & `q=1` != 11.2289, plotly_palette[1], "white")),
color = dplyr::if_else(`q=1` < 8.03, "white", "black")),
`q=2` = cell_spec(`q=2` ,
background = ifelse(`q=2` < 11.5, plotly_palette[2], "white"),
color = dplyr::if_else(`q=2` < 11.5, "white", "black")),
ordem = rownames(.),
ordem = cell_spec(ordem, color = "black"),
`q=0` = cell_spec(`q=0` ,
background = ifelse(`q=0` < 11.3, plotly_palette[2], "white"),
color = dplyr::if_else(`q=0` < 11.3, "white", "black")),
ordem = rownames(.),
ordem = cell_spec(ordem, color = "black")) %>%
dplyr::select(ordem, paste0("q=", 0:3)) %>%
kable(format="html", escape=F, digits = 4, caption="grid NASA") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = F) #%>%
ordem | q=0 | q=1 | q=2 | q=3 |
---|---|---|---|---|
p=0 | 47.3755 | 29.3741 | 21.3981 | 18.0524 |
p=1 | 11.2414 | 12.2492 | 12.3714 | 12.1266 |
p=2 | 11.8039 | 12.1782 | 12.13 | 11.6927 |
p=3 | 11.8599 | 11.5415 | 12.1346 | 11.6237 |
p=4 | 12.3878 | 11.2289 | 11.6482 | 11.7429 |
p=5 | 12.5041 | 12.0852 | 11.4171 | 11.5059 |
p=6 | 12.4723 | 11.9215 | 11.7652 | 11.4321 |
p=7 | 12.4225 | 11.781 | 11.9779 | 11.6692 |
Após selecionarmos os melhores modelos no caso da série não diferenciada, passamos para a confecção dos grids de desempenho para a série diferenciada.
Novamente, utilizaremos o Mean Absolute Percentage Error (MAPE) de um passo a frente como critério de otimalidade e tomando como base os últimos 12 meses para confeccionar um grid que nos apontará os modelos candidatos.
# -----------------------------------------------------------------------
# Identificao da ordem do processo
# com base no erro de previsao 1 passo a frente
# relativo as ultimas 12 observacoes
# -----------------------------------------------------------------------
X.0 <- temp[,c("X.NOAA"), drop=TRUE] # extrair somente os valores como vetor mesmo
N <- nrow(temp[,c("X.NOAA")])
X.0 <- temp[,c("X.NASA"), drop=TRUE]
N <- nrow(temp[,c("X.NASA")])
p.max = 7
q.max = 3
MAPE <- matrix(0, p.max+1, q.max+1)
for (p in 0:p.max){
for (q in 0:q.max){
previsto <- NULL
observado <- NULL
for (t in 0:11){
X <- X.0[1:(N-12+t)]
n <- length(X)
fit <- arima(X, order=c(p, 1, q),xreg=1:n) #Certo
# fit <- arima(X, order=c(p, 0, q),xreg=1:n) #Certo
prev <- predict(fit, n.ahead = 1, newxreg=(n+1))
obs <- X.0[N-12+t+1]
previsto[t+1] <- prev$pred
observado[t+1] <- obs
}
MAPE[(p+1),(q+1)] <- 100*(mean(abs((previsto-observado)/observado)))
}
}
MAPE_diff_NOAA <- MAPE
MAPE_diff_NASA <- MAPE
readr::write_tsv(as.data.frame(MAPE_diff_NOAA), path="/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/MAPE_diff_NOAA.txt")
readr::write_tsv(as.data.frame(MAPE_diff_NASA), path="/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/MAPE_diff_NASA.txt")
Temos os seguintes grids resultantes do algoritmo de otimização:
MAPE_diff_NOAA <- readr::read_tsv("/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/MAPE_diff_NOAA.txt") %>%
magrittr::set_colnames(paste0("q=", 0:3)) %>%
as.data.frame() %>%
round(., 4) %>%
`rownames<-`(paste0("p=", 0:7))
MAPE_diff_NASA <- readr::read_tsv("/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/MAPE_diff_NASA.txt") %>%
magrittr::set_colnames(paste0("q=", 0:3)) %>%
as.data.frame() %>%
round(.,4) %>%
`rownames<-`(paste0("p=", 0:7))
Para cada série analisada, elencamos os 3 melhores modelo, os quais são destacados nos respectivos grids.
library(kableExtra)
library(knitr)
MAPE_diff_NOAA %>%
dplyr::mutate(
`q=1` = cell_spec(`q=1`,
background = ifelse(`q=1` == 8.0038, plotly_palette[3],
ifelse(`q=1` < 8.07 & `q=1` != 7.9136, plotly_palette[1], "white")),
color = dplyr::if_else(`q=1` < 8.03, "white", "black")),
# `q=0` = cell_spec(`q=0`,
# background = ifelse(`q=0` < 8.03, plotly_palette[1], "white"),
# color = dplyr::if_else(`q=0` < 8.03, "white", "black")),
ordem = rownames(.),
ordem = cell_spec(ordem, color = "black")) %>%
dplyr::select(ordem, paste0("q=", 0:3)) %>%
kable(format="html", escape=F, digits = 4, caption="grid NOAA") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = F) #%>%
ordem | q=0 | q=1 | q=2 | q=3 |
---|---|---|---|---|
p=0 | 8.1550 | 9.7389 | 10.0644 | 10.1234 |
p=1 | 8.4431 | 10.1098 | 8.1507 | 8.1945 |
p=2 | 9.0048 | 8.0659 | 8.2027 | 8.1980 |
p=3 | 9.1085 | 8.0038 | 8.2143 | 8.1881 |
p=4 | 9.4822 | 8.0633 | 8.1947 | 8.2052 |
p=5 | 9.7837 | 8.0869 | 8.0813 | 8.1992 |
p=6 | 10.0689 | 8.1458 | 8.1721 | 8.2124 |
p=7 | 10.1352 | 8.2839 | 8.1169 | 8.1729 |
MAPE_diff_NASA %>%
dplyr::mutate(
`q=1` = cell_spec(`q=1`,
background = ifelse(`q=1` == 11.1388, plotly_palette[3],
ifelse(`q=1` < 11.3 & `q=1` != 11.2289, plotly_palette[2], "white")),
color = dplyr::if_else(`q=1` < 8.03, "white", "black")),
`q=2` = cell_spec(`q=2` ,
background = ifelse(`q=2` == 11.1388, plotly_palette[3], "white"),
color = dplyr::if_else(`q=2` < 11.3, "white", "black")),
ordem = rownames(.),
ordem = cell_spec(ordem, color = "black"),
`q=0` = cell_spec(`q=0` ,
background = ifelse(`q=0` < 11.3, plotly_palette[2], "white"),
color = dplyr::if_else(`q=0` < 11.3, "white", "black")),
ordem = rownames(.),
ordem = cell_spec(ordem, color = "black")) %>%
dplyr::select(ordem, paste0("q=", 0:3)) %>%
kable(format="html", escape=F, digits = 4, caption="grid NASA") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = F) #%>%
ordem | q=0 | q=1 | q=2 | q=3 |
---|---|---|---|---|
p=0 | 11.5822 | 13.6448 | 13.4456 | 13.2608 |
p=1 | 12.1087 | 12.9305 | 11.5798 | 11.7431 |
p=2 | 12.2334 | 11.2099 | 11.7838 | 11.5475 |
p=3 | 13.4908 | 11.197 | 11.1388 | 11.8399 |
p=4 | 13.5378 | 11.8974 | 11.9816 | 11.7654 |
p=5 | 13.575 | 11.9675 | 11.8125 | 11.9070 |
p=6 | 13.7499 | 11.9912 | 11.9909 | 12.0445 |
p=7 | 13.627 | 11.995 | 11.9424 | 12.0092 |
No caso da série NOAA os melhores modelos apareceram no caso sem diferenciar, ao passo que na série NASA, os melhores modelos estão na série com diferenciação de 1ª ordem. Portanto, utilizando como critério o desempenho medido pelo MAPE de um passo, no caso NOAA, o modelo escolhido é um ARIMA(4,0,1) (ou ARMA(4,1)). No caso da série NASA, o modelo escolhido é um ARIMA(3,1,2).
Plot valores preditos vs. observados nos modelos selecionados:
Abaixo apresentamos os plots comparando os valores observados e valores preditos para as últimas 12 observações para os modelos selecionados.
X.0 <- X.NOAA_ts
N <- length(X.0)
previsto <- NULL
observado <- NULL
for (t in 0:11){
X <- X.0[1:(N-12+t)]
n <- length(X)
fit <- arima(X, order=c(4, 0, 1),xreg=1:n)
prev <- predict(fit, n.ahead = 1, newxreg=(n+1))
obs <- X.0[N-12+t+1]
previsto[t+1] <- prev$pred
observado[t+1] <- obs
}
hchart(as.ts(observado), name="observado") %>%
hc_add_series(as.ts(previsto), name="previsto") %>%
hc_colors(plotly_palette[c(1,4)]) %>%
hc_title(text = "NOAA - Previsto vs Observado (últimas 12 obs) - Arima(4,0,1)",
margin = 20, align = "center",
style = list(color = "black", useHTML = TRUE))
X.0 <- X.NASA_ts
N <- length(X.0)
previsto <- NULL
observado <- NULL
for (t in 0:11){
X <- X.0[1:(N-12+t)]
n <- length(X)
fit <- arima(X, order=c(3, 1, 2),xreg=1:n)
prev <- predict(fit, n.ahead = 1, newxreg=(n+1))
obs <- X.0[N-12+t+1]
previsto[t+1] <- prev$pred
observado[t+1] <- obs
}
hchart(as.ts(observado), name="observado") %>%
hc_add_series(as.ts(previsto), name="previsto") %>%
hc_colors(plotly_palette[c(2,4)]) %>%
hc_title(text = "NASA - Previsto vs Observado (últimas 12 obs) - Arima(3,1,2)",
margin = 20, align = "center",
style = list(color = "black", useHTML = TRUE))
# ajuste
library(forecast)
# NOAAfit <- arima(X.NOAA_ts, order=c(3,0,1)) # erro ! non-stationary AR part from CSS
NOAAfit <- arima(X.NOAA_ts, order=c(4,0,1), method="ML") # mais lento, porem mais acurado
NASAfit <- arima(X.NASA_ts, order=c(3,1,2), method = "ML")
Valores Preditos NOAA:
library(forecast)
NOAAfcast <- forecast(NOAAfit, h=12)
as.data.frame(NOAAfcast, rownames = TRUE)
Valores Preditos NASA:
NASAfcast <- forecast(NASAfit, h=12)
as.data.frame(NASAfcast, rownames=TRUE)
Plots dos valores preditos:
# help(window)
plotly_palette <- c('#1F77B4', '#FF7F0E', '#2CA02C', '#D62728', "#9467bd", "#8c564b")
NOAAfcast_window <- NOAAfcast # para selecionar janelas de tempo em ts
NOAAfcast_window$x <- window(NOAAfcast$x, 2008, 2017)
hchart(NOAAfcast_window, name="NOAA", type="line") %>%
hc_colors(plotly_palette[c(1,5,4,3,6)]) %>%
hc_title(text = "NOAA - Série Histórica Mensal dos Desvios de Temperatura - Previsão 12 Meses (zoom Jan 2008 - Dez 2017)",
margin = 20, align = "center",
style = list(color = "black", useHTML = TRUE))
# plot(NOAAfcast_window)
NASAfcast_window <- NASAfcast # para selecionar janelas de tempo
NASAfcast_window$x <- window(NASAfcast$x, 2008, 2017)
hchart(NASAfcast_window, name="NASA", type="line") %>%
hc_colors(plotly_palette[c(2,5,4,3,6)]) %>%
hc_title(text = "NASA - Série Histórica Mensal dos Desvios de Temperatura - Previsão 12 Meses (zoom Jan 2008 - Dez 2017)",
margin = 20, align = "center",
style = list(color = "black", useHTML = TRUE))
# plot(NASAfcast_window)
O arquivo \(\verb|Echo.csv|\) contém a série histórica dos volumes mensais evaporados (em acre-pé) no reservatório Echo, desde 1967, localizado na região do Colorado, nos Estados Unidos.
Dados:
Após removermos a coluna de índices dos dados diretamente no Excel, temos:
# ----- leitura e carregamento
library(tibbletime)
library(dplyr)
library(ggplot2)
library(readr)
library(lubridate)
library(reshape2)
library(highcharter)
echo.loc <- "/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/Echo_alt.csv"
echo <- read_csv(echo.loc)
# ----- data preparation
# eliminando os NA's
# e formatando Data para tibbletime
echo2 <- echo %>%
na.omit() %>%
dplyr::mutate(Date = lubridate::dmy(Date)) %>% # usando dmy do lubridate
as_tbl_time(index = Date)
echo2
Começamos pela plotagem das séries, a fim de proceder a uma análise exploratória.
Gráficos das séries mensais:
# crinado as ts
echo_ts <- ts(echo2 %>% dplyr::select(X), start = c(1967,1), end =c(2018,1), frequency = 12)
library(forecast)
library(highcharter)
library(ggplot2)
plotly_palette <- c('#1F77B4', '#FF7F0E', '#2CA02C', '#D62728', "#9467bd", "#8c564b")
hchart(echo_ts) %>%
hc_colors(plotly_palette[5]) %>%
hc_title(text = "Série Histórica Mensal de Evaporação - Reservatório Echo (1967 - 2018)",
margin = 20, align = "center",
style = list(color = "black", useHTML = TRUE))
Gráfico da série semestral:
# ----- plots serie:
# --- serie:
# ggplot:
p1_smst <- echo2 %>%
as_period("6 months") %>% # haverah uma linha para cada ano
ggplot() +
geom_line(aes(x = Date, y = X), size=0.3, alpha = 0.5, colour=plotly_palette[5]) +
labs(x="Data", y="Valores")+
ggtitle("Série Histórica Semestral\nReservatório Echo (1967 - 2018)")+
theme_bw()+
theme(panel.border = element_blank())+ # para ficar igual o plotly
guides(color=guide_legend(title=NULL))+
# scale_color_manual(values=plotly_palette[4])+
theme(plot.title = element_text(hjust=0.5))
plotly::ggplotly(p1_smst) %>%
plotly::layout(legend = list(orientation = "h", x = 0.37, y =-0.1))
Gráfico da série anual:
# ----- plots serie:
# --- serie:
# ggplot:
p1_ano <- echo2 %>%
as_period("1 year") %>% # haverah uma linha para cada ano
ggplot() +
geom_line(aes(x = Date, y = X), size=0.3, alpha = 0.5, colour=plotly_palette[5]) +
labs(x="Data", y="Valores")+
ggtitle("Série Histórica Anual\nReservatório Echo (1967 - 2018)")+
theme_bw()+
theme(panel.border = element_blank())+ # para ficar igual o plotly
guides(color=guide_legend(title=NULL))+
# scale_color_manual(values=plotly_palette[4])+
theme(plot.title = element_text(hjust=0.5))
plotly::ggplotly(p1_ano) %>%
plotly::layout(legend = list(orientation = "h", x = 0.37, y =-0.1))
Como não conhecemos muito bem a série, optamos por fazer um gráfico das médias mensais. Isso ajudará a confirmarmos um eventual comportamento sazonal.
Plot das médias mensais:
# ----- plots serie:
# --- serie:
# ggplot:
p1_medias <- echo2 %>%
dplyr::mutate(month = format(Date, "%m"), year = format(Date, "%Y")) %>%
group_by(month) %>%
dplyr::summarise(medias = mean(X)) %>%
ggplot() +
geom_line(aes(x = month, y = medias, group=1), size=0.7, alpha = 0.5, colour=plotly_palette[5]) +
labs(x="Data", y="Valores")+
ggtitle("Médias Mensais\nReservatório Echo (1967 - 2018)")+
theme_bw()+
theme(panel.border = element_blank())+ # para ficar igual o plotly
guides(color=guide_legend(title=NULL))+
# scale_color_manual(values=plotly_palette[4])+
theme(plot.title = element_text(hjust=0.5))
plotly::ggplotly(p1_medias) %>%
plotly::layout(legend = list(orientation = "h", x = 0.37, y =-0.1))
Nos gráficos mensal, semestral e anual já é possível notar a presença de sazonalidade. Dirimindo quaisquer dúvidas sobre esta última constatação, o gráfico das médias mensais mostra que há diferenças entre os meses e, portanto, sazonalidade na série. Neste último gráfico, assim como no mensal e no semestral, verifica-se que a evaporação sobe no primeiro semestre de cada ano, atingindo o pico no mês de julho (período mais quente no hemisfério norte) para em seguida declinar, atingindo o menor valor para o ano no mês de dezembro (período mais frio).
O gráfico anual serve apenas para uma análise mais completa e de modo que pudéssemos eventualmente verificar possíveis ciclos entre os anos. Com exceção do pico no ano de 1986 (que provavelmente não é uma quebra estrutural), a série, em termos anuais, parece ser bem comportada.
A série não parece indicar a presença de qualquer tendência. Para confirmar novamente a existência de sazonalidade e eliminar quaisquer dúvidas acerca de uma eventual tendência, utilizamos os plots da FAC e FACP diferenciada de lag S=12. Este valor deve-se ao fato de que, por termos uma série mensal - que apresentou comportamento sazonal dentro do ano (diferenças entre os meses), espera-se que os valores de evaporação do mesmo mês do ano seguinte estejam correlacionados aos valores do mesmo mês do último ano. Este plot também nos ajudará a identificar componentes tanto não-sazonais quanto sazonais de nosso modelo ARIMA(p,i,q)\(\times\)(P,D,Q)\(_{[12]}\).
Plots da FAC e FACP diferenciada para S=12:
library(gridExtra)
grid.arrange(gg_acf(diff(echo_ts, lag=12), title = "FAC - Echo", lag.max=12*5), gg_pacf(diff(echo_ts, lag=12), title = "FACP - Echo", lag.max=12*5), ncol=2)
Na FACP e na FAC, na parte não-sazonal, há picos mais significantes nos lags 1, 2 e 11 assim como na FAC. Já na porção sazonal da FAC, temos picos claros que vão reduzindo de intensidade em múltiplos de \(S=12\).
Passamos, então, ao ajuste dos Modelos SARIMA para nossos dados.
Ajuste do modelo:
Algoritmo para testar várias combinações de modelo até ordem 3 e calcular o BIC:
library(astsa)
# ordens que queremos testar
x <- rep(0:3, 2)
# ou # expand.grid(df = data.frame(x=0:3, y=0:3))
cb1 <- combn(x, 2)
cb1 <- t(unique(t(cb1)))
cb1 <- cb1[,-3] # eliminando coluna soh de zeros
# cb1 <- cb1[,-c(3,4,5,9,13,14,15)]
# cb2 <- combn(rev(x), 2)
# cb1[1,5] <- "a"
cb2 <- cb1
BIC.v <- NULL
k = 0
model.orders <- NULL
# library(astsa)
for(j in 1:ncol(cb1)){
for(J in 1:ncol(cb2)){
p <- cb1[1,j]
q <- cb1[2,j]
P <- cb2[1,J]
Q <- cb2[2,J]
k <- k + 1
model.orders[k] <- paste(p,0,q,P,1,Q, sep=",")
# assign(paste0("m.", k), sarima(echo_ts, p,0,q, P,1,Q, S=12, details=FALSE))
BIC.v[k] <- tryCatch({
m <- sarima(echo_ts, p,0,q, P,1,Q, S=12, details=FALSE)
m$BIC
},
error = function(e){
"erro"
})
}
}
dfBIC <- data.frame(model = model.orders, BIC = BIC.v)
# ordenando
dfBIC2 <- dfBIC %>%
dplyr::mutate(BIC = as.numeric(as.character(BIC))) %>%
dplyr::arrange(BIC, model )
readr::write_tsv(dfBIC2, path="/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/dfBIC2.txt")
Modelos testados em ordem de menor BIC:
dfBIC2 <- readr::read_tsv("/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/dfBIC2.txt") %>%
as.data.frame() %>%
dplyr::mutate(BIC = round(BIC, 4))
dfBIC2
Passamos agora ao cálculo dos MAPE dos modelos adotados como possíveis candidatos no cálculo do BIC.
library(astsa)
# X <- as.ts(echo$X)
# tanto faz
X <- echo2$X
abs.pred.error <- NULL
pred <- NULL
n <- length(X)
# fit <- arima(X, order=c(2,0,3), seasonal=list(order=c(3,1,2), period=12),
# method="CSS-ML")
# fit2 <- sarima(X, 2,0,3,3,1,2, S=12)
for(t in 0:11){
model <- sarima.for(X[1:(n-12+t)], n.ahead=1,
2,0,3,3,1,2, S=12, newxreg = n+1)
abs.pred.error[t+1] <- abs((X[(n-12+t+1)]-as.numeric(model$pred))/X[(n-12+t+1)])
pred[t+1] <- as.numeric(model$pred)
}
# mape.203312 <- mean(abs.pred.error)
mape.203312 <- "erro optim"
# ------------------------
abs.pred.error <- NULL
pred <- NULL
n <- length(X)
for(t in 0:11){
model <- sarima.for(X[1:(n-12+t)], n.ahead=1,
3,0,2,3,1,2, S=12, newxreg = n+1)
abs.pred.error[t+1] <- abs((X[(n-12+t+1)]-as.numeric(model$pred))/X[(n-12+t+1)])
pred[t+1] <- as.numeric(model$pred)
}
mape.302312 <- mean(abs.pred.error)
# ------------------------
abs.pred.error <- NULL
pred <- NULL
n <- length(X)
for(t in 0:11){
model <- sarima.for(X[1:(n-12+t)], n.ahead=1,
2,0,3,3,1,3, S=12, newxreg = n+1)
abs.pred.error[t+1] <- abs((X[(n-12+t+1)]-as.numeric(model$pred))/X[(n-12+t+1)])
pred[t+1] <- as.numeric(model$pred)
}
mape.203313 <- mean(abs.pred.error)
# ------------------------
abs.pred.error <- NULL
pred <- NULL
n <- length(X)
for(t in 0:11){
model <- sarima.for(X[1:(n-12+t)], n.ahead=1,
3,0,3,3,1,2, S=12, newxreg = n+1)
abs.pred.error[t+1] <- abs((X[(n-12+t+1)]-as.numeric(model$pred))/X[(n-12+t+1)])
pred[t+1] <- as.numeric(model$pred)
}
mape.303312 <- mean(abs.pred.error)
mape.303312 <- "erro optim"
# ------------------------
abs.pred.error <- NULL
pred <- NULL
n <- length(X)
for(t in 0:11){
model <- sarima.for(X[1:(n-12+t)], n.ahead=1,
3,0,0,3,1,3, S=12, newxreg = n+1)
abs.pred.error[t+1] <- abs((X[(n-12+t+1)]-as.numeric(model$pred))/X[(n-12+t+1)])
pred[t+1] <- as.numeric(model$pred)
}
mape.300313 <- mean(abs.pred.error)
# ------------------------
abs.pred.error <- NULL
pred <- NULL
n <- length(X)
for(t in 0:11){
model <- sarima.for(X[1:(n-12+t)], n.ahead=1,
3,0,0,2,1,3, S=12, newxreg = n+1)
abs.pred.error[t+1] <- abs((X[(n-12+t+1)]-as.numeric(model$pred))/X[(n-12+t+1)])
pred[t+1] <- as.numeric(model$pred)
}
mape.300213 <- mean(abs.pred.error)
mape.sarima <- data.frame(mape = c(mape.203312, round(mape.302312,4), round(mape.203313,4), mape.303312, round(mape.300313,4), round(mape.300213,4)))
readr::write_tsv(mape.sarima, path="/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/mape_sarima.txt")
Grid com o melhor modelo:
mape.sarima <- readr::read_tsv("/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/mape_sarima.txt")
# nao eh numeric
df.result <- cbind(dfBIC2[1:6,], mape.sarima)
plotly_palette <- c('#1F77B4', '#FF7F0E', '#2CA02C', '#D62728', "#9467bd", "#8c564b")
library(knitr)
library(kableExtra)
df.result %>%
dplyr::mutate(
mape = cell_spec(mape,
background = ifelse(mape == "0.1744", plotly_palette[3], "white"),
color = dplyr::if_else(mape == "0.1744", "white", "black"))) %>%
# mape nesse caso eh string, nao eh numero
kable(format="html", escape=F, digits = 4, caption="Grid SARIMA") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = T) #%>%
model | BIC | mape |
---|---|---|
2,0,3,3,1,2 | 5.4907 | erro optim |
3,0,2,3,1,2 | 5.4937 | 0.1752 |
2,0,3,3,1,3 | 5.4979 | 0.1744 |
3,0,3,3,1,2 | 5.5014 | erro optim |
3,0,0,3,1,3 | 5.5110 | 0.1803 |
3,0,0,2,1,3 | 5.5162 | 0.1826 |
Portanto, o modelo mais adequado ao caso, utilizando como critério o MAPE seria o ARIMA(2,0,3)\(\times\)(3,1,3)\(_{[12]}\).
Plot valores preditos vs. observados nos modelos selecionados:
Abaixo apresentamos os plots comparando os valores observados e valores preditos para as últimas 12 observações para o modelo selecionado.
library(astsa)
X <- echo2$X
abs.pred.error <- NULL
pred <- NULL
n <- length(X)
for(t in 0:11){
model <- sarima.for(X[1:(n-12+t)], n.ahead=1,
2,0,3,3,1,3, S=12, newxreg = n+1)
abs.pred.error[t+1] <- abs((X[(n-12+t+1)]-as.numeric(model$pred))/X[(n-12+t+1)])
pred[t+1] <- as.numeric(model$pred)
}
X.last.12 <- X[(n-11):n]
obs_pred.sarima <- data.frame(X.last.12, pred)
readr::write_tsv(obs_pred.sarima, path="/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/obs_pred.sarima.txt")
obs_pred.sarima <- readr::read_tsv("/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/obs_pred.sarima.txt")
X.last.12 <- obs_pred.sarima$X.last.12
pred <- obs_pred.sarima$pred
hchart(as.ts(X.last.12), name="observado") %>%
hc_add_series(as.ts(pred), name="previsto") %>%
hc_colors(plotly_palette[c(5,4)]) %>%
hc_title(text = "Echo - Previsto vs Observado (últimas 12 obs) - Arima(2,0,3)x(3,1,3)[12]",
margin = 20, align = "center",
style = list(color = "black", useHTML = TRUE))
library(forecast)
library(astsa)
echofit <- arima(echo_ts, order=c(2,0,3), seasonal=list(order=c(3,1,3),period=12)) # usaremos arima para facilitar o plot
echofcast <- forecast(echofit, h=12)
Valores Preditos:
as.data.frame(echofcast, rownames = TRUE)
Plots dos valores preditos:
# help(window)
plotly_palette <- c('#1F77B4', '#FF7F0E', '#2CA02C', '#D62728', "#9467bd", "#8c564b")
echofcast_window <- echofcast # para selecionar janelas de tempo em ts
echofcast_window$x <- window(echofcast$x, 2010, 2018)
hchart(echofcast_window, name="NOAA", type="line") %>%
hc_colors(plotly_palette[c(5,1,4,3,6)]) %>%
hc_title(text = "Série Histórica Mensal de Evaporação - Previsão 12 Meses (zoom Jan 2010 - Dez 2018)",
margin = 20, align = "center",
style = list(color = "black", useHTML = TRUE))
# plot(echofcast)
O arquivo \(\verb|DadosNilo2.txt|\) contém a série histórica dos níveis máximos anuais observados no Rio Nilo, Egito, do ano 622 D.C. ao ano 1284 D.C.
Dados brutos antes do tratamento:
# ----- leitura e carregamento
library(tibbletime)
library(dplyr)
library(ggplot2)
library(readr)
library(lubridate)
library(reshape2)
nilo.loc <- "/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/DadosNilo2.txt"
nilo <- as.data.frame(scan(nilo.loc, what = list(volume=0)))
# nilo[is.na(nilo),]
nilo
Nosso interesse é obter o melhor modelo em termos técnicos, ou seja, obter um modelo ARIMA com o melhor desempenho de predição. Por isso, nossa estratégia não será a de testar a estacionariedade da série, mas sim ajustar modelos com a série sem diferenciar e com a série diferenciada e verificar seus resultados em termos do Mean Absolute Percentage Error (MAPE) na predição de um passo.
Inicialmente, procedemos a uma análise de ordem exploratória nos dados para termos uma ideia do comportamento da série.
Começamos pela plotagem das séries.
Gráficos das séries mensais:
# crinado as ts
nilo_ts <- ts(nilo %>% dplyr::select(volume), start = 622, end = 1284, frequency = 1) # uma por ano
library(forecast)
library(highcharter)
library(ggplot2)
plotly_palette <- c('#1F77B4', '#FF7F0E', '#2CA02C', '#D62728', "#9467bd", "#8c564b")
hchart(nilo_ts, nome="volume") %>%
hc_colors(plotly_palette[6]) %>%
hc_title(text = "Série Histórica Nível Máximo Anual do Rio Nilo (622 D.C. - 1284 D.C.)",
margin = 20, align = "center",
style = list(color = "black", useHTML = TRUE))
Plots da FAC e FACP:
library(gridExtra)
grid.arrange(gg_acf(nilo_ts, title = "FAC - Nilo", lag.max=12*10), gg_pacf(nilo_ts, title = "FACP - Nilo", lag.max=12*10), ncol=2)
Olhando para o gráfico da série, não parece haver qualquer tendência nos dados. Não há evidências também de sazonalidade, indicando a adequabilidade de um modelo ARIMA não-sazonal para o caso. A FAC apresenta um decaimento relativamente lento, mas que indica provavelmente um modelo autorregressivo de memória longa e talvez não uma ausência de estacionariedade. Como nosso objetivo é obter o modelo com base na abordagem empírica de performance na predição, deixaremos que eventuais restrições relacionadas a uma possível não-estacionariedade da série reflitam nos resultados ao selecionarmos os melhores modelos. Utilizaremos o Mean Absolute Percentage Error (MAPE) de um passo a frente como critério de otimalidade, tomando como base os últimos 12 meses, para confeccionar um grid que nos apontará os modelos candidatos.
# -----------------------------------------------------------------------
# Identificao da ordem do processo
# com base no erro de previsao 1 passo a frente
# relativo as ultimas 12 observacoes
# -----------------------------------------------------------------------
X.0 <- nilo$volume # extrair somente os valores como vetor mesmo
N <- length(nilo$volume)
p.max = 7
q.max = 3
MAPE <- matrix(0, p.max+1, q.max+1)
for (p in 0:p.max){
for (q in 0:q.max){
previsto <- NULL
observado <- NULL
for (t in 0:11){
X <- X.0[1:(N-12+t)]
n <- length(X)
# fit <- arima(X, order=c(p, 1, q),xreg=1:n) #Certo
fit <- arima(X, order=c(p, 0, q),xreg=1:n) #Certo
prev <- predict(fit, n.ahead = 1, newxreg=(n+1))
obs <- X.0[N-12+t+1]
previsto[t+1] <- prev$pred
observado[t+1] <- obs
}
MAPE[(p+1),(q+1)] <- 100*(mean(abs((previsto-observado)/observado)))
}
}
MAPE_nodiff_nilo <- MAPE
readr::write_tsv(as.data.frame(MAPE_nodiff_nilo), path="/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/MAPE_nodiff_nilo.txt")
Temos os seguintes grids resultantes do algoritmo de otimização:
MAPE_nodiff_nilo <- readr::read_tsv("/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/MAPE_nodiff_nilo.txt") %>%
magrittr::set_colnames(paste0("q=", 0:3)) %>%
as.data.frame() %>%
round(., 4) %>%
`rownames<-`(paste0("p=", 0:7))
Para cada série analisada, elencamos os 3 melhores modelo, os quais são destacados nos respectivos grids.
library(kableExtra)
library(knitr)
MAPE_nodiff_nilo %>%
dplyr::mutate(
`q=0` = cell_spec(`q=0`,
background = ifelse(`q=0` == 4.3837, plotly_palette[3],
ifelse(`q=0` < 4.45 & `q=0` != 4.3837, plotly_palette[6], "white")),
color = dplyr::if_else(`q=0` < 4.45, "white", "black")),
`q=1` = cell_spec(`q=1`,
background = ifelse(`q=1` < 4.5, plotly_palette[6], "white"),
color = dplyr::if_else(`q=1` < 4.5, "white", "black")),
ordem = rownames(.),
ordem = cell_spec(ordem, color = "black")) %>%
dplyr::select(ordem, paste0("q=", 0:3)) %>%
kable(format="html", escape=F, digits = 4, caption="grid Nilo - série não diferenciada") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = F) #%>%
ordem | q=0 | q=1 | q=2 | q=3 |
---|---|---|---|---|
p=0 | 5.6908 | 4.7865 | 4.9811 | 4.7038 |
p=1 | 4.7187 | 4.4472 | 4.6277 | 4.6964 |
p=2 | 4.6182 | 4.712 | 4.7140 | 4.6784 |
p=3 | 4.3837 | 4.7184 | 4.7156 | 4.7001 |
p=4 | 4.4488 | 4.6782 | 4.6954 | 4.8988 |
p=5 | 4.4835 | 4.5002 | 4.6670 | 4.8862 |
p=6 | 4.4702 | 4.683 | 4.6671 | 4.8381 |
p=7 | 4.6226 | 4.744 | 4.7561 | 4.8528 |
Após selecionarmos os melhores modelos no caso da série não diferenciada, passamos para a confecção dos grids de desempenho para a série diferenciada.
Novamente, utilizaremos o Mean Absolute Percentage Error (MAPE) de um passo a frente como critério de otimalidade e tomando como base os últimos 12 meses para confeccionar um grid que nos apontará os modelos candidatos.
# -----------------------------------------------------------------------
# Identificao da ordem do processo
# com base no erro de previsao 1 passo a frente
# relativo as ultimas 12 observacoes
# -----------------------------------------------------------------------
X.0 <- nilo$volume # extrair somente os valores como vetor mesmo
N <- length(nilo$volume)
p.max = 7
q.max = 3
MAPE <- matrix(0, p.max+1, q.max+1)
for (p in 0:p.max){
for (q in 0:q.max){
previsto <- NULL
observado <- NULL
for (t in 0:11){
X <- X.0[1:(N-12+t)]
n <- length(X)
fit <- arima(X, order=c(p, 1, q),xreg=1:n) #Certo
# fit <- arima(X, order=c(p, 0, q),xreg=1:n) #Certo
prev <- predict(fit, n.ahead = 1, newxreg=(n+1))
obs <- X.0[N-12+t+1]
previsto[t+1] <- prev$pred
observado[t+1] <- obs
}
MAPE[(p+1),(q+1)] <- 100*(mean(abs((previsto-observado)/observado)))
}
}
MAPE_diff_nilo <- MAPE
readr::write_tsv(as.data.frame(MAPE_diff_nilo), path="/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/MAPE_diff_nilo.txt")
Temos os seguintes grids resultantes do algoritmo de otimização:
MAPE_diff_nilo <- readr::read_tsv("/home/allan/Documents/1S2018/A_SERIES_TEMPORAIS/PP2/dados/MAPE_diff_nilo.txt") %>%
magrittr::set_colnames(paste0("q=", 0:3)) %>%
as.data.frame() %>%
round(., 4) %>%
`rownames<-`(paste0("p=", 0:7))
Para cada série analisada, elencamos os 3 melhores modelo, os quais são destacados nos respectivos grids.
library(kableExtra)
library(knitr)
MAPE_diff_nilo %>%
dplyr::mutate(
`q=0` = cell_spec(`q=0`,
background = ifelse(`q=0` == 4.0483, plotly_palette[3],
ifelse(`q=0` < 4.45 & `q=0` != 4.3837, plotly_palette[6], "white")),
color = dplyr::if_else(`q=0` < 4.45, "white", "black")),
`q=1` = cell_spec(`q=1`,
background = ifelse(`q=1` < 4.5, plotly_palette[6], "white"),
color = dplyr::if_else(`q=1` < 4.5, "white", "black")),
ordem = rownames(.),
ordem = cell_spec(ordem, color = "black")) %>%
dplyr::select(ordem, paste0("q=", 0:3)) %>%
kable(format="html", escape=F, digits = 4, caption="grid Nilo - série diferenciada") %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = F) #%>%
ordem | q=0 | q=1 | q=2 | q=3 |
---|---|---|---|---|
p=0 | 4.9889 | 4.745 | 4.8405 | 4.9001 |
p=1 | 4.7124 | 4.8692 | 4.8346 | 4.7068 |
p=2 | 4.0483 | 4.8607 | 4.8579 | 4.7071 |
p=3 | 4.3445 | 4.7404 | 4.7331 | 4.7660 |
p=4 | 4.3819 | 4.7299 | 4.7318 | 5.1384 |
p=5 | 4.2914 | 4.7308 | 4.7468 | 4.9004 |
p=6 | 4.5855 | 4.7521 | 4.7778 | 4.9065 |
p=7 | 4.6389 | 4.7937 | 4.8062 | 4.9051 |
Dentre os modelos analisados (para série não diferenciada e diferenciada), o melhor modelo, utilizando como critério o desempenho medido pelo MAPE de um passo é um ARIMA(2,1,0), o que se aproxima do modelo sugerido por Aguado (1982), qual seja, Arima(2,1,1). A diferença deve-se provavelmente ao fato de Aguado (1982) ter utilizado como critério o ajuste do modelo comporando os BIC’s, enquanto nós utilizamos o MAPE, focando no desempenho preditivo.
Plot valores preditos vs. observados nos modelos selecionados:
Abaixo apresentamos os plots comparando os valores observados e valores preditos para as últimas 12 observações para o modelo selecionado.
X.0 <- nilo_ts
N <- length(X.0)
# X.0 <- nilo$volume # extrair somente os valores como vetor mesmo
# N <- length(nilo$volume)
previsto <- NULL
observado <- NULL
for (t in 0:11){
X <- X.0[1:(N-12+t)]
n <- length(X)
fit <- arima(X, order=c(2, 1, 0),xreg=1:n)
prev <- predict(fit, n.ahead = 1, newxreg=(n+1))
obs <- X.0[N-12+t+1]
previsto[t+1] <- prev$pred
observado[t+1] <- obs
}
hchart(as.ts(observado), name="observado") %>%
hc_add_series(as.ts(previsto), name="previsto") %>%
hc_colors(plotly_palette[c(6,4)]) %>%
hc_title(text = "Nível Máximo Nilo - Previsto vs Observado (últimas 12 obs) - Arima(2,1,0)",
margin = 20, align = "center",
style = list(color = "black", useHTML = TRUE))
library(forecast)
library(astsa)
nilofit <- arima(nilo_ts, order=c(2,1,0)) # usaremos arima para facilitar o plot
nilofcast <- forecast(nilofit, h=5)
Valores Preditos:
as.data.frame(nilofcast, rownames = TRUE)
Plot dos valores preditos:
# help(window)
plotly_palette <- c('#1F77B4', '#FF7F0E', '#2CA02C', '#D62728', "#9467bd", "#8c564b")
nilofcast_window <- nilofcast # para selecionar janelas de tempo em ts
nilofcast_window$x <- window(nilofcast$x, 1180, 1289)
hchart(nilofcast_window, name="NOAA", type="line") %>%
hc_colors(plotly_palette[c(6,1,4,3,5)]) %>%
hc_title(text = "Série Histórica Anual - Nível Rio Nilo - Previsão 5 Anos (zoom 1180 - 1289)",
margin = 20, align = "center",
style = list(color = "black", useHTML = TRUE))
# plot(echofcast)
AGUADO, E. Time Series Analysis of Nile Flows. Annals of the Association of the American Geographers 72: 109-19.
MORETTIN, P.A. & TOLOI, C.M. Análise de Séries Temporais. 2a ed., Edgard Blücher, 2005.
NOTAS DE AULA. Análise de Séries Temporais. Curso de Graduação em Estatística, UnB, 2018.
R CORE TEAM. R: A language and environment for statistical computing. R Foundation for Statistical Computing, Vienna, Austria. URL https://www.R-project.org/.
SHUMWAY, R.H. & STOFFER, D.S. Time Series Analysis and Its Applications with R Examples. Springer, 2011.