井出草平の研究ノート

poLCAでデータ加工をしてRandomLCAでBLRTの計算をする[R]

私たちが使い慣れているデータ(行にケース、列に変数という形式のもの)を使ってRでブートストラップ尤度比検定(Bootstrapped Likelihood Ratio Test)を計算する方法についてのエントリである。
poLCAには残念ながらBLRTの機能がないので、poLCAのpredcell関数でデータを加工してからRandomLCAパッケージでBLRTの計算をするという手順を踏む。

データ

poLCAのcarcinomaデータを利用する。 子宮頸部のがんのデータである。デモなのでデータの説明は省く。

library(poLCA)
data(carcinoma)
carcinoma[100:105,] #100~105行目を抽出

次のようなデータである。

    A B C D E F G
100 2 2 2 2 2 1 2
101 2 2 2 2 2 1 2
102 2 2 2 2 2 1 2
103 2 2 2 2 2 2 2
104 2 2 2 2 2 2 2
105 2 2 2 2 2 2 2

predcell関数でデータ形式を変換

データ形式を下記の手順で変換する。

data(carcinoma)
f <- cbind(A,B,C,D,E,F,G)~1
clc2 <- poLCA(f,carcinoma,nclass=2)
carcinoma2<- clc2$predcell # スタック形式carcinoma2とする
print(carcinoma2) 

このようにするとRandomLCAで扱える形式のデータに変換できる。

   A B C D F G observed expected
1  1 1 1 1 1 1       36   30.028
2  1 2 1 1 1 1       10   16.197
3  1 2 1 1 1 2        6    2.023
4  2 1 1 1 1 1        2    3.751
5  2 1 2 1 1 2        1    0.203
6  2 2 1 1 1 1        4    2.023
7  2 2 1 1 1 2        8    4.075
8  2 2 1 1 2 2        1    2.769
9  2 2 1 2 1 2        3    4.447
10 2 2 1 2 2 2        3    3.222
11 2 2 2 1 1 2       13   11.858
12 2 2 2 1 2 2        5    8.592
13 2 2 2 2 1 2       10   13.797
14 2 2 2 2 2 2       16    9.997

もっとスマートな方法は他にもありそうだが、とりあえずpredcell関数しか僕は発見できていないので、今回はこの方法を利用する。

randomLCAパッケージで潜在クラス分析

データcarcinoma2のA~Gはデータは1/2で構成されている。RandomLCAは0/1である必要があるため、memiscパッケージを利用して0/1にリコードする。

library(memisc)
carcinoma2$A <- recode(carcinoma2$A , 0 <- 1, 1 <- 2)
carcinoma2$B <- recode(carcinoma2$B , 0 <- 1, 1 <- 2) 
carcinoma2$C <- recode(carcinoma2$C , 0 <- 1, 1 <- 2) 
carcinoma2$D <- recode(carcinoma2$D , 0 <- 1, 1 <- 2) 
carcinoma2$E <- recode(carcinoma2$E , 0 <- 1, 1 <- 2) 
carcinoma2$F <- recode(carcinoma2$F , 0 <- 1, 1 <- 2) 
carcinoma2$G <- recode(carcinoma2$G , 0 <- 1, 1 <- 2) 

データタイプは整数型でも実数型でも走るようだ。

今回は2クラスモデルと3クラスモデルを比較する。
比較する2クラスモデルと3クラスモデルを作成しておく。

library(randomLCA)
carcinoma2.lca2 <- randomLCA(carcinoma2[,1:7],freq=carcinoma2$observed,nclass=2)
carcinoma2.lca3 <- randomLCA(carcinoma2[,1:7],freq=carcinoma2$observed,nclass=3)

BLRT

BLRTのスクリプトに関する細かい説明は先のエントリを参照のこと。
まず、対数尤度の差の二乗。

## 3クラス、2クラスモデルの対数尤度の差の二乗
obslrt <- 2*(logLik(carcinoma2.lca3)-logLik(carcinoma2.lca2)) 
print(obslrt)

結果は以下。

'log Lik.' 47.09539 (df=23)

BLRT。

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

P値。

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

結果は以下。

p-value=0.001

Mplusに比べて手順が煩雑なのが欠点であろうか。

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クラスモデルの方がさそうである。