R / Stan によるカテゴリカル分布のパラメーター推定

カテゴリカル分布

カテゴリカル分布は順序情報のないカテゴリデータを扱うための文法である。例えば、地域名、種名、性別などがカテゴリデータにあたる。サイコロの振り目も 1 から 6 までの数字として出るが、これらの数値には(解析目的によっては)順序情報が含まれていないと考えることができる。例えば、賞金設定で 2 がでたら 500 円、 3 がでたら 900 円のように、必ずしも目が大きいと意味があるわけではない。

ここでサイコロの振り目データを乱数で発生させて、各目がどれぐらいの確率で出るのかを Stan で推定してみる。まず、少し不公平なサイコロの振り目データを 100 個作成する。このとき、1, 2, 3, 4, 5, 6 が出る確率をそれぞれ 0.3, 0.1, 0.1, 0.2, 0.2, 0.1 とする。

x <- sample(1:6, 100, replace = TRUE, prob = c(0.3, 0.1, 0.1, 0.2, 0.2, 0.1))
table(x)
##  1  2  3  4  5  6
## 28 11  8 25 19  9

次に、Stan コードを利用してモデルを記述していく。サイコロの各目の出る確率を求めたいので、その確率をベクトル θ とおく。このときベクトル θ は 6 個の要素を持ち、それらの合計値が 1.0 となる。Stan では、ベクトルの合計値が 1.0 となるように制限が存在するとき、vector 型の代わりに simplex 型を用いると便利である。

data {
    int N;
    int M;
    int y[N];
}
parameters {
    simplex[M] theta;
}
model {
    for (n in 1:N) {
        y[n] ~ categorical(theta);
    }
}

続いて R で Stan コードを読み込んで、データを代入してパラメーターを推定していく。

d <- list(y = x, N = length(x), M = length(unique(x)))
fit <- stan(file = 'multi_norm.stan', data = d)
fit
## Inference for Stan model: multi_norm.
## 4 chains, each with iter=2000; warmup=1000; thin=1;
## post-warmup draws per chain=1000, total post-warmup draws=4000.
## 
##             mean se_mean   sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
## theta[1]    0.27    0.00 0.04    0.19    0.24    0.27    0.30    0.36  4761    1
## theta[2]    0.11    0.00 0.03    0.06    0.09    0.11    0.13    0.18  4334    1
## theta[3]    0.08    0.00 0.03    0.04    0.06    0.08    0.10    0.14  4422    1
## theta[4]    0.25    0.00 0.04    0.17    0.22    0.24    0.27    0.33  4130    1
## theta[5]    0.19    0.00 0.04    0.12    0.16    0.19    0.21    0.27  4983    1
## theta[6]    0.09    0.00 0.03    0.05    0.07    0.09    0.11    0.16  5203    1
## lp__     -181.98    0.04 1.61 -186.02 -182.78 -181.64 -180.80 -179.88  1843    1

推定されたパラメーターの情報は上のように fit 変数を表示させれば、画面上に表示される。95% 信用区間を自分で求めたい場合は、次のようにする。

ms <- rstan::extract(fit)
apply(ms$theta, 2, quantile, probs = c(0.025,  0.975))
##              [,1]       [,2]       [,3]      [,4]      [,5]       [,6]
##   2.5%  0.1931747 0.06016473 0.04020945 0.1694428 0.1207068 0.04658794
##   97.5% 0.3630181 0.18112827 0.14349897 0.3314907 0.2707293 0.15697648

サイコロの振り目 1, 2, 3, 4, 5, 6 が出る確率をそれぞれ 0.3, 0.1, 0.1, 0.2, 0.2, 0.1 としてデータを生成したので、この真の値と推定された 95% 信用区間を見比べると、真の値がすべて 95% 信用区間に含まれていることがわかる。

各パラメーターの分布図は stan_hist 関数で描くことができる。

stan_hist(fit)
Stan によって推定されたカテゴリカル分布のパラメーター分布