KL ダイバージェンスと最尤推定#
パラメータの最尤推定
入力
真の確率分布 \(p_\ast (x)\) から生成された \(N\) 個のサンプル \(\{x^{(1)},x^{(2)},\ldots,x^{(N)}\}\)
パラメータ \(\theta\) で調整できる確率分布 \(p_\theta(x)\)
出力
\(p_\theta(x)\) が \(p_\ast(x)\) に最も近づくような \(\theta\) の値
最尤推定では,以下の対数尤度を目的関数とする.
この対数尤度を最大化するパラメータを以下のように表記する.
ここで,「\(p_\theta(x)\) を \(p_\ast(x)\) に近づける」は, 「\(p_\theta(x)\) と \(p_\ast(x)\) の KL ダイバージェンスを最小にする」と言い換えられる.
すなわち,
を最小にするような \(\theta\) を求められればよい.
しかし,\(p_\ast\) が未知である以上,実際に積分計算を行うことはできない…
そこで,モンテカルロ法を用いて近似的に求めることを考える.
モンテカルロ法を用いた期待値の近似#
確率分布 \(p(x)\) に対する任意の関数 \(f(x)\) の期待値 \(\mathbb{E}_{p(x)}[f(x)]\) を以下のように定義する.
近似のアルゴリズム#
確率分布 \(p(x)\) からサンプル \(\{x^{(1)}, x^{(2)}, \ldots, x^{(N)}\}\) を生成する
各データ \(x^{(i)}\) における \(f(x^{(i)})\) を求め,その平均を計算する.
実験してみる#
積分結果#
解析的に計算すると,
:dep rand = "0.8.5"
:dep rand_distr = "0.4.3"
use rand::prelude::*;
use rand_distr::Normal;
// 乱数生成器を初期化
let mut rng = thread_rng();
// 標準正規分布
let std_normal = Normal::new(0.0, 1.0).unwrap();
// サンプリング回数
const NUM: usize = 50000;
fn f(x: f64) -> f64 {
x
}
fn g(x: f64) -> f64 {
x + 1.0
}
// fの期待値
let exp_f = std_normal
.sample_iter(&mut rng)
.take(NUM)
.map(f)
.sum::<f64>() / NUM as f64;
exp_f
-0.0005952278388999247
// gの期待値
let exp_g = std_normal
.sample_iter(&mut rng)
.take(NUM)
.map(g)
.sum::<f64>() / NUM as f64;
exp_g
0.9985557292925885
モンテカルロ法なので精度は低いが,理論値である以下の値にある程度近づいていることがわかる.
\(\mathbb{E}_{p(x)}[f(x)] = 0\)
\(\mathbb{E}_{p(x)}[g(x)] = 1\)