井出草平の研究ノート

RandomLCAパッケージを用いた潜在クラス分析とBLRT[R]

Rで潜在クラス分析をするパッケージとしてはpoLCAが有名だが、RandomLCAでも潜在クラス分析ができる。 poLCAではブートストラップ尤度比検定(Bootstrapped Likelihood Ratio Test: BLRT)ができないが、RandomLCAではできるらしい。

cran.r-project.org

RandomLCAの特徴

RandomLCAは1) スタンダードな潜在クラス分析 2)シングルレベルランダム効果モデル 3)2レベルランダム効果モデル3つが使用できる。

ちなみにこのパッケージの作者はBeath自身である。 RandomLCAは他の統計パッケージではできない解析ができるようだ。

ランダム効果モデルの話はまたの機会にするとして、今回はとりあえず、スタンダードな潜在クラス分析を行ってみたい。

データの特徴

RandomLCAで利用するデータの形式は私たちが普段使っている形式とは異なっている。サンプルデータのHIV testing dataを例にとろう。

f:id:iDES:20191119174243p:plain

V1~V4までの0/1のパターンは2の4乗なので16通りあり、右側にその条件を満たす頻度が書かれている。もともとは潜在クラス分析の計算はこの形式にしてから計算をするので、慣れない感じはあるが、こちらのデータセット形式の方が正統的ではある。このブログでは一度も言及したことはずだが、統計パッケージのLEMもこのような形式のデータセットを用いる。

潜在クラス分析

サンプルデータとして利用するのはHandelman et al. (1986)の歯のX線データである。 1-5行目が変数であり、6行目はfreqという頻度のデータである。

library(randomLCA)
data(dentistry) 
dentistry.lca2 <- randomLCA(dentistry[,1:5],freq=dentistry$freq,nclass=2)
summary(dentistry.lca2)

結果は次のようになる。

  Classes      AIC      BIC     AIC3    logLik penlogLik
        2 14952.77 15021.64 14963.77 -7465.385 -7465.446
Class probabilities 
Class  1 Class  2 
  0.1961   0.8039 
Outcome probabilities 
             V1     V2     V3     V4     V5
Class  1 0.4034 0.7129 0.5981 0.4888 0.9155
Class  2 0.0106 0.1020 0.0136 0.0316 0.3053

BLRT

BLRTは下記のように実施する。 今回は2クラスモデルと3クラスモデルを比較する。

dentistry.lca2 <- randomLCA(dentistry[,1:5],freq=dentistry$freq,nclass=2) # 2クラスモデル
dentistry.lca3 <- randomLCA(dentistry[,1:5],freq=dentistry$freq,nclass=3) # 3クラスモデル
obslrt <- 2*(logLik(dentistry.lca3)-logLik(dentistry.lca2)) # 3クラス、2クラスモデルの対数尤度の差の二乗
print(obslrt)

Printはこの出力は、観察された(ブートストラップでシミュレーションされたものではない)実際の対数尤度の差の二乗である。この値はP値を求める際に使用する。

'log Lik.' 108.3152 (df=17)

BLRTは下記の次のように行う。

nsims <- 999 # ブートストラップの回数を指定
thesims <- simulate(dentistry.lca2, nsims) # シミュレーションを作成
simlrt <- rep(NA,nsims) 
for (isim in 1:nsims) {
submodel <- refit(dentistry.lca2,newpatterns=thesims[[isim]]) # submodelは比較対象の2クラスモデル
fullmodel <- refit(dentistry.lca3,newpatterns=thesims[[isim]]) # fullmodelは3クラスモデル
simlrt[isim] <- 2*(logLik(fullmodel)-logLik(submodel)) # 2つのモデルの尤度の差を二乗
}

P値はシミュレートされたLRTが実際のLRTより大きい割合である。1は修正値である。

print((sum(simlrt>=obslrt)+1)/(nsims+1)) # P値の計算

結果は下記のようになる。

0.001

P値が有意であった場合、2クラスモデルから3クラスモデルにしてモデルが改善した、つまり2ではなく3クラスモデルが支持されるという解釈を行う。

課題と考察

P値の計算式の分母に反復回数であるnsimsが入っているので、P値を細かく出そうとすると反復回数はそこそこ大きい数字の方が求められる。小数点3桁でP値を表示するには999+1回の反復が必要である。

この例ではシミュレートされたLRTが実際のLRTより大きかった回数(sum(simlrt>=obslrt)+1)は1回もないので値は0である。Rでsum(simlrt>=obslrt)+1と打って返されるのは0であることで確認できる。そこに修正値の1を足しているので分子は1である。

反復回数が9回だった場合、このモデル比較だと、P値は0+1/(9+1)であり、0.1、つまり10%となる。頻度主義は5%以下をだいたいの場合は有意とするので、モデルの改善がないと判断される。つまり、BLRTでは反復回数は完全に自由に決めてよいというわけではないのだ。

修正値が1の場合は反復回数は少なくとも20回ないと5%有意にならない。20回というのは分子が0(クラス数の増加によつて明らかにモデル改善がある場合)だけであって、ぎりぎりの数値であり、実際には20回というのは少なすぎる。

修正値を0.1にすると、反復回数は100回で小数点3桁のP値が得られる。修正値は分子・分母(特に分母)を0にしないために入れられるものなので、1である必要はないのかもしれない。0.1であってもよさそうに思える。ブートストラップの反復回数と修正値は連動しているというのは少なくとも間違いないだろう。修正値として何が適切なのかを知るには、BLRTについてちゃんと勉強しないといけないようである。

潜在クラス分析のエントロピーの計算[R]

RのpoLCAパッケージで潜在クラス分析のエントロピーを計算してみたい。

相対的エントロピーと絶対的エントロピー

エントロピーという指標はMplusユーザーにとってはお馴染みのものである。
Mplusで出力されるのは正確に言うと、相対的エントロピー(Relative Entropy)と呼ばれるものである。RのpoLCAパッケージでもエントロピーが出力できるが、絶対的エントロピーであって、相対的エントロピーとは異なったものだ。

相対的エントロピーの文献はRamaswamyらの論文であろうか。

Ramaswamy et al. 1993, "An Empirical Pooling Approach for Estimating Marketing Mix Elasticities with PIMS Data"

相対化エントロピーは最小値が0で1が最大値である。1に近い方がクラスの分類が正確だとされている。
相対化エントロピーの値は0.7以上で十分、0.8以上で良好な分類だと言われている。
Ramaswamyらの論文ではこの基準が書かれているかというと、似たような記述はあるが、決して基準の提唱をしているわけではない。Mplusの作者Muthen & MuthenがMplusのマニュアルで0.8以上の推奨をしていることが確認できた。

下記の本の304頁には0.7以上で十分、0.8以上で良好という記述がある。

International Perspectives on Teacher Knowledge, Beliefs and Opportunities to Learn: TEDS-M Results (Advances in Mathematics Education)

International Perspectives on Teacher Knowledge, Beliefs and Opportunities to Learn: TEDS-M Results (Advances in Mathematics Education)

該当の論文はResearch Gateにある。

Sigrid Blömeke and Gabriele Kaiser - Homogeneity or Heterogeneity? Profiles of Opportunities to Learn in Primary Teacher Education and Their Relationship to Cultural Context and Outcomes

本来は異なったクラス数のモデル間で、相対化していないエントロピーを比較するのが正しい使い方なのではないかと思うが、標準化してもこの機能は果たせるので、相対化エントロピーでも問題はない。ただ、0.7以上といった基準は個人的にはあまりどうでもいい気がする。この議論は相関係数がどの程度あれば強い相関なのか、といった議論と同種のものであるからだ。

絶対的エントロピーの計算

潜在クラス分析は先のエントリーで使用したものを利用する。先のエントリでは共変量を設定しているが下記のスクリプトでは共変量のないノーマルな潜在クラス分析を行っている。

library("poLCA")
data("election",package="poLCA") # electionデータ読み込み
election$GENDER <- factor(election$GENDER) # 因子型にする
d1 <- election[,c(1:3,7:12,16:17)] # 道徳性・思いやり・知識が豊富のゴア、ブッシュの値、性別、政党を抜き出し
d1 <- na.omit(d1) # 欠損値除去
fm <- cbind(MORALG,CARESG,KNOWG,MORALB,CARESB,KNOWB)~1 # 式formulaの作成
res3 <- poLCA(formula=fm,data=d1,nclass=3,nrep=10) # 潜在クラス分析の実行
poLCA.entropy(res3) # エントロピーの計算

エントロピーは6.62と計算される。

6.621753

この関数でエラーが出るという報告がある(こちら)。僕の環境ではエラーは出ていないので、特に問題ないのだが、エラーが出る人もいるのだろうか。

その代わりに次のような手計算の式が書かれてあるのだが、僕の場合はこちらの計算でエラーが出た。

poLCA.entropy.fix <- function (lc)
{
 K.j <- sapply(lc$probs, ncol)
 fullcell <- expand.grid(sapply(K.j, seq, from = 1))
 P.c <- poLCA.predcell(lc, fullcell)
 return(-sum(P.c * log(P.c), na.rm = TRUE))
}
poLCA.entropy.fix(lca.polca)
[1] 3.602397

相対的エントロピーの計算

RのpoLCAは相対的エントロピーの計算はしてくれないので、自力で行う必要がある。自力といっても、潜在クラス分析の結果はもちろん使って行うので、先に潜在クラス分析の計算はしなくてはならない。下のスクリプトこちらを参考にした。

n <- 1346 # サンプルサイズ
K <- 3 #クラス数
nume.E <- -sum(res3$posterior * log(res3$posterior)) # 分子
deno.E <- n*log(K) #分母
Entro <- 1-(nume.E/deno.E)
Entro

結果は以下のようになる。

0.7329062

他の計算法としては、Daniel Oberskiが提案しているものがある(PDF)。

entropy <- function (p) sum(-p*log(p))
error_prior <- entropy(res3$P) # クラス割合
error_post <- mean(apply(res3$posterior, 1, entropy))
R2_entropy <- (error_prior - error_post) / error_prior
R2_entropy

共変量を伴った潜在クラス分析[R]

Rで共変量を伴った潜在クラス分析を行ってみたい。
パッケージはpoLCAを使う。

poLCAパッケージを利用した潜在クラス分析は以前にエントリしている。
RのpoLCAパッケージで潜在クラス分析を行う

共変量とは何かというのは、以前にMplusでの方法をエントリしているのでそちらを参照のこと。
Mplus 共変量を伴った潜在クラス分析

パッケージを読み込む。

library("poLCA")

データはpoLCAパッケージに含まれるelectionデータを利用する。 2000年のアメリカ大統領選挙アル・ゴアジョージ・W・ブッシュの評価のデータである。

下記の6点について4段階で評価している。

  1. 道徳性 moral
  2. 思いやり caring
  3. 知識が豊富 knowledgeable
  4. 良いリーダー good leader
  5. 正直ではない dishonest、
  6. 知的 intelligent

他の変数としては以下のものが含まれる。

  • 投票 VOTE3:(1) ゴア (2) ブッシュ (3) その他
  • 年齢 AGE: 連続変数
  • 教育 EDUC (1)第8学年以下 (2)9-11年生(3)高校卒業または同等(4)12年以上の学校教育(5)ジュニアまたはコミュニティカレッジレベルの学位 (6)学士レベルの学位 (7)高度な学位
  • 性別 GENDER:(1)男性 (2)女性
  • 政党 PARTY:(1)強い民主党員(2)弱い民主党員 (3)所属の無い民主党員 (4)支持政党なし(5)所属の無い共和党員 (6)弱い共和党員 (7)強い共和党

VOTE3を用いれば、抹消結果Distal Outcomesを伴った潜在クラス分析もできるデータのようだ。

少しデータが多いので、分析するデータを編集。

data("election",package="poLCA") # electionデータ読み込み
election$GENDER <- factor(election$GENDER) # 因子型にする
## 道徳性・思いやり・知識が豊富のゴア、ブッシュの値、年齢、教育、性別、政党を抜き出し
d1 <- election[,c(1:3,7:12,14:17)]
d1 <- na.omit(d1) # 欠損値除去

共変量を伴った潜在クラス分析

共変量は式の最後のチルダの後につける。
ノーマルな潜在クラス分析だとここに~1と表記するが、そこに共変量を設定することになる。 クラス数は3で走らせる。

fm1 <- cbind(MORALG,CARESG,KNOWG,MORALB,CARESB,KNOWB)~PARTY # 式formulaの作成
res1 <- poLCA(formula=fm1,data=d1,nclass=3,nrep=10) # 潜在クラス分析の実行

僕の環境ではRStudioのR Markdownからは出力ができず、コンソールからのみ共変量の結果は出力できた。
それにしても、よく起こるバグである。

共変量のところのみ結果を表示する。

========================================================= 
Fit for 3 latent classes: 
========================================================= 
2 / 1 
            Coefficient  Std. error  t value  Pr(>|t|)
(Intercept)     2.44815     0.21781   11.240         0
PARTY          -0.74290     0.06139  -12.101         0
========================================================= 
3 / 1 
            Coefficient  Std. error  t value  Pr(>|t|)
(Intercept)    -3.88769     0.47323   -8.215         0
PARTY           0.66537     0.08135    8.179         0
========================================================= 

p値は0である。ゴアとブッシュへの評価が潜在クラスの中身なので、政党支持が関連を持っているのは明らかだろう。
参照カテゴリは1である。参照カテゴリを変更させるコマンドは探してみたがなかった。変更できないと少し不便だ。

2つ以上の共変量を伴った潜在クラス分析

2つ以上の共変量を設定するときは単純に+をいれるとよい。

fm2 <- cbind(MORALG,CARESG,KNOWG,MORALB,CARESB,KNOWB)~PARTY+AGE+EDUC # 式の作成
res2 <- poLCA(formula=fm2,data=d1,nclass=3,nrep=10) # 潜在クラス分析の実行

今回も共変量のところのみ結果を表示する。

========================================================= 
Fit for 3 latent classes: 
========================================================= 
2 / 1 
            Coefficient  Std. error  t value  Pr(>|t|)
(Intercept)     4.38411     0.65075    6.737     0.000
PARTY          -1.59906     0.10977  -14.567     0.000
AGE             0.00910     0.00825    1.102     0.270
EDUC            0.27591     0.08981    3.072     0.002
========================================================= 
3 / 1 
            Coefficient  Std. error  t value  Pr(>|t|)
(Intercept)     5.02711     0.58119    8.650     0.000
PARTY          -0.99110     0.09064  -10.935     0.000
AGE            -0.02268     0.00714   -3.179     0.002
EDUC            0.16649     0.07637    2.180     0.029
========================================================= 

潜在クラス分析の応答確率の棒グラフ[Stata]

Stataでは潜在クラス分析の応答確率の棒グラフが描ける。棒グラフというのは今まで見たことがなかった。不要な気もしないでもないが、説明するときにわかりやすいのかもしれない。

使用するのはmarginsmarginsplotである。説明によると条件付き応答確率の関数であるestat lcmeanmarginsのラッパーらしい。ちなみにestat lcmean前のエントリで応答確率を計算するときに使ったコマンドである。

前のエントリで計算はしているが、一応今回も同じ潜在クラス分析のモデルを作っておこう。

. use http://www.stata-press.com/data/r16/gsem_lca1.dta, clear
. gsem (accident play insurance stock <- ), logit lclass(C 2)

前回のフィッテング指標の結果2クラスの方が良かったので、今回は2クラスのモデルで計算してある。プロットは下記のように記述する。

. margins, predict(outcome(accident) class(1)) ///
predict(outcome(play) class(1)) ///
predict(outcome(insurance) class(1)) ///
predict(outcome(stock) class(1))

. marginsplot, recast(bar) title("Class 1") xtitle("") ///
xlabel(1 "accident" 2 "play" 3 "insurance" 4 "stock", angle(45)) ///
ytitle("Predicted mean") ylabel(0(0.1)1) name(class1)


. margins, predict(outcome(accident) class(2)) ///
predict(outcome(play) class(2)) ///
predict(outcome(insurance) class(2)) ///
predict(outcome(stock) class(2))

. marginsplot, recast(bar) title("Class 2") xtitle("") ///
xlabel(1 "accident" 2 "play" 3 "insurance" 4 "stock", angle(45)) ///
ytitle("") ylabel(0(0.1)1) name(class2)


.graph combine class1 class2, cols(2)

書いてあることは難しくないが、内容のわりにやたらと長い。
2クラスなのでこの程度だが、4クラスだとこの倍の量になる。とても洗練されているとは言い難い。estat lcmeanmarginsのラッパーであれば、プロットもオプションとして用意して、marginsから記述しなくてもいいようにできなかったのだろうか。

少し注意が必要そうなのは、ylabelの目盛りを調節だ。この図を出すまでに何回か調節をする必要があった。

f:id:iDES:20191116032605p:plain

潜在クラス分析[Stata]

Stataで潜在クラス分析ができるのでやってみた。
Stata15から標準機能で利用できるらしい。

Lanzaらのプラグインを使えばStata11から利用可能である。

www.methodology.psu.edu

Stataの標準機能だと機能が足りないように思うので、Lanzaらのパッケージを結局使うことになりそうだ。
LanzaらのパッケージはSASでも利用できる。SASといっても、無料で使えるSAS University Editionには対応していない。
ソフトウェアの価格の面から考えるとStataでの利用となりそうだ。

以下で実行しているデモはStata15から搭載されている標準機能を使ったものである。

サンプルデータ

Stataの用意しているサンプルデータを利用する。
http://www.stata-press.com/data/r16/gsem_lca1.dta

変数 ラベル
accident would testify against friend in accident case
事故の場合に友人に対して証言するだろう
play would give negative review of friend's play
友人の遊びに否定的な評価をするだろう
insurance would disclose health concerns to friend's insurance company
友人の健康上の問題を保険会社に開示するだろう
stock would keep company secret from friend
友人から会社の秘密を守るだろう

何のデータがいまいちわからないが、デモであれば特に問題ないだろう。

潜在クラス分析

Stataでは潜在クラスの式は最初に走らせる必要がある。とりあえず3クラスモデルで走らせている。

. use http://www.stata-press.com/data/r16/gsem_lca1.dta, clear
. gsem (accident play insurance stock <- ), logit lclass(C 3)

コマンドはgsemである。一般化SEMのバリエーションの一つだ。フォーマットは、()の中に潜在クラスに利用する変数を入れて最後に<-をつける。次に、コンマを打ちlogit lclass(C 3)と潜在クラスのオプションをつける。(C 3)は3クラスモデルを意味している。

クラス構成割合

クラス構成割合のコマンドと表示は以下である。

. estat lcprob

Latent class marginal probabilities             Number of obs     =        216

--------------------------------------------------------------
             |            Delta-method
             |     Margin   Std. Err.     [95% Conf. Interval]
-------------+------------------------------------------------
           C |
          1  |   .1560766   15.31178      2.1e-100           1
          2  |   .6346788   11.94001      2.55e-44           1
          3  |   .2092446   3.373463      1.17e-18           1
--------------------------------------------------------------

応答確率

条件付き応答確率は次のように出力する。

. estat lcmean

Latent class marginal means                     Number of obs     =        216

--------------------------------------------------------------
             |            Delta-method
             |     Margin   Std. Err.     [95% Conf. Interval]
-------------+------------------------------------------------
1            |
    accident |   .3935409   25.44072      1.20e-91           1
        play |   .0466199   12.58716      4.3e-243           1
   insurance |   .2541585   3.758665      4.52e-18           1
       stock |   .0656737   2.330868      3.26e-34           1
-------------+------------------------------------------------
2            |
    accident |   .8220824   4.909919      1.23e-28           1
        play |    .455712   9.045093      7.63e-32           1
   insurance |   .4224278    5.13116      9.18e-19           1
       stock |   .1818264    3.94581      5.89e-24           1
-------------+------------------------------------------------
3            |
    accident |   .9963741   .3046207      4.65e-70           1
        play |   .9725123   1.448169      2.73e-45           1
   insurance |   .9850408   3.020941      2.1e-173           1
       stock |    .881904   6.083824      1.41e-49           1
--------------------------------------------------------------

フィッティング指標

潜在クラス分析ではクラス数を検討しなければならない。 estat lcgofコマンドで尤度比、尤度比検定、AICBICが出力できる。

. estat lcgof
----------------------------------------------------------------------------
Fit statistic        |      Value   Description
---------------------+------------------------------------------------------
Likelihood ratio     |
          chi2_ms(1) |      0.387   model vs. saturated
            p > chi2 |      0.534
---------------------+------------------------------------------------------
Information criteria |
                 AIC |   1034.602   Akaike's information criterion
                 BIC |   1081.856   Bayesian information criterion
----------------------------------------------------------------------------

フィッティング指標の比較

. gsem (accident play insurance stock <- ), logit lclass(C 2)
estimates store twoclass
. gsem (accident play insurance stock <- ), logit lclass(C 3)
estimates store threeclass

それぞれの結果をtwoclassthreeclassに格納する。この値は任意である。
この2つのフィッティング指標を比較することができる。

. estimates stats twoclass threeclass
Akaike's information criterion and Bayesian information criterion

-----------------------------------------------------------------------------
       Model |          N   ll(null)  ll(model)      df        AIC        BIC
-------------+---------------------------------------------------------------
    twoclass |        216          .  -504.4677       9   1026.935   1057.313
  threeclass |        216          .  -503.3011      14   1034.602   1081.856
-----------------------------------------------------------------------------
Note: BIC uses N = number of observations. See [R] BIC note.

AICBICをみるといずれも2クラスモデルの方が値が小さいので、2クラスモデルの方がさそうである。

ベイジアンロジスティック回帰分析・その3

HardinとHilbeのStata本にあるベイジアンロジスティック回帰分析の続き。今回は事前分布としてコーシー分布を使う方法についてである。

1回目エントリはこちら
2回目エントリはこちら

Generalized Linear Models and Extensions: Fourth Edition

Generalized Linear Models and Extensions: Fourth Edition

情報事前分布

先の2つのエントリーでは無情報事前分布(non-informative prior distribution)を用いてきたが、今回は情報事前分布(informative priors)を利用する。

センタリングした変数は医師の訪問cdocと年齢cageの2つで、この2つの変数をコーシー事前分布(Cauchy priors)を用いて推定する。ベイズ事前分布は堅実な外部情報に基づいている必要がある。ベイズ推定のように、既に同じようなものを計測していると、より確かな推定値が得られる。コーシー分布が堅実だと言い切れるかというとそうではない。実際に推定して推定結果を比較してどちらが良いか、比較することになる。

下記のケースでは推定の際に、任意の値をspecificationととして用いることで、デフォルトとは異なる推定を行う。 コーシー分布の理論的な説明は後ほどするとして、先にStataでの使用方法について述べていこう。

コーシー分布をベイジアンロジスティック回帰

Stata15以降の機能である。

. bayes,
> prior({outwork:female kids _cons}, normal(0, 1000))
> prior({outwork:cdoc}, cauchy(0,6))
> prior({outwork:cage}, cauchy(0,11))
> rseed (35841): glm outwork female kids cdoc cage, family(binomial)

Model summary
------------------------------------------------------------------------------
Likelihood:
  outwork ~ glm(xb_outwork)

Priors:
  {outwork:female kids _cons} ~ normal(0,1000)                             (1)
               {outwork:cdoc} ~ cauchy(0,6)                                (1)
               {outwork:cage} ~ cauchy(0,11)                               (1)
------------------------------------------------------------------------------
(1) Parameters are elements of the linear form xb_outwork.

Bayesian generalized linear models               MCMC iterations  =     12,500
Random-walk Metropolis-Hastings sampling         Burn-in          =      2,500
                                                 MCMC sample size =     10,000
Family : Bernoulli                               Number of obs    =      3,874
Link   : logit                                   Scale parameter  =          1
                                                 Acceptance rate  =      .2057
                                                 Efficiency:  min =     .03496
                                                              avg =     .04486
Log marginal-likelihood = -1993.0855                          max =     .05717

------------------------------------------------------------------------------
             |                                                Equal-tailed
     outwork |      Mean   Std. Dev.     MCSE     Median  [95% Cred. Interval]
-------------+----------------------------------------------------------------
      female |  2.260141   .0842407   .004506   2.254865   2.097708   2.431913
        kids |  .3540421   .0906731   .003792   .3560368   .1811122   .5379961
        cdoc |  .0248758   .0063243   .000318   .0247956   .0130655   .0382379
        cage |  .0544032   .0039354    .00017   .0543025   .0469003   .0626092
       _cons | -2.012612   .0799112   .004051  -2.011676  -2.171733  -1.862155
------------------------------------------------------------------------------

コーシー分布を事前分布ベイジアンロジスティック回帰・MH法

同じく、Stata15以降の機能である。

. bayesmh outwork female kids cdoc cage, likelihood (logit)
> prior({outwork:female kids _cons}, normal(0, 1000))
> prior({outwork:cdoc}, cauchy(0,6))
> prior({outwork:cage}, cauchy(0,11))
> rseed (35841)

Model summary
------------------------------------------------------------------------------
Likelihood:
  outwork ~ logit(xb_outwork)

Priors:
  {outwork:female kids _cons} ~ normal(0,1000)                             (1)
               {outwork:cdoc} ~ cauchy(0,6)                                (1)
               {outwork:cage} ~ cauchy(0,11)                               (1)
------------------------------------------------------------------------------
(1) Parameters are elements of the linear form xb_outwork.

Bayesian logistic regression                     MCMC iterations  =     12,500
Random-walk Metropolis-Hastings sampling         Burn-in          =      2,500
                                                 MCMC sample size =     10,000
                                                 Number of obs    =      3,874
                                                 Acceptance rate  =      .1844
                                                 Efficiency:  min =     .03402
                                                              avg =     .05568
Log marginal-likelihood = -1993.0309                          max =     .07315

------------------------------------------------------------------------------
             |                                                Equal-tailed
     outwork |      Mean   Std. Dev.     MCSE     Median  [95% Cred. Interval]
-------------+----------------------------------------------------------------
      female |  2.258607   .0839686   .004552   2.261023     2.0928   2.423481
        kids |  .3565683   .0899923   .003727   .3605532   .1768716   .5279933
        cdoc |   .024811   .0064852   .000282   .0244694   .0122816   .0378834
        cage |  .0547071   .0039411   .000146   .0547988   .0469502     .06197
       _cons | -2.010109   .0794933   .003246  -2.009283  -2.171436  -1.854177
------------------------------------------------------------------------------

情報基準量

情報基準量はいつもの通り。

. bayesstats ic
Bayesian information criteria

----------------------------------------------
             |       DIC    log(ML)    log(BF)
-------------+--------------------------------
      active |  3928.181  -1993.031          .
----------------------------------------------
Note: Marginal likelihood (ML) is computed
      using Laplace-Metropolis approximation.

分布の比較

無情報事前分布(noninformative)とコーシー分布(informative)を用いた推定値の比較をしてみよう。

noninformative informative
female 2.60 2.259
kids 0.356 0.356
cdoc 0.024 0.025
cage 0.055 0.055
xcons -2.01 -2.01

Stataにはモデルの事後確率を基に仮説検定ができるコマンドがあるとのこと。bayestest modelコマンドを利用すると、モデルの限界尤度と事前確率と事後確率が表示できるようだ。レファレンスを参照とのこと。

プロット

cageのグラフに改善点があったため、それが前回の推定より改善されているかが問題となる。改善をしていれば、コーシー事前分布は有用ということになる。

. bayesgraph diagnostics {outwork:cdoc}

f:id:iDES:20191112152036p:plain

. bayesgraph diagnostics {outwork:cage}

f:id:iDES:20191112152049p:plain

このグラフは以前よりも改善されている。センタリングされた年齢の変数は以前のグラフではほぼ二峰性だった(参照)。 また、このモデルでは、無情報事前分布のモデルよりもcageの確信区間が狭くなっている。その理由は事前確率があった方が情報量がわずかに多いためである。Cauchy事前分布のモデルは、フラット事前分布のモデルよりも、センタリングされた年齢変数に適したものになっている。

コーシー分布

コーシー事前分布では、位置パラメーターとスケールパラメーター指定する。

f:id:iDES:20191112151933p:plain

上の式をStataのコマンドにすると以下のようになる。

prior({outwork: cage}, logdensity(ln(11)-ln(11^2+({outwork: cage})^2-ln(_pi))))

Stata15から導入されたprefixであるcauchy()はこの式をlogdensity()オプションに入れなくてもコマンドを走らせることができる。

ベイズ統計でコーシー分布といえばGelmanの論文である。

projecteuclid.org PDF
http://www.stat.columbia.edu/~gelman/research/published/taumain.pdf

本としては以下のもの。

Bayesian Data Analysis (Chapman & Hall/CRC Texts in Statistical Science)

Bayesian Data Analysis (Chapman & Hall/CRC Texts in Statistical Science)

  • 作者: Andrew Gelman,John B. Carlin,Hal S. Stern,David B. Dunson,Aki Vehtari,Donald B. Rubin
  • 出版社/メーカー: Chapman and Hall/CRC
  • 発売日: 2013/11/05
  • メディア: ハードカバー
  • この商品を含むブログを見る

コーシー分布を事前分布としたベイジアンロジスティック回帰

logdensity()のオプション指定をすると、Stata15から搭載されたcauchy()のprefixを使わずに、同様の意味を持つ式が書けるのでStata14でも走るように思うのだが、Stata14は持ってないのでよくわからない。

変数cdocおよびcageについては、a = 0を設定する。cdocはscaleパラメーターb = 6を設定し、cageはb = 11とする。説明が前後しているが、これらの任意の値は冒頭のスクリプトにも入れてある。変数femaleとkidsはnormal(0,1000)の事前分布を使用。これはベイズ統計を使用するときのデフォルトである。

スクリプトは次のようになる。

. bayes, prior({outwork:female kids _cons}, normal(0, 1000)) 
> prior({outwork:cdoc},
> logdensity(ln(6)-ln(6^2+({outwork:cdoc})^2)-ln(_pi)))
> prior({outwork:cage},
> logdensity(ln(11)-ln(11^2+{outwork:cage}^2)-ln(_pi)))
> rseed (35841): glm outwork female kids cdoc cage, family(binomial)

コーシー分布を事前分布としたベイジアンロジスティック回帰・MH法

MH法のbayesmhコマンドでは次のように指定する。

. bayesmh outwork female kids cdoc cage, likelihood(logit)
> prior({outwork:female kids _cons}, normal(0, 1000))
> prior({outwork:cdoc},
> logdensity(ln(6)-ln(6^2+({outwork:cdoc})^2)-ln(_pi)))
> prior({outwork:cage},
> logdensity(ln(11)-ln(11^2+({outwork:cage})^2)-ln(_pi)))
> rseed (35841)

logdensity()でコーシー分布の指定をしなくてもいいので、Stata15以降の方が多少楽になった気はする。
HardinとHilbeのテキストのコーシー分布自力計算のスクリプト内logdensity()オプションの中に誤植があったので、教科書を書く人間が間違うくらいだから、Stata15以降の改善は良いことなのだろうと思う。