Hay tres cuestiones menores en tseries::arma
en comparación con stats::arima
que conducen a un resultado ligeramente diferente en el modelo ARMA para las series diferenciadas utilizando tseries::arma
y ARIMA en stats::arima
.
-
Valores iniciales de los coeficientes: stats::arima
pone a cero los coeficientes iniciales AR y MA, mientras que tseries::arma
utiliza el procedimiento descrito en Hannan y Rissanen (1982) para obtener los valores iniciales de los coeficientes.
-
Escala de la función objetivo: la función objetivo en tseries::arma
devuelve el valor de las sumas condicionales de los cuadrados, RSS; stats::arima
devuelve 0.5*log(RSS/(n-ncond))
.
-
Algoritmo de optimización: Por defecto, se utiliza Nelder-Mead en tseries::arma
, mientras que stats::arima
emplea el algoritmo BFGS.
Este último puede modificarse mediante el argumento optim.method
en stats::arima
pero los otros requerirían modificar el código. A continuación, muestro una versión abreviada del código fuente (código mínimo para este modelo en particular) para stats::arima
donde se modifican las tres cuestiones mencionadas anteriormente para que sean las mismas que en tseries::arma
. Después de abordar estas cuestiones, el mismo resultado que en tseries::arma
se obtiene.
Versión mínima de stats::arima
(con los cambios mencionados anteriormente):
# objective function, conditional sum of squares
# adapted from "armaCSS" in stats::arima
armaCSS <- function(p, x, arma, ncond)
{
# this does nothing, except returning the vector of coefficients as a list
trarma <- .Call(stats:::C_ARIMA_transPars, p, arma, FALSE)
res <- .Call(stats:::C_ARIMA_CSS, x, arma, trarma[[1L]], trarma[[2L]], as.integer(ncond), FALSE)
# return the conditional sum of squares instead of 0.5*log(res),
# actually CSS is divided by n-ncond but does not relevant in this case
#0.5 * log(res)
res
}
# initial values of coefficients
# adapted from function "arma.init" within tseries::arma
arma.init <- function(dx, max.order, lag.ar=NULL, lag.ma=NULL)
{
n <- length(dx)
k <- round(1.1*log(n))
e <- as.vector(na.omit(drop(ar.ols(dx, order.max = k, aic = FALSE, demean = FALSE, intercept = FALSE)$resid)))
ee <- embed(e, max.order+1)
xx <- embed(dx[-(1:k)], max.order+1)
return(lm(xx[,1]~xx[,lag.ar+1]+ee[,lag.ma+1]-1)$coef)
}
# modified version of stats::arima
modified.arima <- function(x, order, seasonal, init)
{
n <- length(x)
arma <- as.integer(c(order[-2L], seasonal$order[-2L], seasonal$period, order[2L], seasonal$order[2L]))
narma <- sum(arma[1L:4L])
ncond <- order[2L] + seasonal$order[2L] * seasonal$period
ncond1 <- order[1L] + seasonal$period * seasonal$order[1L]
ncond <- as.integer(ncond + ncond1)
optim(init, armaCSS, method = "Nelder-Mead", hessian = TRUE, x=x, arma=arma, ncond=ncond)$par
}
Ahora, compara ambos procedimientos y comprueba que dan el mismo resultado (requiere la serie x
generado por el OP en el cuerpo de la pregunta).
Utilizando los valores iniciales elegidos en tseries::arima
:
dx <- diff(x)
fit1 <- arma(dx, order=c(3,3), include.intercept=FALSE)
coef(fit1)
# ar1 ar2 ar3 ma1 ma2 ma3
# 0.33139827 0.80013071 -0.45177254 0.67331027 -0.14600320 -0.08931003
init <- arma.init(diff(x), 3, 1:3, 1:3)
fit2.coef <- modified.arima(x, order=c(3,1,3), seasonal=list(order=c(0,0,0), period=1), init=init)
fit2.coef
# xx[, lag.ar + 1]1 xx[, lag.ar + 1]2 xx[, lag.ar + 1]3 ee[, lag.ma + 1]1
# 0.33139827 0.80013071 -0.45177254 0.67331027
# ee[, lag.ma + 1]2 ee[, lag.ma + 1]3
# -0.14600320 -0.08931003
all.equal(coef(fit1), fit2.coef, check.attributes=FALSE)
# [1] TRUE
Utilizando los valores iniciales elegidos en stats::arima
(ceros):
fit3 <- arma(dx, order=c(3,3), include.intercept=FALSE, coef=rep(0,6))
coef(fit3)
# ar1 ar2 ar3 ma1 ma2 ma3
# 0.33176424 0.79999112 -0.45215742 0.67304072 -0.14592152 -0.08900624
init <- rep(0, 6)
fit4.coef <- modified.arima(x, order=c(3,1,3), seasonal=list(order=c(0,0,0), period=1), init=init)
fit4.coef
# [1] 0.33176424 0.79999112 -0.45215742 0.67304072 -0.14592152 -0.08900624
all.equal(coef(fit3), fit4.coef, check.attributes=FALSE)
# [1] TRUE
0 votos
fit1
tiene sólo 1 parámetro MA y 1 AR: ¿se refiere afit1<-arma(diff(x,1,lag=1),c(3,3),include.intercept=F)
?1 votos
Supongo que hay alguna ligera diferencia en los algoritmos de ajuste incluso cuando se especifica la minimización de la suma condicional de los errores al cuadrado. Las páginas de ayuda de
arima
mencionar unn.cond
argumento que da el número de observaciones al principio de la serie que hay que ignorar al calcularla - tal vez sea eso. (¿Qué hay de malo en utilizar la máxima verosimilitud?)0 votos
AFAIK n.cond no utiliza las primeras observaciones para ajustar. A mí no me ha servido de nada. No hay nada malo con ML en absoluto. Sólo me gustaría entender las diferencias.
3 votos
¿Duplicado? stats.stackexchange.com/a/32799/159