Неэффективная выборка простой биномиальной GLM с использованием rstan MCMC

Я пытаюсь подогнать биномиальный GLM с помощью пакета rethinking (опирается на rstan MCMC).

Модель подходит, но выборка неэффективна, и Рат указывает на то, что что-то пошло не так. Я не понимаю причину этой проблемы с подгонкой.

Это данные:

d <- read_csv("https://gist.githubusercontent.com/sebastiansauer/a2519de39da49d70c4a9e7a10191cb97/raw/election.csv")
d <- as.data.frame(dummy)

Это модель:

m1_stan <- map2stan( 
 alist(
    afd_votes ~ dbinom(votes_total, p),
    logit(p) <- beta0 + beta1*foreigner_n,
    beta0 ~ dnorm(0, 10),
    beta1 ~ dnorm(0, 10)
  ),
  data = d, 
  WAIC = FALSE,
  iter = 1000)

Диагностика соответствия (Rhat, количество эффективных образцов) указывает на то, что что-то пошло не так:

      Mean StdDev lower 0.89 upper 0.89 n_eff Rhat
beta0 -3.75      0      -3.75      -3.75     3 2.21
beta1  0.00      0       0.00       0.00    10 1.25

На графике не показана «толстая волосатая гусеница»:

traceplot m0_stan

В стандартном выводе предлагалось увеличить два параметра, adapt_delta и max_treedepth, что я и сделал. Это несколько улучшило процесс выборки:

      Mean StdDev lower 0.89 upper 0.89 n_eff Rhat
beta0 18.1   0.09      18.11      18.16    28 1.06
beta1  0.0   0.00       0.00       0.00    28 1.06

Но, как показывает график трассировки, что-то все еще не так:  traceplot2

Странно выглядит и парный сюжет:

парный сюжет

Что еще пробовал:

  • Я центрировал / z-стандартизовал предиктор (выдал эту ошибку: «« Ошибка в сэмплере $ call_sampler (args_list [[i]]): Инициализация не удалась. »)
  • Я пробовал нормальную модель (но это подсчет данных)
  • Проверил, что промахов нет (их нет)
  • Увеличил количество итераций до 4000, улучшения нет
  • Увеличил sd приоры (модели влезают годами)

Но пока ничего не помогло. В чем может быть причина неэффективной примерки? Что я мог попробовать?

Может ли быть проблемой большое количество подсчетов в каждом?

 mean(d_short$afd_votes)
[1] 19655.83

Отрывок из данных:

 head(d)
  afd_votes votes_total foreigner_n
1     11647      170396       16100
2      9023      138075       12600
3     11176      130875       11000
4     11578      156268        9299
5     10390      150173       25099
6     11161      130514       13000

информация о сеансе:

sessionInfo()
R version 3.5.0 (2018-04-23)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS High Sierra 10.13.6

Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] parallel  stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] viridis_0.5.1      viridisLite_0.3.0  sjmisc_2.7.3       pradadata_0.1.3    rethinking_1.59    rstan_2.17.3       StanHeaders_2.17.2 forcats_0.3.0      stringr_1.3.1     
[10] dplyr_0.7.6        purrr_0.2.5        readr_1.1.1        tidyr_0.8.1        tibble_1.4.2       ggplot2_3.0.0      tidyverse_1.2.1   

loaded via a namespace (and not attached):
 [1] httr_1.3.1         jsonlite_1.5       modelr_0.1.2       assertthat_0.2.0   stats4_3.5.0       cellranger_1.1.0   yaml_2.1.19        pillar_1.3.0       backports_1.1.2   
[10] lattice_0.20-35    glue_1.3.0         digest_0.6.15      rvest_0.3.2        snakecase_0.9.1    colorspace_1.3-2   htmltools_0.3.6    plyr_1.8.4         pkgconfig_2.0.1   
[19] broom_0.5.0        haven_1.1.2        bookdown_0.7       mvtnorm_1.0-8      scales_0.5.0       stringdist_0.9.5.1 sjlabelled_1.0.12  withr_2.1.2        RcppTOML_0.1.3    
[28] lazyeval_0.2.1     cli_1.0.0          magrittr_1.5       crayon_1.3.4       readxl_1.1.0       evaluate_0.11      nlme_3.1-137       MASS_7.3-50        xml2_1.2.0        
[37] blogdown_0.8       tools_3.5.0        loo_2.0.0          data.table_1.11.4  hms_0.4.2          matrixStats_0.54.0 munsell_0.5.0      prediction_0.3.6   bindrcpp_0.2.2    
[46] compiler_3.5.0     rlang_0.2.1        grid_3.5.0         rstudioapi_0.7     labeling_0.3       rmarkdown_1.10     gtable_0.2.0       codetools_0.2-15   inline_0.3.15     
[55] curl_3.2           R6_2.2.2           gridExtra_2.3      lubridate_1.7.4    knitr_1.20         bindr_0.1.1        rprojroot_1.3-2    KernSmooth_2.23-15 stringi_1.2.4     
[64] Rcpp_0.12.18       tidyselect_0.2.4   xfun_0.3           coda_0.19-1       

person Sebastian Sauer    schedule 31.08.2018    source источник


Ответы (1)


STAN лучше справляется с единичным масштабом, некоррелированными параметрами. Из руководства STAN, §28.4 Моделирование условий и кривизны:

В идеале все параметры должны быть запрограммированы так, чтобы они имели единичный масштаб и чтобы уменьшалась апостериорная корреляция; Вместе эти свойства означают, что для оптимальной производительности алгоритмов Стэна не требуется вращения или масштабирования. Для гамильтониана Монте-Карло это подразумевает матрицу единичных масс, которая не требует адаптации, поскольку именно там инициализируется алгоритм. Риманов гамильтониан Монте-Карло выполняет это согласование на лету на каждом шаге, но такое согласование требует больших вычислительных ресурсов.

В вашем случае beta1 привязан к foreigner_n, у которого нет шкалы единиц, и поэтому он несбалансирован по сравнению с beta0. Кроме того, поскольку foreigner_n не центрирован, обе бета-версии изменяют положение p во время выборки, отсюда и апостериорная корреляция.

Стандартизация дает более управляемую модель. Преобразование foreigner_n в центрирование и единичный масштаб позволяет модели быстро сходиться и дает высокие эффективные размеры выборки. Я также утверждаю, что бета-версии в этой форме более интерпретируемы, поскольку beta0 фокусируется только на местонахождении p, а beta1 касается только того, как вариация в foreigner_n объясняет вариацию в afd_votes/total_votes.

library(readr)
library(rethinking)

d <- read_csv("https://gist.githubusercontent.com/sebastiansauer/a2519de39da49d70c4a9e7a10191cb97/raw/election.csv")
d <- as.data.frame(d)
d$foreigner_z <- scale(d$foreigner_n)

m1 <- alist(
  afd_votes ~ dbinom(votes_total, p),
  logit(p) <- beta0 + beta1*foreigner_z,
  c(beta0, beta1) ~ dnorm(0, 1)
)

m1_stan <- map2stan(m1, data = d, WAIC = FALSE,
                    iter = 10000, chains = 4, cores = 4)

Рассматривая выборку, имеем

> summary(m1_stan)
Inference for Stan model: afd_votes ~ dbinom(votes_total, p). 
4 chains, each with iter=10000; warmup=5000; thin=1;  
post-warmup draws per chain=5000, total post-warmup draws=20000.

              mean se_mean   sd         2.5%          25%          50%          75%        97.5% n_eff Rhat 
beta0        -1.95    0.00 0.00        -1.95        -1.95        -1.95        -1.95        -1.95 16352    1 
beta1        -0.24    0.00 0.00        -0.24        -0.24        -0.24        -0.24        -0.24 13456    1 
dev      861952.93    0.02 1.97    861950.98    861951.50    861952.32    861953.73    861958.26  9348    1 
lp__  -17523871.11    0.01 0.99 -17523873.77 -17523871.51 -17523870.80 -17523870.39 -17523870.13  9348    1

Samples were drawn using NUTS(diag_e) at Sat Sep  1 11:48:55 2018.
For each parameter, n_eff is a crude measure of effective sample size, 
and Rhat is the potential scale reduction factor on split chains (at
convergence, Rhat=1).

И глядя на график пар, мы видим, что корреляция между бета-версиями снижена до 0,15:

введите описание изображения здесь


Дополнительный анализ

Первоначально я интуитивно догадывался, что нецентрированность foreigner_n была главной проблемой. В то же время я был немного сбит с толку, потому что STAN использует HMC / NUTS, которые, как мне кажется, должны быть довольно устойчивыми к коррелированным скрытым переменным. Однако я заметил в руководстве STAN комментарии о практических проблемах масштабной инвариантности из-за числовой нестабильности, которые также прокомментировал Майкл Бетанкур. в ответе CrossValidated (хотя это довольно старый пост). Итак, я хотел проверить, что больше всего повлияло на улучшение выборки - центрирование или масштабирование.

Центрирование в одиночестве

Центрирование по-прежнему приводит к довольно низкой производительности. Обратите внимание, что эффективный размер выборки - это буквально одна эффективная выборка на цепочку.

library(readr)
library(rethinking)

d <- read_csv("https://gist.githubusercontent.com/sebastiansauer/a2519de39da49d70c4a9e7a10191cb97/raw/election.csv")
d <- as.data.frame(d)
d$foreigner_c <- d$foreigner_n - mean(d$foreigner_n)

m2 <- alist(
  afd_votes ~ dbinom(votes_total, p),
  logit(p) <- beta0 + beta1*foreigner_c,
  c(beta0, beta1) ~ dnorm(0, 1)
)

m2_stan <- map2stan(m2, data = d, WAIC = FALSE,
                    iter = 10000, chains = 4, cores = 4)

что дает

Inference for Stan model: afd_votes ~ dbinom(votes_total, p).
4 chains, each with iter=10000; warmup=5000; thin=1; 
post-warmup draws per chain=5000, total post-warmup draws=20000.

              mean   se_mean          sd         2.5%          25%          50%         75%        97.5% n_eff Rhat
beta0        -0.64       0.4        0.75        -1.95        -1.29        -0.54         0.2         0.42     4 2.34
beta1         0.00       0.0        0.00         0.00         0.00         0.00         0.0         0.00     4 2.35
dev    18311608.99 8859262.1 17270228.21    861951.86   3379501.84  14661443.24  37563992.4  46468786.08     4 1.75
lp__  -26248697.70 4429630.9  8635113.76 -40327285.85 -35874888.93 -24423614.49 -18782644.5 -17523870.54     4 1.75

Samples were drawn using NUTS(diag_e) at Sun Sep  2 18:59:52 2018.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).

И все же, похоже, есть проблемный парный сюжет:

введите описание изображения здесь

Масштабирование в одиночку

Масштабирование значительно улучшает выборку! Несмотря на то, что полученные апостериорные данные все еще имеют довольно высокую корреляцию, эффективные размеры выборки находятся в приемлемых диапазонах, хотя и значительно ниже, чем при полной стандартизации.

library(readr)
library(rethinking)

d <- read_csv("https://gist.githubusercontent.com/sebastiansauer/a2519de39da49d70c4a9e7a10191cb97/raw/election.csv")
d <- as.data.frame(d)
d$foreigner_s <- d$foreigner_n / sd(d$foreigner_n)

m3 <- alist(
  afd_votes ~ dbinom(votes_total, p),
  logit(p) <- beta0 + beta1*foreigner_s,
  c(beta0, beta1) ~ dnorm(0, 1)
)

m3_stan <- map2stan(m2, data = d, WAIC = FALSE,
                    iter = 10000, chains = 4, cores = 4)

уступающий

Inference for Stan model: afd_votes ~ dbinom(votes_total, p).
4 chains, each with iter=10000; warmup=5000; thin=1; 
post-warmup draws per chain=5000, total post-warmup draws=20000.

              mean se_mean   sd         2.5%          25%          50%          75%        97.5% n_eff Rhat
beta0        -1.58    0.00 0.00        -1.58        -1.58        -1.58        -1.58        -1.57  5147    1
beta1        -0.24    0.00 0.00        -0.24        -0.24        -0.24        -0.24        -0.24  5615    1
dev      861952.93    0.03 2.01    861950.98    861951.50    861952.31    861953.69    861958.31  5593    1
lp__  -17523870.45    0.01 1.00 -17523873.15 -17523870.83 -17523870.14 -17523869.74 -17523869.48  5591    1

Samples were drawn using NUTS(diag_e) at Sun Sep  2 19:02:00 2018.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).

График пар показывает, что все еще существует значимая корреляция:

введите описание изображения здесь

Следовательно, хотя декорреляция переменных действительно улучшает выборку, устранение масштабного дисбаланса является наиболее важным в этой модели.

person merv    schedule 01.09.2018
comment
Спасибо, я не понимал, что даже корреляция предсказателя с распределением перехвата может быть проблемой. - person Sebastian Sauer; 01.09.2018
comment
@SebastianSauer Я был неправ, утверждая, что центрирование было основной проблемой, мешающей вашей выборке. Оказывается, в основном это был дисбаланс масштабов между переменными, который, по-видимому, может быть серьезной проблемой в HMC / NUTS. Так что я тоже кое-что узнал! Ответ дополнен деталями. - person merv; 03.09.2018
comment
Еще раз спасибо, что насчет обоих (т.е. z-трансформации)? Может быть лучшим из обоих миров. - person Sebastian Sauer; 03.09.2018
comment
@SebastianSauer: да, стандартизация / z-преобразование - это первая модель в ответе (это то, что делает функция scale), и она производит выборку наиболее эффективно. - person merv; 03.09.2018