Hi everyone:

My question is about the function "StructTS" of the core package "stats", which 
fits by maximum likelihood the basic structural time series model.

According to theory and the references given in "?StructTS", the covariance 
matrix of the initial state vector is a diagonal matrix. However, in "StructTS" 
it is defined as a matrix containing the same value in the diagonal and 
off-diagonal elements of the matrix. The matrix is defined as follows in 
"StructTS":

Z$P[] <- 1e+06 * vx

Does anybody know why is this matrix defined as non-diagonal? May it be some 
kind of diffuse initialization? That's not the way I understand it in textbooks 
though, as it still involves diagonal matrices.

I thought it may be a bug in the code. However, as "StructTS" has been defined 
in this way for years and as the documentation claims that the result for the 
"AirPassengers" data is superior to the results reported in other source, I 
wondered whether there may be a reason to use a non-diagonal matrix.

I used the package "stsm" [http://cran.r-project.org/package=stsm] to compare 
some results based on a non-diagonal and a diagonal initial covariance matrix.

# original result obtained with StructTS
res0 <- stats::StructTS(log(AirPassengers), type = "BSM")
res0
# Variances:
#     level      slope       seas    epsilon 
# 0.0007719  0.0000000  0.0013969  0.0000000 

# StructTS can be replicated using the interface in package "stsm" as follows
require("stsm")
mairp <- stsm.model(model = "BSM", y = log(AirPassengers), transPars = 
"StructTS")
res1 <- maxlik.td.optim(mairp, KF.version = "KFKSDS",
KF.args = list(P0cov = TRUE), method = "L-BFGS-B")
mairp1 <- set.pars(mairp, pmax(res1$par, .Machine$double.eps))
round(get.pars(mairp1)[c(4,1:3)], 7)
#      var4      var1      var2      var3
# 0.0013969 0.0000000 0.0007719 0.0000000
all.equal(get.pars(mairp1), res0$coef[c(4,1:3)],
tol = 1e-04, check.attributes = FALSE)
# [1] TRUE

# next, the likelihood function and the optimization procedure
# are defined as in StructTS except for Z$P, which is now a diagonal matrix
res2 <- maxlik.td.optim(mairp, KF.version = "KFKSDS",
KF.args = list(P0cov = FALSE), method = "L-BFGS-B")
mairp2 <- set.pars(mairp, pmax(res2$par, .Machine$double.eps))
round(get.pars(mairp2)[c(4,1:3)], 7)
#      var4      var1      var2      var3
# 0.0000642 0.0001293 0.0006995 0.0000000

The results imply a different allocation of the variance across the components, 
as reflected by these ratios:

round(get.pars(mairp1)[-4]/get.pars(mairp1)[4], 3)
#  var1  var2  var3
# 0.000 0.553 0.000
round(get.pars(mairp2)[-4]/get.pars(mairp2)[4], 3)
#  var1   var2   var3
# 2.014 10.898  0.000

The estimated seasonal component for the modified "StructTS" version (i.e., the 
standard approach using a diagonal matrix) looks better, because the range is 
more homogeneous.

ss2 <- char2numeric(mairp2, P0cov = FALSE)
kf2 <- KFKSDS::KF(mairp1@y, ss2)
ks2 <- KFKSDS::KS(mairp1@y, ss2, kf2)
par(mfcol = c(2,2), mar = c(2.5,5.1,3,2.1))
plot(tsSmooth(res0)[,1], main = "StructTS", ylab = "level")
plot(tsSmooth(res0)[,3], ylab = "seasonal")
plot(ks2$ahat[,1], main = "Modified StructTS", ylab = "level")
plot(ks2$ahat[,3], ylab = "seasonal") 

[image in attachment airp1.pdf]

Yet, I am still doubtful whether this is a bug or intentional. In some cases, I 
have found it useful to use P0cov=TRUE (non-diagonal matrix) when the 
likelihood function is evaluated by the optimization algorithm. Then, given the 
parameter estimates, the smoothed components can be extracted setting 
P0cov=FALSE (diagonal matrix) in the Kalman smoother, in order to avoid the 
erratic behaviour at the beginning of the sample observed in the plot above. 
See for example my answer in this post 
[http://stats.stackexchange.com/questions/115506/forecasting-a-seasonal-time-series-in-r].


I wonder if this qualifies as a bug or if there is a reason that explains the 
non-diagonal matrix used in "StructTS". I would be grateful for some feedback.

Thanks.

--
javi 
http://jalobe.com

Attachment: airp1.pdf
Description: Adobe PDF document

______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to