Este conjunto de dados descreve o número mensal de vendas de xampu em um período de 3 anos. As unidades são uma contagem de vendas e há 36 observações. O conjunto de dados original é creditado a Makridakis, Wheelwright e Hyndman (1998).
shampoo = read.table(file = "http://leg.ufpr.br/~lucambio/CE017/20212S/shampoo.txt", sep=",", header = TRUE)
head(shampoo)
## Month Sales
## 1 1-01 266.0
## 2 1-02 145.9
## 3 1-03 83.1
## 4 1-04 119.3
## 5 1-05 180.3
## 6 1-06 168.5
vendas = ts(shampoo$Sales, start = c(2001,1), frequency = 12)
par(mfrow=c(1,1), mar=c(3,3,1,2)+.5, mgp=c(1.6,.6,0), pch=19)
plot(vendas, ylab="Número mensal de vendas de xampu", xlab="Tempo")
grid()
O conjunto de dados mostra uma tendência crescente e possivelmente algum componente sazonal. Pensamos em tendência não linear, possivelmente uma função exponencial.
Pensamos sempre como refrência alguma curva matemática conhecida: logaritmo, inversa, exponencial, linear, polinômio, etc. Visualizemos algumas destas curvas a continuação.
par(mfrow=c(2,2), mar=c(3,3,1,2)+.5, mgp=c(1.6,.6,0), pch=19)
x = seq(0.01,5,by=0.01)
plot(x,log(x), type="l", col="red",xlab="x",ylab = "logaritmo")
grid()
x = seq(0.01,5,by=0.01)
plot(x,exp(x), type="l", col="red",xlab="x",ylab = "exponencial")
grid()
x = seq(0.01,5,by=0.01)
plot(x,1/x, type="l", col="red",xlab="x",ylab = "inversa")
grid()
x = seq(0.01,5,by=0.01)
plot(x,x+x^2, type="l", col="red",xlab="x",ylab = "polinômio")
grid()
Transformando os dados originais podemos obter como resposta uma série sem tendência e mesmo um série estacionária. Faremos a continuação a eleiminação da tendência visualizada e verificamos a estaiocionariedade da série obtida.
trend = lm(vendas ~ time(vendas)+I(time(vendas)^2))
(summary(trend))
##
## Call:
## lm(formula = vendas ~ time(vendas) + I(time(vendas)^2))
##
## Residuals:
## Min 1Q Median 3Q Max
## -103.816 -44.693 -7.286 33.564 145.622
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 2.571e+08 6.515e+07 3.947 0.000391 ***
## time(vendas) -2.570e+05 6.507e+04 -3.949 0.000389 ***
## I(time(vendas)^2) 6.420e+01 1.625e+01 3.951 0.000386 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 65.27 on 33 degrees of freedom
## Multiple R-squared: 0.8269, Adjusted R-squared: 0.8164
## F-statistic: 78.8 on 2 and 33 DF, p-value: 2.713e-13
par(mfrow=c(1,1), mar=c(3,3,1,2)+.5, mgp=c(1.6,.6,0), pch=19)
plot(vendas, ylab="Número mensal de vendas de xampu \n tendência estimada", xlab="Tempo")
lines(ts(fitted(trend),start = c(2001,1), frequency = 12), col="red", lwd=2)
grid()
vendas1 = vendas - fitted(trend)
par(mfrow=c(1,1), mar=c(3,3,1,2)+.5, mgp=c(1.6,.6,0), pch=19)
plot(vendas1, ylab="Número mensal de vendas de xampu", xlab="Tempo", col="violet", type="b")
abline(h=0, lwd=2)
grid()
library(astsa)
acf2(vendas1)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
## ACF -0.45 0.16 -0.19 0.03 0.03 -0.11 0.08 -0.23
## PACF -0.45 -0.05 -0.17 -0.16 -0.03 -0.17 -0.08 -0.30
Devemos ter alguma ideia de qual modelo propôr. Uma forma de fazer isso é verificando as possíveis influências das observações atrás na resposta no momento atual.
lag1.plot(vendas1, 6)
Percebemos que este modelo apresenta-se como autoregressivo de ordem máximo 2.
mod1 = arima(vendas1, order=c(1,0,0))
mod1
##
## Call:
## arima(x = vendas1, order = c(1, 0, 0))
##
## Coefficients:
## ar1 intercept
## -0.4653 -1.0452
## s.e. 0.1492 6.3574
##
## sigma^2 estimated as 3065: log likelihood = -195.7, aic = 397.41
mod2 = arima(vendas1, order=c(2,0,0))
mod2
##
## Call:
## arima(x = vendas1, order = c(2, 0, 0))
##
## Coefficients:
## ar1 ar2 intercept
## -0.4939 -0.0605 -1.1361
## s.e. 0.1687 0.1670 5.9993
##
## sigma^2 estimated as 3053: log likelihood = -195.64, aic = 399.28
Podemos investir em mais parâmetros.
mod3 = arima(vendas1, order=c(3,0,0))
mod3
##
## Call:
## arima(x = vendas1, order = c(3, 0, 0))
##
## Coefficients:
## ar1 ar2 ar3 intercept
## -0.4893 -0.1313 -0.1475 -0.8507
## s.e. 0.1674 0.1865 0.1791 5.2756
##
## sigma^2 estimated as 2993: log likelihood = -195.3, aic = 400.61
Caso seja aceito o modelo no objeto mod1 como adequado podemos, entre outras coisas, proceder a predizer valores de vendas futuros. Primeiro fazer ista previsão nos dados transformados, posteriormente apresentamos esta previsão nos dados originais.
# horizonte de provisão
m = 3
preditos = predict(mod1, n.ahead = m)
par(mfrow = c(1,1), mar=c(4,3,1,1), mgp=c(1.6,.6,0), pch=19)
ts.plot(vendas1, preditos$pred, col=1:2, xlim=c(2001,2004.2), lwd=2, ylab="Vendas de xampú", xlab="Tempo")
U = preditos$pred+preditos$se; L = preditos$pred-preditos$se
xx = c(time(U), rev(time(U))); yy = c(L, rev(U))
polygon(xx, yy, border = 8, col = gray(.6, alpha = .2))
lines(preditos$pred, type="p", col=2)
grid()
Procedemos agora a aplicar a transformação inversa nos dados, ou seja, acrescentrar a tendência estimada aos dados transformados e ainda predizemos os valores de tendência para os valores preditos serem transformados à escala origina.
n = length(vendas)
novas.vendas = ts(c(shampoo$Sales,rep(0,m)), start = c(2001,1), frequency = 12)
vendas2 = coef(trend)[1]+coef(trend)[2]*time(novas.vendas)+coef(trend)[3]*I(time(novas.vendas)^2)
novos.preditos = vendas2[(n+1):(n+m)]+preditos$pred
par(mfrow = c(1,1), mar=c(4,3,1,1), mgp=c(1.6,.6,0), pch=19)
ts.plot(vendas, novos.preditos, col=1:2, xlim=c(2001,2004.2), lwd=2, ylab="Vendas de xampu", xlab="Tempo")
U = novos.preditos+preditos$se; L = novos.preditos-preditos$se
xx = c(time(U), rev(time(U))); yy = c(L, rev(U))
polygon(xx, yy, border = 8, col = gray(.6, alpha = .2))
lines(novos.preditos, type="p", col=2)
grid()