Я пытаюсь настроить марковскую модель с нулевым завышением Пуассона, скрытой от Стэна. Для Poisson-HMM на прошлом форуме эта настройка была показана. см. ссылку.
В то время как для настройки ZIP с классическая теория хорошо документирована кодом и моделью.
ziphsmm
library(ziphsmm)
set.seed(123)
prior_init <- c(0.5,0.5)
emit_init <- c(20,6)
zero_init <- c(0.5,0)
tpm <- matrix(c(0.9, 0.1, 0.2, 0.8),2,2,byrow=TRUE)
result <- hmmsim(n=100,M=2,prior=prior_init, tpm_parm=tpm,emit_parm=emit_init,zeroprop=zero_init)
y <- result$series
serie <- data.frame(y = result$series, m = result$state)
fit1 <- fasthmmfit(y,x=NULL,ntimes=NULL,M=2,prior_init,tpm,
emit_init,0.5, hessian=FALSE,method="BFGS",
control=list(trace=1))
fit1
$prior
[,1]
[1,] 0.997497445
[2,] 0.002502555
$tpm
[,1] [,2]
[1,] 0.9264945 0.07350553
[2,] 0.3303533 0.66964673
$zeroprop
[1] 0.6342182
$emit
[,1]
[1,] 20.384688
[2,] 7.365498
$working_parm
[1] -5.9879373 -2.5340475 0.7065877 0.5503559 3.0147840 1.9968067
$negloglik
[1] 208.823
Stan
library(rstan)
ZIPHMM <- 'data {
int<lower=0> N;
int<lower=0> y[N];
int<lower=1> m;
}
parameters {
real<lower=0, upper=1> theta; //
positive_ordered[m] lambda; //
simplex[m] Gamma[m]; // tpm
}
model {
vector[m] log_Gamma_tr[m];
vector[m] lp;
vector[m] lp_p1;
// priors
lambda ~ gamma(0.1,0.01);
theta ~ beta(0.05, 0.05);
// transposing tpm and taking the log of each entry
for(i in 1:m)
for(j in 1:m)
log_Gamma_tr[j, i] = log(Gamma[i, j]);
lp = rep_vector(-log(m), m); //
for(n in 1:N) {
for(j in 1:m){
if (y[n] == 0)
lp_p1[j] = log_sum_exp(log_Gamma_tr[j] + lp) +
log_sum_exp(bernoulli_lpmf(1 | theta),
bernoulli_lpmf(0 | theta) + poisson_lpmf(y[n] | lambda[j]));
else
lp_p1[j] = log_sum_exp(log_Gamma_tr[j] + lp) +
bernoulli_lpmf(0 | theta) +
poisson_lpmf(y[n] | lambda[j]);
}
lp = lp_p1;
}
target += log_sum_exp(lp);
}'
mod_ZIP <- stan(model_code = ZIPHMM, data=list(N=length(y), y=y, m=2), iter=1000, chains=1)
print(mod_ZIP,digits_summary = 3)
mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat
theta 0.518 0.002 0.052 0.417 0.484 0.518 0.554 0.621 568 0.998
lambda[1] 7.620 0.039 0.787 6.190 7.038 7.619 8.194 9.132 404 1.005
lambda[2] 20.544 0.039 0.957 18.861 19.891 20.500 21.189 22.611 614 1.005
Gamma[1,1] 0.664 0.004 0.094 0.473 0.604 0.669 0.730 0.841 541 0.998
Gamma[1,2] 0.336 0.004 0.094 0.159 0.270 0.331 0.396 0.527 541 0.998
Gamma[2,1] 0.163 0.003 0.066 0.057 0.114 0.159 0.201 0.312 522 0.999
Gamma[2,2] 0.837 0.003 0.066 0.688 0.799 0.841 0.886 0.943 522 0.999
lp__ -222.870 0.133 1.683 -227.154 -223.760 -222.469 -221.691 -220.689 161 0.999
True values
real = list(tpm = tpm,
zeroprop = nrow(serie[serie$m == 1 & serie$y == 0, ]) / nrow(serie[serie$m == 1,]),
emit = t(t(tapply(serie$y[serie$y != 0],serie$m[serie$y != 0], mean))))
real
$tpm
[,1] [,2]
[1,] 0.9 0.1
[2,] 0.2 0.8
$zeroprop
[1] 0.6341463
$emit
[,1]
1 20.433333
2 7.277778
Оценки дают довольно странно, чтобы кто-то мог помочь мне понять, что я делаю неправильно. Как мы видим, оценки stan zeroprop = 0,518, тогда как реальное значение равно 0,634, с другой стороны, значения t.p.m. в стане они довольно далеки и средние значения лямбда1 = 7,62 и лямбда2 = 20,54, хотя они достаточно приближены, дали в другом порядке реальные 20,43 и 7,27. Я думаю, что делаю какую-то ошибку в определении модели в Стэне, но я не знаю, какую.
theta
= 0,518 и реальным 0,634, то же самое для значений матрицы перехода. Также среднее значенийlambda1
= 7,62 иlambda2
= 20,54, а действительныеlambda1
= 20,43 иlambda2
= 7,27. То есть они пересекаются. - person Rafael Díaz   schedule 19.02.2019theta
похоже на то, что оно возникает из-за того, чтоfasthmmfit
налагает нулевую инфляцию только на первое состояние, тогда как способ, которым вы закодировали модель Стэна, применяет нулевую инфляцию на обоих состояниях. Априор, который вы навязываетеtheta
, является бимодальным, что обычно трудно подобрать. Вы пробовали плоскую приору наtheta
и навязывали ее только одному штату? - person merv   schedule 19.02.2019zeroprop
равно 0,5. Вам нужна модель, которая лучше всего восстанавливает истинные параметры HMM, или вам нужна точная повторная реализация этой оценки MAP на основе SGD, но с использованием Стэна? Если последнее, тоrstan::optimizing
используется для оценок MAP. Кроме того, вам, вероятно, не следует инициализироватьfasthmmfit
с истинными параметрами, если вы хотите получить реалистичную характеристику его поведения. - person merv   schedule 20.02.2019