{rstan} で 「状態空間時系列分析入門」 を再現したい。やっていること / 数式はテキストを参照。
リポジトリ: https://github.com/sinhrks/stan-statespace
library(devtools)
# devtools::install_github('hoxo-m/pforeach')
# devtools::install_github('sinhrks/ggfortify')
library(rstan)
library(pforeach)
library(ggplot2)
ggplot2::theme_set(theme_bw(base_family="HiraKakuProN-W3"))
library(ggfortify)
# モデルが収束しているか確認
is.converged <- function(stanfit) {
summarized <- summary(stanfit)
all(summarized$summary[, 'Rhat'] < 1.1)
}
# 値がだいたい近いか確認
is.almost.fitted <- function(result, expected, tolerance = 0.001) {
if (abs(result - expected) > tolerance) {
print(paste('Result is ', result))
return(FALSE)
} else {
return(TRUE)
}
}
ukdrivers <- read.table('../data/UKdriversKSI.txt', skip = 1)
ukdrivers <- ts(ukdrivers[[1]], start = c(1969, 1), frequency = 12)
ukdrivers <- log(ukdrivers)
確定的ローカルレベルモデル。
model_file <- '../models/fig02_01.stan'
cat(paste(readLines(model_file)), sep = '\n')
data {
int<lower=1> n;
vector[n] y;
}
parameters {
# 確定的レベル
real mu;
# 撹乱項
real<lower=0> sigma;
}
model {
y ~ normal(mu, sigma);
}
y <- ukdrivers
standata <- within(list(), {
y <- as.vector(y)
n <- length(y)
})
stan_fit <- stan(file = model_file, chains = 0)
##
## TRANSLATING MODEL 'fig02_01' FROM Stan CODE TO C++ CODE NOW.
## COMPILING THE C++ CODE FOR MODEL 'fig02_01' NOW.
fit <- pforeach(i = 1:4, .final = sflist2stanfit)({
stan(fit = stan_fit, data = standata,
iter = 2000, chains = 1, seed = i)
})
stopifnot(is.converged(fit))
mu <- get_posterior_mean(fit, par = 'mu')[, 'mean-all chains']
title <- 'Figure 2.1. Deterministic level.'
title <- '図 2.1 確定的レベル'
# 原系列
p <- autoplot(y)
# stan
p <- p + geom_hline(yintercept = mu, colour = 'blue')
# 通常の計算結果
p <- p + geom_hline(yintercept = mean(y),
colour = 'red', linetype = 'dashed')
p + ggtitle(title)
title <- 'Figure 2.2. Irregular component for deterministic level model.'
title <- '図 2.2 確定的レベルに対する不規則要素'
autoplot(y - mu, ts.linetype = 'dashed') + ggtitle(title)