This illustration examines monthly New Residential Construction (1964-2012), Housing Units Started, Single Family Units. (The four series are from the Survey of Construction of the U.S. Census Bureau, available at http://www.census.gov/construction/nrc/how_the_data_are_collected/soc.html.) We refer to the series as starts for short. The data corresponds to the four regions of South, West, NorthEast, and MidWest. This example illustrates modeling a multivariate series with $8$ components, estimated with both MOM and MLE methods, and the extraction of signals with two methods (direct matrix and truncated Wiener-Kolmogorov). We also show how functions of a signal, such as growth rates, can be obtained.
This code installs and loads the packages, and loads the data into a variable named starts.
library(devtools) library(Rcpp) devtools::install_github("tuckermcelroy/sigex") library(sigex)
start.date = c(1964,1) period <- 12
dataALL.ts <- sigex.load(starts,start.date,period, c("South","West","NE","MW"),TRUE)
transform <- "none" aggregate <- FALSE subseries <- c(1,2,3,4) begin.date <- start.date end.date <- end(dataALL.ts) range <- list(begin.date,end.date) data.ts <- sigex.prep(dataALL.ts,transform,aggregate,subseries,range,TRUE)
# raw data par(mfrow=c(2,2)) for(i in subseries) { sigex.specar(data.ts,FALSE,i,period) }
# growth rates par(mfrow=c(2,2)) for(i in subseries) { sigex.specar(data.ts,TRUE,i,period) }
N <- dim(data.ts)[2] T <- dim(data.ts)[1]
mdl <- NULL mdl <- sigex.add(mdl,seq(1,N),"arma",c(0,0),NULL,"trend",c(1,-2,1)) mdl <- sigex.add(mdl,seq(1,N),"arma",c(0,0),NULL,"first seasonal", c(1,-sqrt(3),1)) mdl <- sigex.add(mdl,seq(1,N),"arma",c(0,0),NULL,"second seasonal",c(1,-1,1)) mdl <- sigex.add(mdl,seq(1,N),"arma",c(0,0),NULL,"third seasonal",c(1,0,1)) mdl <- sigex.add(mdl,seq(1,N),"arma",c(0,0),NULL,"fourth seasonal",c(1,1,1)) mdl <- sigex.add(mdl,seq(1,N),"arma",c(0,0),NULL,"fifth seasonal", c(1,sqrt(3),1)) mdl <- sigex.add(mdl,seq(1,N),"arma",c(0,0),NULL,"sixth seasonal",c(1,1)) mdl <- sigex.add(mdl,seq(1,N),"arma",c(0,0),NULL,"irregular",1)
mdl <- sigex.meaninit(mdl,data.ts,0)
mdl.mom <- mdl constraint <- NULL par.default <- sigex.default(mdl.mom,data.ts,constraint) par.mom <- sigex.momfit(data.ts,par.default,mdl.mom) psi.mom <- sigex.par2psi(par.mom,mdl.mom)
r sigex.lik(psi.mom,mdl.mom,data.ts,FALSE)
.resid.mom <- sigex.resid(psi.mom,mdl.mom,data.ts)[[1]] resid.mom <- sigex.load(t(resid.mom),start(data.ts), frequency(data.ts),colnames(data.ts),TRUE) resid.acf <- acf(resid.mom,lag.max=4*period,plot=TRUE)$acf
log(sigex.conditions(data.ts,psi.mom,mdl.mom))
thresh <- -6.22 reduced.mom <- sigex.reduce(data.ts,par.mom,mdl.mom,thresh,TRUE) mdl.mom <- reduced.mom[[1]] par.mom <- reduced.mom[[2]] psi.mom <- sigex.par2psi(par.mom,mdl.mom)
r sigex.lik(psi.mom,mdl.mom,data.ts,FALSE)
.resid.mom <- sigex.resid(psi.mom,mdl.mom,data.ts)[[1]] resid.mom <- sigex.load(t(resid.mom),start(data.ts), frequency(data.ts),colnames(data.ts),TRUE) resid.acf <- acf(resid.mom,lag.max=4*period,plot=TRUE)$acf
log(sigex.conditions(data.ts,psi.mom,mdl.mom))
sigex.portmanteau(resid.mom,4*period,length(psi.mom)) sigex.gausscheck(resid.mom)
analysis.mom <- sigex.bundle(data.ts,transform,mdl.mom,psi.mom)
data.ts <- analysis.mom[[1]] mdl <- analysis.mom[[3]] psi.mom <- analysis.mom[[4]] par.mom <- sigex.psi2par(psi.mom,mdl,data.ts)
constraint <- NULL psi.mle <- sigex.par2psi(par.mom,mdl)
#fit.mle <- sigex.mlefit(data.ts,par.mom,constraint,mdl,"bfgs",debug=TRUE) psi.mle <- c(0.430604758988307, 0.138843971938441, 0.211034753655249, 0.122497565015475, 0.273961955347927, 0.83829841362335, -2.19718581249183, -4.85906104866881, -6.69696771334971, -6.13282806492413, 1.12175825784647, 0.289882305425559, 0.873677616319397, -0.745293003402034, -0.754732471766407, -0.498376140705462, -2.42443529609759, -4.72941611158525, -6.52941280216317, 0.459400674188665, 0.208306224143506, 1.24487637498583, -1.388883213613, -0.526433078980047, -3.90916616951099, -5.82829964996699, -0.169794036259361, 0.22214398081366, 0.152889428361731, -0.00908575947899202, -0.00318543112970812, 0.0884748269673841, -2.73579660752933, -3.66216778737483, -4.49261642825817, -0.112193904428172, -0.203557855469594, -0.164528907998198, -0.680285482020193, 0.244662042202419, -3.28673706196714, -6.93954034182091, 1.05554783833862, -0.16328976555996, 0.311473085983565, -4.85381927837337, -0.244998596862816, 0.0508029104468634, 0.194372016161389, 1.14475061810928, -0.253386348374559, -3.61493340437869, -6.83641878016894, 0.0921157226442518, 0.0283709627836627, -0.0389611692363272, 0.0109437749519264, 0.0358792010736619, 0.245040148693726, 2.69734505562902, 1.07979552299194, -0.0671443528547337, 0.302809384452077, 0.000724801053757517, 0.000779888484070904, -2.68663079304438e-05, 0.000373610017630947) par.mle <- sigex.psi2par(psi.mle,mdl,data.ts)
r sigex.lik(psi.mle,mdl,data.ts,FALSE)
.r sigex.lik(psi.mom,mdl.mom,data.ts,FALSE)
.resid.mle <- sigex.resid(psi.mle,mdl,data.ts)[[1]] resid.mle <- sigex.load(t(resid.mle),start(data.ts), frequency(data.ts),colnames(data.ts),TRUE) resid.acf <- acf(resid.mle,lag.max=4*period,plot=TRUE)$acf
log(sigex.conditions(data.ts,psi.mle,mdl))
sigex.portmanteau(resid.mle,4*period,length(psi.mle)) sigex.gausscheck(resid.mle)
analysis.mle <- sigex.bundle(data.ts,transform,mdl,psi.mle)
data.ts <- analysis.mle[[1]] mdl <- analysis.mle[[3]] psi <- analysis.mle[[4]] param <- sigex.psi2par(psi,mdl,data.ts)
signal.trend <- sigex.signal(data.ts,param,mdl,1) signal.seas <- sigex.signal(data.ts,param,mdl,seq(2,7)) signal.sa <- sigex.signal(data.ts,param,mdl,c(1,8))
extract.trend <- sigex.extract(data.ts,signal.trend,mdl,param) extract.seas <- sigex.extract(data.ts,signal.seas,mdl,param) extract.sa <- sigex.extract(data.ts,signal.sa,mdl,param)
reg.trend <- NULL for(i in 1:N) { reg.trend <- cbind(reg.trend,sigex.fixed(data.ts,mdl,i,param,"Trend")) }
trendcol <- "tomato" seascol <- "seagreen" sacol <- "navyblue" fade <- 60 par(mfrow=c(2,2)) for(i in 1:N) { plot(data.ts[,i],xlab="Year",ylab="",ylim=c(min(data.ts[,i])-25, max(data.ts[,i])),lwd=1) sigex.graph(extract.sa,reg.trend,begin.date,period,i,0,sacol,fade) sigex.graph(extract.trend,reg.trend,begin.date,period,i,0,trendcol,fade) sigex.graph(extract.seas,NULL,begin.date,period,i,min(data.ts[,i])-10, seascol,fade) }
## spectral diagnostics: trend par(mfrow=c(2,2)) for(i in 1:N) { sigex.specar(ts(extract.trend[[1]],frequency=period, names=colnames(data.ts)),FALSE,i,period) }
## spectral diagnostics: sa par(mfrow=c(2,2)) for(i in 1:N) { sigex.specar(ts(extract.sa[[1]],frequency=period, names=colnames(data.ts)),FALSE,i,period) }
grid <- 200 par(mfrow=c(4,4)) frf.trend <- sigex.getfrf(data.ts,param,mdl,1,TRUE,grid)
par(mfrow=c(4,4)) frf.seas <- sigex.getfrf(data.ts,param,mdl,seq(2,7),TRUE,grid)
par(mfrow=c(4,4)) frf.sa <- sigex.getfrf(data.ts,param,mdl,c(1,8),TRUE,grid)
len <- 50 target <- array(diag(N),c(N,N,1)) par(mfrow=c(4,4)) wk.trend <- sigex.wk(data.ts,param,mdl,1,target,TRUE,grid,len)
par(mfrow=c(4,4)) wk.seas <- sigex.wk(data.ts,param,mdl,seq(2,7),target,TRUE,grid,len)
par(mfrow=c(4,4)) wk.sa <- sigex.wk(data.ts,param,mdl,c(1,8),target,TRUE,grid,len)
grid <- 7000 window <- 50 horizon <- 0 target <- array(diag(N),c(N,N,1))
extract.trend2 <- sigex.wkextract(psi,mdl,data.ts,1,target, grid,window,horizon,TRUE) extract.seas2 <- sigex.wkextract(psi,mdl,data.ts,seq(2,7),target, grid,window,horizon,TRUE) extract.sa2 <- sigex.wkextract(psi,mdl,data.ts,c(1,8),target, grid,window,horizon,TRUE)
par(mfrow=c(2,2)) for(subseries in 1:N) { ex.true <- (extract.trend[[1]][,subseries]-extract.trend[[3]][,subseries])/2 ex.appr <- (extract.trend2[[1]][,subseries]-extract.trend2[[3]][,subseries])/2 plot(ts(ex.true,start=begin.date,frequency=period),ylab="Root MSE", xlab="Year",ylim=c(0,max(ex.true))) lines(ts(ex.appr,start=begin.date,frequency=period),col=trendcol) }
par(mfrow=c(2,2)) for(subseries in 1:N) { ex.true <- (extract.sa[[1]][,subseries]-extract.sa[[3]][,subseries])/2 ex.appr <- (extract.sa2[[1]][,subseries]-extract.sa2[[3]][,subseries])/2 plot(ts(ex.true,start=begin.date,frequency=period),ylab="Root MSE", xlab="Year",ylim=c(0,max(ex.true))) lines(ts(ex.appr,start=begin.date,frequency=period),col=sacol) }
gr.poly <- c(1,-1) p <- length(gr.poly)-1 gr.mat <- t(rev(gr.poly)) %x% diag(N) mse.trend <- array(signal.trend[[2]],c(N,T,N,T)) mse.trend.gr <- array(0,c(N,N,T-p)) trend.gr <- array(0,c(T-p,N)) trend.est <- extract.trend[[1]] + reg.trend for(t in (p+1):T) { trend.gr[t-p,] <- gr.mat %*% matrix(t(trend.est[(t-p):t,]),ncol=1) mse.trend.gr[,,t-p] <- gr.mat %*% matrix(mse.trend[,(t-p):t,,(t-p):t], c(N*(p+1),N*(p+1))) %*% t(gr.mat) } trend.gr <- ts(rbind(array(NA,c(p,N)),trend.gr), start=begin.date,frequency=period,names=colnames(data.ts)) extract.trendgr <- list(trend.gr,trend.gr,trend.gr) for(k in 1:N) { extract.trendgr[[2]][,k] <- extract.trendgr[[2]][,k] + 2*sqrt(c(rep(NA,p),mse.trend.gr[k,k,])) extract.trendgr[[3]][,k] <- extract.trendgr[[3]][,k] - 2*sqrt(c(rep(NA,p),mse.trend.gr[k,k,])) }
par(mfrow=c(2,2)) for(i in 1:N) { plot(data.ts[,i],xlab="Year",ylab="", ylim=c(min(extract.trendgr[[3]][,i],na.rm=TRUE), max(extract.trendgr[[2]][,i],na.rm=TRUE)),lwd=1,col=0) sigex.graph(extract.trendgr,NULL,begin.date,period,i,0,trendcol,fade) }
grid <- 70000 # need large grid value to get accuracy window <- 100 horizon <- 0 gr.array <- array(t(gr.poly) %x% diag(N),c(N,N,p+1)) reg.gr <- array(0,c(T,N)) for(k in 1:N) { reg.gr[,k] <- stats::filter(reg.trend[,k],gr.poly, method="convolution",sides=1) }
extract.trendgr2 <- sigex.wkextract(psi,mdl,data.ts,1,gr.array, grid,window,horizon,TRUE) par(mfrow=c(2,2)) for(i in 1:N) { plot(data.ts[,i],xlab="Year",ylab="", ylim=c(min(extract.trendgr2[[3]][,i]+reg.gr[,i],na.rm=TRUE), max(extract.trendgr2[[2]][,i]+reg.gr[,i],na.rm=TRUE)),lwd=1,col=0) sigex.graph(extract.trendgr2,reg.gr,begin.date,period,i,0,trendcol,fade) }
extract.sagr2 <- sigex.wkextract(psi,mdl,data.ts,c(1,8),gr.array, grid,window,horizon,TRUE) par(mfrow=c(2,2)) for(i in 1:N) { plot(data.ts[,i],xlab="Year",ylab="", ylim=c(min(extract.sagr2[[3]][,i]+reg.gr[,i],na.rm=TRUE), max(extract.sagr2[[2]][,i]+reg.gr[,i],na.rm=TRUE)),lwd=1,col=0) sigex.graph(extract.sagr2,reg.gr,begin.date,period,i,0,sacol,fade) }
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.