ディリクレ分布

Takami Torao
  • このエントリーをはてなブックマークに追加

次元での任意の に対して取りうる の確率分布をヒートマップで表すシミュレーション。 であることから を省略し の 2 次元で表現している。ヒートマップ上での白抜けは発散を示している。

, ,
期待値 (?,?,?)
最頻値   (?,?,?)
分散 (?,?,?)

定義と性質

ディリクレ分布 (dirichlet distribution) は独立した事象 がそれぞれ 回観測されたときに各事象の生起確率が である確率を示す連続した確率密度関数。 がすべて整数であれば と置き換えてもよい。

ここで の範囲において となる部分で が発散することに注意。

としたとき、ディリクレ分布における期待値 、最頻値 、分散 は以下のように表される。 多項分布の推定で導出した MAP 推定の最頻値 としたディリクレ分布の最頻値と同じである。

事象のモデルは多項分布 と同じであり、実際、多項分布の自然共役分布であることから、ベイズの定理で多項分布を尤度関数としたときの事前確率、事後確率として使われている。

多項分布が事象 の生起確率 から観測数 となる確率分布を表しているのに対して、ディリクレ分布は実際の観測数 から生起確率 がどこにあるかの確率分布を表している。

ディリクレ分布の可視化

を変化させて得られるディレクリ分布からその意味を考えてみよう。

一様分布

α=(1,1,1) は全ての で一様な確率分布となる。事象 の観測数が であることを考えれば はまだ一つも有効なデータを観測していないことを表している。推定に利用できるデータがまだ存在しない状況では全ての生起確率は均等な確かさという意味である。一様分布が事前確率に使用されるとき無情報事前確率と呼ばれる。

対称ディリクレ分布

α=(2,2,2) のように がすべて等しい分布を対称ディリクレ分布と呼ぶ。期待値、最頻値ともに 次元の中央となる に存在する。この意味は「すべての事象が同じ回数出現した観測結果から導かれる最も妥当な推定は全ての生起確率が等しいこと」である。

対称ディリクレ分布

α=(10,10,10) も同様に対称ディリクレ分布であるが、 のときよりもよりピークが鋭い (分散が小さい)。これは「すべての事象の出現回数が全て9となるケースは、出現回数が全て1となるケースよりまれで、したがって の時より『全ての生起確率が等しい』推定の確度が高い」ことを意味する。

ディリクレ分布

α=(2,0,0) とは の事象が 1 回現れたという意味である。したがって、ディリクレ分布は が最も確度の高い生起確率であることを示している。 を大きくするに従って の分布ピークも鋭くなってゆく (自分で確認せよ)。

ディリクレ分布

α=(3,2,10) からは の事象が起きやすく、 を比較して「どちらかと言うと の方が起きやすい」ことを示している。実際に分布のピークは の高くなる 付近に存在し 方向よりも 方向に少し寄っている。

対称ディリクレ分布

α=(0.7,0.7,0.7) について、 をとるディリクレ分布は凸型ではなく凹型となり前述の通り の部分で発散しているのが分かる。

このとき、 しか取り得ないという意味なのか の値は取りえないという意味なのか、確率分布として発散の意味は何なのか (そもそも がどういう意味なのか想像が及んでいない)。 しかとりえないのであれば の対象ディリクレ分布は となり を満たさなくなる。

実用例

多項分布を尤度関数としたときの事後確率となるため、カテゴリカル分布に従う試行を繰り返すときのそれぞれの事象 の生起確率を求めるためによく使われている。特に自然言語処理ではトピックモデルで各トピックに単語が所属する生起確率を求める使い方がされている。

0
()
()
()
()
()
()
0

Example 1

一様に落ちてくる 10 個のボールが 5 つの区画にそれぞれ 入ったとき、各区画に入る確率 の期待値、最頻値、分散はそれぞれ以下のように表される。区画の広さの比率は (0.1, 0.4, 0.2, 0.2, 0.1) である可能性が最も高いが、確率のぶれを考慮して のように考えてもよい。

適当な点を採用して生起確率 に対応するディリクレ分布の値は: となる。

多項分布 (Multinomial Distribution)

Example 2

種類のカードが出るガチャを考える。 回引いて出た枚数がそれぞれ であったとき、それぞれの最頻値は以下のように表される。

アルゴリズム

ディリクレ分布の式 () は分数の形でガンマ関数が含まれているためオーバーフローを防ぐために対数を加減算してから指数化するとよいだろう。

ここでは対数ガンマ関数を使用している。

def dirichletln(alpha:Array[Double])(p:Array[Double]):Double = {
  assert(p.length == alpha.length && p.length != 0)
  val k = p.length;
  var Σa = 0.0
  var ΣlogΓa = 0.0
  var Σa1logp = 0.0
  for(k <- 0 until k){
    Σa += a(k)
    ΣlogΓa += gammaln(a(k))
    Σa1logp += (a(k) - 1) * math.log(p(k))
  }
  gammaln(Σa) - ΣlogΓa + Σa1logp
}

def dirichlet(alpha:Array[Double])(p:Array[Double]):Double = math.exp(dirichletln(p, a))

参照

  1. 多項分布の推定 (MOXBOX)