KLダイバージェンス完全ガイド — 確率分布間の情報量距離を直感で理解する

KLダイバージェンスとは、2つの確率分布 $P$ と $Q$ の「ずれ」を1つの数値で表す量です。「$P$ を真の分布として、モデル分布 $Q$ がどれだけ違うか」を測り、0ならまったく同じ、大きいほど異なる分布を意味します。距離に似ていますが後述するように非対称なため「距離ではなくダイバージェンス(発散)」と呼ばれます。

この量はさまざまな名前で呼ばれます。本記事ではすべて同じ量を指します:

  • KLダイバージェンス (KL divergence) — 最も広く使われる呼び名
  • カルバック・ライブラー情報量 / カルバック-ライブラー情報量 — 考案者の名前から
  • KL情報量 — 略称
  • 相対エントロピー (relative entropy) — 情報理論における呼び名
  • KL divergence — 英語表記

ある言語モデルが「次に来る単語」の確率を予測したとします。$P$ を真の分布、$Q$ をモデルの予測分布としたとき、「$Q$ は $P$ にどのくらい近いか」を一つの数字で表せるでしょうか。あるいは、コインを100回投げて60回表が出たとき、「表確率 $0.5$ という仮説」と「$0.6$ という仮説」のどちらが観測データ分布に近いと言えるでしょうか。こうした「2つの確率分布の違いを定量化する」という問いに、情報理論から自然に導かれる答えが、上に挙げた KLダイバージェンスです。

真の分布Pをモデル分布Qで近似するイメージ図

KLダイバージェンスは、機械学習・統計の中核にいる道具です。ニューラルネットの分類で使われるクロスエントロピー損失は実質KL最小化と等価ですし、画像生成で有名な VAE (変分オートエンコーダ) の損失関数には事前分布と近似事後分布のKLが正則化項として現れます。強化学習の PPO では方策更新の安定化にKL制約を使い、ベイズ統計の中心にある変分推論は事後分布をKLの意味で近似する手続きそのものです。一見抽象的なこの量が、現代のAI技術の土台で静かに働いています。

本記事の内容

  • KLダイバージェンスの直感的意味 — 「$P$ で生まれたデータを $Q$ で符号化したときの余分なビット数」
  • 連続/離散の定義と、$\log x \leq x – 1$ から始まるGibbsの不等式 ($D_{KL} \geq 0$) の証明
  • 非対称性 — forward KL と reverse KL の挙動の違い (mode-covering vs mode-seeking)
  • クロスエントロピーとの関係と、最尤推定がKL最小化と等価である理由
  • ガウス分布間のKLの閉形式とPython実装
  • VAE・変分推論・PPO での具体的な役割

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が深まります。

なぜ「分布の距離」が必要なのか

KLダイバージェンスの定義式に入る前に、そもそも「2つの確率分布の距離を測る」というのがどういう問題なのかを少しだけ整理しておきます。

機械学習や統計の現場で繰り返し現れる問いがあります。観測データが従う真の分布 $P$ と、私たちが手元のモデルで構築した推定分布 $Q$ がどれだけずれているか——これを一つの実数値で評価したい、というものです。例えば言語モデルなら $Q$ は学習済みの確率モデル、$P$ は実際のテキストデータの分布です。この差を縮めるように $Q$ のパラメータを更新するのが「学習」というプロセスにほかなりません。

素朴に思いつくのは、各 $x$ について差の絶対値を足す 全変動距離 $\frac{1}{2}\sum_x |p(x) – q(x)|$ や、ユークリッド距離 $\sqrt{\sum_x (p(x) – q(x))^2}$ でしょう。しかし、これらには重要な情報が抜け落ちています。それは尤度比 $p(x)/q(x)$ の情報です。尤度比は「観測 $x$ を $P$ で説明するのと $Q$ で説明するのとで、どちらがどれだけ尤もらしいか」を直接表す量で、ベイズ推論や仮説検定の根幹にあります。せっかく分布の差を測るなら、この尤度比を素直に扱える定義式が欲しい。

もうひとつの観点は符号化です。情報理論の創始者シャノンが示したのは、ある分布 $P$ に従って発生するシンボルを最適に符号化すると、平均符号長は エントロピー $H(P) = -\sum_x p(x) \log p(x)$ ビットになるという事実でした。では、本当は $P$ から出るのに $Q$ にもとづいた符号を使ってしまったら、どのくらい無駄が発生するでしょうか。この「余分なビット数の期待値」こそが、これから定義するKLダイバージェンスの正体です。

直感的に距離らしき量に最低限求めたい性質を整理すると、

  1. 非負性 — 同じ分布同士なら $0$、違うほど大きくなる
  2. 尤度比を素直に扱える — $\log p(x)/q(x)$ のような形が自然に出る
  3. 加法性 — 独立な要素なら個別に評価できる

の3つでしょう。実は、これらを満たす最も自然な量が、シャノンの情報量から導かれるKLダイバージェンスなのです。

それでは早速、定義に進みましょう。

KLダイバージェンスの定義

離散の場合

2つの離散確率分布 $P, Q$ が同じ標本空間 $\mathcal{X}$ 上で確率質量関数 $p(x), q(x)$ を持つとします。このとき KLダイバージェンス は次で定義されます。

$$ D_{KL}(P \,\|\, Q) = \sum_{x \in \mathcal{X}} p(x) \log \frac{p(x)}{q(x)} $$

記号は $D_{KL}(P \| Q)$ と縦棒2本で書くのが標準です。「$P$ から $Q$ へのKLダイバージェンス」あるいは「$P$ に対する $Q$ のKLダイバージェンス」と読みます。順序が大事で、慣例的に第一引数 $P$ が真の (基準となる) 分布、第二引数 $Q$ が比較先 (モデル分布) です。

連続の場合

確率密度関数 $p(x), q(x)$ を持つ連続分布なら、和を積分に置き換えて

$$ D_{KL}(P \,\|\, Q) = \int p(x) \log \frac{p(x)}{q(x)}\, dx $$

とすればよいだけです。離散と連続をまとめて、$P$ に関する期待値の形で

$$ D_{KL}(P \,\|\, Q) = \mathbb{E}_{x \sim P}\!\left[\log \frac{p(x)}{q(x)}\right] $$

と書くのが、もっとも本質を表していて使いやすい形です。$P$ からサンプルした $x$ について、対数尤度比 $\log p(x)/q(x)$ の平均——これがKLダイバージェンスです。

0 と $\infty$ の約束

定義式に対数や割り算が入っているので、$p(x) = 0$ や $q(x) = 0$ となる点での値が気になります。次の慣習を置きます。

  • $p(x) = 0$ ならその点では $0 \log 0 = 0$ (極限) とみなし、和から除く
  • $p(x) > 0$ かつ $q(x) = 0$ となる点が一点でもあれば $D_{KL} = +\infty$

後者の規約は、「$P$ が値を持つ場所では $Q$ も値を持っていないとダメ」(絶対連続性 $P \ll Q$ の要請) を意味します。VAEや変分推論で「事前分布は十分広いガウスにする」「dropoutの確率は0や1にしない」といった工夫が出てくるのは、この発散を避ける実用上の理由が背景にあります。

定義はこれだけなのですが、なぜこの形なのか、何を測っているのかを次節で掘り下げていきます。

直感 — 「$Q$ で符号化したときの余分なビット数」

定義式 $D_{KL}(P\|Q) = \mathbb{E}_{x \sim P}[\log p(x)/q(x)]$ は何を計算しているのでしょうか。最も直感的な解釈は、情報理論の符号化文脈にあります。

最適符号長は $-\log_2 p(x)$ ビット

シャノンが示した古典的な結果に、シャノン符号化定理があります。確率 $p(x)$ で出現するシンボル $x$ を可逆符号で表現するとき、平均符号長 $\bar{L}$ には下限 $H(P) = -\sum_x p(x) \log_2 p(x)$ があり、これがエントロピーです。直感としては「確率の小さい (= 珍しい) シンボルほど長いビット列を割り当て、確率の大きい (= ありふれた) シンボルほど短いビット列を割り当てる」のが効率的で、最適にやると1シンボルあたり $-\log_2 p(x)$ ビットを使うのが理想ということになります。ハフマン符号や算術符号がこの限界に漸近的に到達します。

「間違った分布」で符号化する代償

ここで、本当は $P$ から出ているデータなのに、こちらは $Q$ という別の分布だと勘違いして符号設計してしまったとしましょう。$Q$ にもとづく最適符号は1シンボル $x$ に対して $-\log_2 q(x)$ ビットを割り当てます。この符号で $P$ から来るデータを符号化したときの平均符号長は

$$ H(P, Q) = -\sum_x p(x) \log_2 q(x) $$

となります。これをクロスエントロピー (cross-entropy) と呼びます。$P$ が真の分布だと知っていれば $H(P)$ ビットで済んだのに、$Q$ を信じてしまったがゆえに $H(P, Q)$ ビット使ってしまった——その差分こそがKLダイバージェンスです。

$$ \boxed{\,D_{KL}(P \| Q) = H(P, Q) – H(P)\,} $$

確かめておくと、

$$ H(P, Q) – H(P) = -\sum_x p(x) \log q(x) – \left(-\sum_x p(x) \log p(x)\right) = \sum_x p(x) \log \frac{p(x)}{q(x)} = D_{KL}(P\|Q) $$

となり、定義式と一致します (対数の底は揃っていれば何でもよい)。だから KL は 相対エントロピー (relative entropy) とも呼ばれるのです。「Pに対するQの余計な符号長 = エントロピー的な意味での『間違い具合』」が、KLダイバージェンスの直感的な意味です。

クロスエントロピーがエントロピーHとKL余分ビットに分解される図

期待対数尤度比としての解釈

統計の言葉で言い換えると、$\log p(x)/q(x)$ は対数尤度比そのもので、「観測 $x$ を $P$ と $Q$ のどちらで説明する方が尤もらしいか」を測っています。$P = Q$ ならどんな $x$ でも $\log p/q = 0$ で平均も $0$。$P$ と $Q$ がずれているほど、$P$ からサンプルした $x$ について平均的に $\log p/q$ が大きな正の値になる、という構造です。

「符号長の差」「期待対数尤度比」「相対エントロピー」——同じ量に対するこれら3つの見方は、応用ごとに使い分けると便利です。たとえば最尤推定の話題なら期待対数尤度比、データ圧縮の話なら符号長の差、変分推論の話なら相対エントロピーという呼び方が自然に出てきます。

ここまでで KL の意味の中核は押さえられました。次に、KL が常に非負であるという最重要性質を、対数の不等式から証明します。

Gibbsの不等式 — KL が非負である証明

KLダイバージェンスは 常に $D_{KL}(P \| Q) \geq 0$ であり、等号は $P = Q$ のときに限る。これは Gibbsの不等式 と呼ばれる定理で、KL を「分布の差」として使う根拠そのものです。EMアルゴリズムや変分推論の収束性、最尤推定の一致性、情報量規準などの理論的支柱はすべてここに帰着します。証明を一度自分の手で追っておく価値があります。

鍵となる初等不等式

証明の出発点は、対数関数についての次の初等不等式です。

$$ \log x \leq x – 1, \quad x > 0 \quad (\text{等号は } x = 1 \text{ のとき}) $$

これは「$\log x$ のグラフは点 $(1, 0)$ で接線 $y = x – 1$ に接し、それ以外では下にいる」という事実です。微分すれば一発で、$f(x) = (x-1) – \log x$ とすると $f'(x) = 1 – 1/x$ で、$x = 1$ で最小値 $f(1) = 0$ を取る。よって $f(x) \geq 0$、つまり $\log x \leq x – 1$。

log xと接線y=x-1の幾何的関係を示す図

符号を反転すると、より使いやすい

$$ -\log x \geq 1 – x \quad (x > 0) $$

の形になります。これを KL の各項に当てはめていきます。

不等式の代入

KL の定義式を負号付きで書き直しておくと、

$$ D_{KL}(P\|Q) = -\sum_x p(x) \log \frac{q(x)}{p(x)} $$

($\log p/q = -\log q/p$ を使ったので、和の外に負号が出てきた)。各項に $-\log x \geq 1 – x$ を $x = q(x)/p(x)$ で適用します。$p(x) > 0$ の各点で

$$ -\log \frac{q(x)}{p(x)} \geq 1 – \frac{q(x)}{p(x)} $$

が成立します。両辺に $p(x) \geq 0$ を掛けて非負性を保ったまま $x$ について和を取ると、

$$ \sum_x p(x) \left(-\log \frac{q(x)}{p(x)}\right) \geq \sum_x p(x) \left(1 – \frac{q(x)}{p(x)}\right) $$

になります。左辺はそのまま $D_{KL}(P\|Q)$ です。右辺を展開すると、

$$ \sum_x p(x) – \sum_x p(x) \cdot \frac{q(x)}{p(x)} = \sum_x p(x) – \sum_x q(x) = 1 – 1 = 0 $$

となります。最後の等号は「$P, Q$ がともに確率分布」だから $\sum p = \sum q = 1$ を使いました。まとめると

$$ D_{KL}(P\|Q) \geq 0 $$

が示せました。

等号成立条件

等号は、すべての $x$ について $-\log q/p = 1 – q/p$ となるとき、すなわち $q(x)/p(x) = 1$ がすべての $x$ で成り立つときに限られます。これは $P = Q$ そのものです。逆に $P = Q$ なら $\log p/q = \log 1 = 0$ で $D_{KL} = 0$ になることは定義から直接わかります。よって $D_{KL}(P\|Q) = 0 \iff P = Q$ が示せました。

連続分布の場合も、和を積分に置き換えるだけで同じ証明が成立します。

Jensenの不等式による別証明

別ルートも紹介しておきます。$-\log$ は凸関数なので、Jensenの不等式

$$ \mathbb{E}[\varphi(X)] \geq \varphi(\mathbb{E}[X]) \quad (\varphi \text{ 凸}) $$

が使えます。$\varphi = -\log$、$X = q(x)/p(x)$ ($x \sim P$) として、

$$ D_{KL}(P\|Q) = \mathbb{E}_{x \sim P}\!\left[-\log \frac{q(x)}{p(x)}\right] \geq -\log \mathbb{E}_{x \sim P}\!\left[\frac{q(x)}{p(x)}\right] = -\log \sum_x q(x) = -\log 1 = 0 $$

これも非常にエレガントな証明で、$-\log$ の凸性がKLの非負性の本質であることを示しています。

これで KL が「もっともらしい距離もどき」であることの数学的保証が得られました。ただし、注意すべき性質がひとつあります——KL は対称ではないのです。その前に、定義式の感触をつかむため、手で追える具体的な数値例を一つ確認しておきます。

手計算で確かめる数値例

抽象的な式に慣れるには、まず小さな例を自分で計算してみるのが近道です。2値のカテゴリカル分布 $P, Q$ を使って、定義式を一行ずつ展開します。

設定

「コインの表裏」のような2カテゴリの分布を考えます。

$$ P = [0.9,\ 0.1], \quad Q = [0.6,\ 0.4] $$

$P$ は「ほぼ確実に表」という偏った分布、$Q$ は「6割表」というもう少し穏やかな分布です。

KL(P ‖ Q) の計算

定義式 $D_{KL}(P\|Q) = \sum_x p(x) \log \frac{p(x)}{q(x)}$ に代入します (自然対数 $\ln$)。

$$ D_{KL}(P \| Q) = 0.9 \times \ln\!\frac{0.9}{0.6} + 0.1 \times \ln\!\frac{0.1}{0.4} $$

各項を計算すると、$\ln(0.9/0.6) = \ln 1.5 \approx 0.4055$、$\ln(0.1/0.4) = \ln 0.25 \approx -1.3863$ なので、

$$ D_{KL}(P \| Q) = 0.9 \times 0.4055 + 0.1 \times (-1.3863) = 0.3649 – 0.1386 \approx 0.2263 $$

KL(Q ‖ P) の計算

引数の順序を逆にして計算します。$\ln(0.6/0.9) = \ln 0.667 \approx -0.4055$、$\ln(0.4/0.1) = \ln 4 \approx 1.3863$ なので、

$$ D_{KL}(Q \| P) = 0.6 \times (-0.4055) + 0.4 \times 1.3863 = -0.2433 + 0.5545 \approx 0.3112 $$

読み取り

$D_{KL}(P\|Q) \approx 0.226 \neq D_{KL}(Q\|P) \approx 0.311$ であり、引数の順序を入れ替えると値が異なることが数値で確認できました。また、どちらも0以上で等号は $P=Q$ のときのみ(Gibbsの不等式)、という性質も成り立っています。この例では「$Q$ から $P$ を見たとき (reverse KL) の方が値が大きい」——これは $Q$ が0.4という比較的大きな確率を裾 ($x=1$) に割り当てているのに対し、$P$ はそこにわずか 0.1しか割り当てておらず、$\log(q/p)$ の罰則が逆方向より効いているためです。

なお、この2値の例をそのままPythonで実行確認もできます。

import numpy as np

p = np.array([0.9, 0.1])
q = np.array([0.6, 0.4])

kl_pq = np.sum(p * np.log(p / q))
kl_qp = np.sum(q * np.log(q / p))

print(f"KL(P||Q) = {kl_pq:.4f}")  # 0.2263
print(f"KL(Q||P) = {kl_qp:.4f}")  # 0.3112
print(f"非対称: {kl_pq:.4f} != {kl_qp:.4f}")

実行すると上の手計算値と一致します。p * np.log(p / q) が定義式の各項 $p(x)\log(p(x)/q(x))$ を要素ごとに計算しており、np.sum で総和を取るだけなので、定義式をほぼそのままコードに翻訳した形です。KL がゼロとなるのは p == q の時に限られ、それ以外では常に正の値を返すことも確かめられます。

数値の感触をつかんだところで、KL が対称でない理由——forward KL と reverse KL の意味の違いに進みましょう。

非対称性 — forward KL と reverse KL

KL は対称ではない

定義式を見ればすぐ気づくとおり、KL ダイバージェンスは一般に

$$ D_{KL}(P \| Q) \neq D_{KL}(Q \| P) $$

です。期待値を取る分布が違う (前者は $P$ について、後者は $Q$ について) ので、値が違うのは当然と言えば当然です。具体例として、$P$ がデルタ分布 ($x = 0$ に質量1)、$Q = \mathcal{N}(0, 1)$ で計算してみると、$D_{KL}(P\|Q)$ は有限ですが、$D_{KL}(Q\|P)$ は $+\infty$ (Q の質量がほとんどの $x$ で P=0 の領域にある) になってしまいます。

この非対称性のため、KL は 距離 (metric) の公理 (対称性と三角不等式) を満たしません。距離ではなく「ダイバージェンス (divergence)」と呼ぶ理由がここにあります。

Forward KL と Reverse KL

機械学習では、真の分布 $P$ を固定して近似分布 $Q$ を最適化する場面が多く、引数の順序によって挙動がガラッと変わります。

  • Forward KL $D_{KL}(P \| Q)$ — $P$ で平均する。最尤推定 (MLE) はこれを最小化することと等価
  • Reverse KL $D_{KL}(Q \| P)$ — $Q$ で平均する。変分推論 (VI)・VAE はこれを最小化する

「forward」は「真の分布から見て」、「reverse」は「近似分布から見て」という意味合いです。どちらを使うかで、得られる近似 $Q$ の形が大きく変わります。

Mode-covering: forward KL の挙動

Forward KL の被積分項 $p(x) \log p(x)/q(x)$ は、$p(x) > 0$ の点で $q(x) \to 0$ になると $\log p/q \to +\infty$ と罰則が発散します。つまり最適化は「$P$ が値を持つ場所では $Q$ もちゃんと値を持たせる」方向に動きます。この性質を mode-covering または zero-avoiding と呼びます。

$P$ が二峰性 (例: 山が2つあるガウス混合)、$Q$ をひとつのガウスで近似する場合、forward KL は両方の山をカバーする幅広い分布を選びます。表現力の高いモデルなら細かい構造も学習しますが、表現力が低いと「どちらの山にも属さない谷の中央」に平均が落ち着くこともあります。

最尤推定との関係も確かめておきましょう。データ $\{x_i\}_{i=1}^N$ が $P$ から得られたとき、

$$ D_{KL}(P \| Q_\theta) = \mathbb{E}_{x \sim P}[\log p(x)] – \mathbb{E}_{x \sim P}[\log q_\theta(x)] $$

の第1項は $\theta$ に依らない定数なので、KL の最小化は第2項の最大化、つまり対数尤度の最大化 $\max_\theta \sum_i \log q_\theta(x_i) / N$ と同値です。サンプル平均で経験分布を置けば、これがまさに最尤推定です。

Mode-seeking: reverse KL の挙動

Reverse KL の被積分項 $q(x) \log q(x)/p(x)$ では、期待値が $Q$ について取られます。$p(x) = 0$ の領域でも $q(x) > 0$ だと $\log q/p \to +\infty$ で罰則が無限大です。これを避けるには「$P$ がゼロの領域では $Q$ もゼロにする」必要があります。これが mode-seeking または zero-forcing と呼ばれる性質です。

二峰性の $P$ をひとつのガウス $Q$ で近似する場合、reverse KL は「どちらか一方の山にぴったり寄り添う」狭い分布を選びます。両方の山にまたがると、山と山の間の谷 ($p$ が小さい領域) に $q$ が広がって罰則を受けるからです。VAE の生成画像が「鮮明だが多様性に乏しい」と言われる傾向の理論的背景の一つとされます。

どちらを選ぶか

  • データから最尤でパラメータ推定 → forward KL (= MLE)
  • 扱いやすい分布族で事後分布を近似 (扱いやすさ優先) → reverse KL (= 変分推論・VAE)
  • 対称性が欲しい → JS ダイバージェンス (次節で軽く触れ、詳細は別記事へ)

「向き」の選択が結果を変えるという事実は、KL を使う人すべてが押さえておくべきポイントです。

forward KLとreverse KLによるガウス近似の挙動比較図

ここまでで KL の定義・非負性・非対称性の三本柱を押さえました。次に、機械学習の現場で頻繁に出てくるクロスエントロピーとの関係を、改めて整理します。

クロスエントロピー損失との関係

ニューラルネットの分類タスクでは、損失関数としてクロスエントロピー (cross-entropy loss) を使うのが定番です。例えば $C$ クラス分類で、データ点 $x$ の真のラベルが $y \in \{1, \dots, C\}$、モデルの予測確率が $\hat{p}_c(x)$ のとき、

$$ \mathcal{L}_{\text{CE}}(x, y) = -\log \hat{p}_y(x) $$

を最小化します。なぜこれが「正解ラベルの確率を上げる」良い損失なのか——実は、これは KL ダイバージェンスの最小化と完全に等価なのです。

一点分布で考える

真のラベル $y$ をワンホット分布 $P$ (= $y$ にのみ確率1、他は0) と見なすと、データ点 $x$ で予測すべき真の分布は $P_x$ で、$p_{x}(c) = \delta_{c, y}$。一方、モデルが出力する分布は $\hat{P}_x$ で、$\hat{p}_{x}(c) = \hat{p}_c(x)$ です。この2つのクロスエントロピーは

$$ H(P_x, \hat{P}_x) = -\sum_{c=1}^C p_x(c) \log \hat{p}_x(c) = -\log \hat{p}_y(x) $$

となり、まさにクロスエントロピー損失 $\mathcal{L}_{\text{CE}}$ と一致します。

KL との関係

クロスエントロピーとKLの関係 $D_{KL}(P\|Q) = H(P, Q) – H(P)$ を思い出すと、

$$ \mathcal{L}_{\text{CE}}(x, y) = H(P_x, \hat{P}_x) = D_{KL}(P_x \| \hat{P}_x) + H(P_x) $$

ですが、$P_x$ はワンホットで $H(P_x) = 0$ なので、

$$ \mathcal{L}_{\text{CE}}(x, y) = D_{KL}(P_x \| \hat{P}_x) $$

つまり「クロスエントロピー損失 = forward KL」なのです。データ全体について平均すれば、

$$ \mathbb{E}_x \mathcal{L}_{\text{CE}} = \mathbb{E}_x D_{KL}(P_x \| \hat{P}_x) $$

となり、モデル学習は「データから見たクラス分布」と「モデル予測分布」のKLを各データ点で最小化していることになります。これはまた、経験分布での最尤推定でもあります。

ソフトラベル (label smoothing や知識蒸留) では $P_x$ がワンホットでなくなりますが、それでもクロスエントロピー = forward KL の関係はそのまま成立します。深層学習でクロスエントロピーを使うときは、裏で常にKLを最小化していることを思い出すと、ロス設計の意図が見えやすくなります。

次に、KLが閉形式で計算できる代表例、ガウス分布間のKLを導出します。これはVAEのELBOで必ず出てくる、知っていると得をする式です。

ガウス分布間のKL — 閉形式

1次元ガウスの場合

2つの1次元正規分布 $P = \mathcal{N}(\mu_1, \sigma_1^2)$、$Q = \mathcal{N}(\mu_2, \sigma_2^2)$ のKLは、解析的に書けます。

$$ D_{KL}\!\left(\mathcal{N}(\mu_1, \sigma_1^2) \,\|\, \mathcal{N}(\mu_2, \sigma_2^2)\right) = \log \frac{\sigma_2}{\sigma_1} + \frac{\sigma_1^2 + (\mu_1 – \mu_2)^2}{2\sigma_2^2} – \frac{1}{2} $$

この式は VAE の ELBO で頻繁に登場するので、導出を追っておきます。

ガウス分布のKLを平均と標準偏差で動かしたときの曲線

導出

定義から、

$$ D_{KL}(P\|Q) = \int p(x) \log \frac{p(x)}{q(x)} dx = \mathbb{E}_{x \sim P}[\log p(x) – \log q(x)] $$

です。正規分布の対数尤度

$$ \log p(x) = -\frac{1}{2}\log(2\pi \sigma_1^2) – \frac{(x – \mu_1)^2}{2\sigma_1^2} $$

を $\log p – \log q$ の中に入れると、

$$ \log p(x) – \log q(x) = -\frac{1}{2}\log\frac{\sigma_1^2}{\sigma_2^2} – \frac{(x – \mu_1)^2}{2\sigma_1^2} + \frac{(x – \mu_2)^2}{2\sigma_2^2} $$

となります (定数 $\log 2\pi$ がキャンセル)。これの $P$ についての期待値を取ります。$x \sim P$ では $\mathbb{E}[(x – \mu_1)^2] = \sigma_1^2$ なので第2項の期待値は $-1/2$ で簡単。第3項は

$$ \mathbb{E}[(x – \mu_2)^2] = \mathbb{E}[(x – \mu_1 + \mu_1 – \mu_2)^2] = \sigma_1^2 + (\mu_1 – \mu_2)^2 $$

(分散 + 平均の差の二乗 = MSE分解、と覚えるとよい) なので、第3項の期待値は $\frac{\sigma_1^2 + (\mu_1 – \mu_2)^2}{2\sigma_2^2}$ です。まとめて、

$$ D_{KL}(P\|Q) = -\frac{1}{2}\log\frac{\sigma_1^2}{\sigma_2^2} – \frac{1}{2} + \frac{\sigma_1^2 + (\mu_1 – \mu_2)^2}{2\sigma_2^2} $$

$\log \sigma_1^2/\sigma_2^2 = 2\log \sigma_1/\sigma_2$ より $-\frac{1}{2}\log\sigma_1^2/\sigma_2^2 = \log\sigma_2/\sigma_1$ と書き直して、冒頭の公式が得られました。

標準正規分布との KL (VAE で頻出)

特に $Q = \mathcal{N}(0, 1)$ の場合、$\mu_2 = 0, \sigma_2 = 1$ を代入して

$$ D_{KL}\!\left(\mathcal{N}(\mu, \sigma^2) \,\|\, \mathcal{N}(0, 1)\right) = \frac{1}{2}\!\left(\mu^2 + \sigma^2 – 1 – 2\log\sigma\right) = \frac{1}{2}\!\left(\mu^2 + \sigma^2 – 1 – \log\sigma^2\right) $$

この式が VAE のELBOでKL正則化項 (近似事後分布 $\mathcal{N}(\mu_\phi, \sigma_\phi^2)$ と事前分布 $\mathcal{N}(0, 1)$ の差) として登場する超重要な式です。多次元 (対角共分散) なら、これを各次元について足したもの——式の形がよく VAE のコードに「-0.5 * sum(1 + log_var - mu**2 - exp(log_var))」として現れるのはこのためです。

多変量ガウスへの拡張

$d$ 次元の多変量正規分布 $P = \mathcal{N}(\boldsymbol{\mu}_1, \boldsymbol{\Sigma}_1)$、$Q = \mathcal{N}(\boldsymbol{\mu}_2, \boldsymbol{\Sigma}_2)$ では、

$$ D_{KL}(P\|Q) = \frac{1}{2}\!\left[\log \frac{|\boldsymbol{\Sigma}_2|}{|\boldsymbol{\Sigma}_1|} – d + \mathrm{tr}(\boldsymbol{\Sigma}_2^{-1} \boldsymbol{\Sigma}_1) + (\boldsymbol{\mu}_2 – \boldsymbol{\mu}_1)^\top \boldsymbol{\Sigma}_2^{-1}(\boldsymbol{\mu}_2 – \boldsymbol{\mu}_1)\right] $$

詳細な導出は 多変量正規分布の導出と性質 を参考にしてください。実装でガウス混合のEMや、ベイズ的線形回帰の事後分布のKLを計算するときに頻出します。

理論はここまで。次にPythonで実装し、定義式・閉形式・数値積分が一致することを確かめ、forward / reverse KL の挙動の違いを目で見て体感します。

Python実装

離散分布での基本計算

まず離散分布での KL を、定義式どおりの自前実装と scipy の両方で計算してみます。

import numpy as np
from scipy.special import rel_entr

def kl_divergence(p, q, eps=1e-12):
    """KL(p || q) の素朴実装 (離散カテゴリカル分布)"""
    p = np.asarray(p, dtype=float)
    q = np.asarray(q, dtype=float)
    mask = p > 0  # p=0 の点は 0 log 0 = 0 として除く
    return float(np.sum(p[mask] * np.log(p[mask] / (q[mask] + eps))))

# テスト用の2つのカテゴリカル分布 (3カテゴリ)
p = np.array([0.1, 0.4, 0.5])
q = np.array([0.2, 0.3, 0.5])

# scipy.special.rel_entr は要素ごとに p*log(p/q) を返す
kl_scipy = float(np.sum(rel_entr(p, q)))

print(f"KL(P||Q) manual: {kl_divergence(p, q):.6f}")
print(f"KL(P||Q) scipy : {kl_scipy:.6f}")
print(f"KL(Q||P) manual: {kl_divergence(q, p):.6f}  <- 非対称!")
print(f"KL(P||P) manual: {kl_divergence(p, p):.6f}  <- 同じ分布同士は 0")

このコードを実行すると、自前実装と scipy の rel_entr の総和が浮動小数点誤差レベルで一致することがわかります。また $D_{KL}(P\|Q) \neq D_{KL}(Q\|P)$ で非対称性が数値レベルで実感でき、$P = P$ なら KL がちょうど0になることでGibbsの不等式の等号条件も確認できました。

ガウス分布同士の KL: 閉形式と数値積分の一致

次に、上で導出したガウス間KLの閉形式が、数値積分の結果と一致するかを確かめます。

import numpy as np
from scipy.stats import norm

def kl_normal_analytic(mu1, sigma1, mu2, sigma2):
    """N(mu1, sigma1^2) と N(mu2, sigma2^2) の KL の閉形式"""
    return (np.log(sigma2 / sigma1)
            + (sigma1**2 + (mu1 - mu2)**2) / (2 * sigma2**2)
            - 0.5)

def kl_normal_numeric(mu1, sigma1, mu2, sigma2, x_range=(-15, 15), n=10000):
    """同じKLを数値積分でも計算 (検算用)"""
    xs = np.linspace(*x_range, n)
    p = norm.pdf(xs, mu1, sigma1)
    q = norm.pdf(xs, mu2, sigma2)
    mask = p > 1e-15
    return float(np.trapz(p[mask] * np.log(p[mask] / q[mask]), xs[mask]))

# N(0, 1) と N(1, 2)
kl_a = kl_normal_analytic(0, 1, 1, 2)
kl_n = kl_normal_numeric(0, 1, 1, 2)
print(f"KL analytic: {kl_a:.6f}")
print(f"KL numeric : {kl_n:.6f}")
print(f"差         : {abs(kl_a - kl_n):.2e}")

# 標準正規分布同士は厳密に 0
print(f"KL(N(0,1) || N(0,1)) = {kl_normal_analytic(0, 1, 0, 1):.6e}")

# VAE で頻出: N(mu, sigma^2) と N(0, 1) の KL
def kl_to_standard_normal(mu, sigma):
    return 0.5 * (mu**2 + sigma**2 - 1 - 2 * np.log(sigma))

print(f"KL(N(0.5, 0.8^2) || N(0,1)) = {kl_to_standard_normal(0.5, 0.8):.6f}")
print(f"  解析式と一致確認        = {kl_normal_analytic(0.5, 0.8, 0, 1):.6f}")

実行すると、解析式と数値積分の結果が小数点以下5〜6桁レベルで一致し、$P = Q$ なら KL がほぼ厳密にゼロになることが確認できます。VAEのKL正則化項 0.5 * (mu**2 + sigma**2 - 1 - log(sigma**2)) も同じ式の派生形であり、コード上で「0.5 * sum(mu**2 + sigma**2 - 1 - log_var)」と書くだけでガウス事前分布とのKLが計算できる手軽さの根拠が、ここで導出した閉形式にあるわけです。

Forward KL と Reverse KL の挙動を可視化

ここからが本記事の山場のひとつ、非対称性の可視化です。二峰性の真分布 $P$ をひとつのガウス $Q_\theta = \mathcal{N}(\mu, \sigma^2)$ で近似することを考え、forward KL と reverse KL それぞれを最小化して得られる $Q$ がどう違うかを見ます。

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize
from scipy.stats import norm

# 真の分布: 二峰性 (2つのガウスの混合)
def p_target(x):
    return 0.5 * norm.pdf(x, -3, 0.8) + 0.5 * norm.pdf(x, 3, 0.8)

xs = np.linspace(-8, 8, 2000)
dx = xs[1] - xs[0]
p_vals = p_target(xs)

# Forward KL: KL(P || Q) — P で平均
def forward_kl(params):
    mu, log_sigma = params
    sigma = np.exp(log_sigma)
    q_vals = norm.pdf(xs, mu, sigma)
    mask = p_vals > 1e-12
    return np.sum(p_vals[mask] * np.log(p_vals[mask] / (q_vals[mask] + 1e-12))) * dx

# Reverse KL: KL(Q || P) — Q で平均
def reverse_kl(params):
    mu, log_sigma = params
    sigma = np.exp(log_sigma)
    q_vals = norm.pdf(xs, mu, sigma)
    mask = q_vals > 1e-12
    return np.sum(q_vals[mask] * np.log(q_vals[mask] / (p_vals[mask] + 1e-12))) * dx

# それぞれを最小化
res_fwd       = minimize(forward_kl, x0=[0.0, 0.0], method='Nelder-Mead')
res_rev_left  = minimize(reverse_kl, x0=[-3.0, 0.0], method='Nelder-Mead')
res_rev_right = minimize(reverse_kl, x0=[ 3.0, 0.0], method='Nelder-Mead')

mu_f,  sig_f  = res_fwd.x[0],       np.exp(res_fwd.x[1])
mu_rL, sig_rL = res_rev_left.x[0],  np.exp(res_rev_left.x[1])
mu_rR, sig_rR = res_rev_right.x[0], np.exp(res_rev_right.x[1])

print(f"Forward KL  : mu={mu_f:.3f}, sigma={sig_f:.3f}  (mode-covering)")
print(f"Reverse KL L: mu={mu_rL:.3f}, sigma={sig_rL:.3f}  (mode-seeking, 左)")
print(f"Reverse KL R: mu={mu_rR:.3f}, sigma={sig_rR:.3f}  (mode-seeking, 右)")

# 可視化
fig, axes = plt.subplots(1, 2, figsize=(12, 5), sharey=True)
panels = [
    (mu_f,  sig_f,  f"Forward KL (mode-covering)\nmu={mu_f:.2f}, sigma={sig_f:.2f}"),
    (mu_rL, sig_rL, f"Reverse KL (mode-seeking)\nmu={mu_rL:.2f}, sigma={sig_rL:.2f}"),
]
for ax, (mu, sig, title) in zip(axes, panels):
    ax.plot(xs, p_vals, 'k-', lw=2, label='True P (bimodal)')
    ax.plot(xs, norm.pdf(xs, mu, sig), 'r--', lw=2, label='Approx Q (Gaussian)')
    ax.fill_between(xs, 0, norm.pdf(xs, mu, sig), color='red', alpha=0.15)
    ax.set_title(title)
    ax.set_xlabel('x'); ax.legend(); ax.grid(alpha=0.3)
axes[0].set_ylabel('density')
plt.tight_layout()
plt.savefig('forward_vs_reverse_kl.png', dpi=140, bbox_inches='tight')
plt.show()

この実験から、forward / reverse KL の本質的な違いがひと目でわかります。Forward KL を最小化したガウスは、平均が二峰の中央付近 ($0$ 付近) に、分散は大きめに取られ、両方の山を「カバー」する形になります——これが mode-covering の挙動です。一方、reverse KL は初期値によって左の山か右の山どちらかにぴったり寄り添う狭いガウスに収束します。両方の山にまたがると、山と山の間の谷で $p \approx 0$ なのに $q > 0$ となり、$\log q/p$ が大きな罰則を出すからです。これが mode-seeking (zero-forcing) の挙動で、reverse KLは初期値依存で異なる局所最適に到達することも体感できます。

VAEのELBOで使うのは reverse KL なので、学習の結果として「一つのモードに丁寧に寄り添う」mode-seeking な振る舞いが内包されます。生成画像が「鮮明だが多様性が乏しい」と言われる傾向の理論的根拠の一つは、ここにあるわけです。

KLの形状をサーフェスで眺める

$P = \mathcal{N}(0, 1)$ を固定し、$Q = \mathcal{N}(\mu, \sigma)$ の $(\mu, \sigma)$ を動かしたときの forward / reverse KL の形をコンター図で見ます。

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

mus    = np.linspace(-3, 3, 60)
sigmas = np.linspace(0.3, 3.0, 60)
MU, SG = np.meshgrid(mus, sigmas)

xs = np.linspace(-12, 12, 2000)
dx = xs[1] - xs[0]
p_vals = norm.pdf(xs, 0, 1)

KL_PQ = np.zeros_like(MU)
KL_QP = np.zeros_like(MU)
for i in range(MU.shape[0]):
    for j in range(MU.shape[1]):
        mu, sg = MU[i, j], SG[i, j]
        q_vals = norm.pdf(xs, mu, sg)
        mask = p_vals > 1e-12
        KL_PQ[i, j] = np.sum(p_vals[mask] * np.log(p_vals[mask] / (q_vals[mask] + 1e-12))) * dx
        mask = q_vals > 1e-12
        KL_QP[i, j] = np.sum(q_vals[mask] * np.log(q_vals[mask] / (p_vals[mask] + 1e-12))) * dx

fig, axes = plt.subplots(1, 2, figsize=(11, 4.5))
for ax, Z, title in zip(axes, [KL_PQ, KL_QP], ['KL(P||Q)  forward', 'KL(Q||P)  reverse']):
    cs = ax.contourf(MU, SG, Z, levels=20, cmap='viridis')
    plt.colorbar(cs, ax=ax)
    ax.set_xlabel('mu (Q)'); ax.set_ylabel('sigma (Q)')
    ax.set_title(title + '   (P = N(0,1) fixed)')
    ax.scatter([0], [1], color='red', s=100, marker='*', edgecolor='white', label='P=Q')
    ax.legend(loc='upper right')
plt.tight_layout()
plt.savefig('kl_surface.png', dpi=140, bbox_inches='tight')
plt.show()

2枚のコンター図を比較すると、いくつかの重要な特徴が読み取れます。まず、どちらも $(\mu, \sigma) = (0, 1)$ で最小値 $0$ を取ります (赤い星印)——これは Gibbsの不等式の等号条件 $P = Q$ そのものです。次に、forward $D_{KL}(P\|Q)$ は $\sigma$ が小さくなる方向 ($Q$ が鋭くなる方向) で急激に発散する一方、reverse $D_{KL}(Q\|P)$ は逆に $\sigma$ が大きくなる方向で罰則が増えます。これは数式直感どおり、forward は「$P$ の裾を $Q$ で覆っていないと困る」、reverse は「$Q$ が $P$ の外に質量を持ってはいけない」という挙動の現れです。

forward/reverse KLのサーフェスをμ-σ空間で比較したコンター図

VAEのELBOによる変分推論シミュレーション

最後に、変分推論の入門的シミュレーションをやります。観測モデル $p(x|z) = \mathcal{N}(z, 1)$、事前分布 $p(z) = \mathcal{N}(0, 1)$ で観測 $x = 2$ が得られたとき、事後分布 $p(z|x)$ をガウス近似 $q(z) = \mathcal{N}(\mu_q, \sigma_q^2)$ で求めます。

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
from scipy.optimize import minimize

x_obs = 2.0

# 真の事後 (今回は両方ガウスなので解析的に求まる): N(x/2, 1/2)
mu_true, sigma_true = x_obs / 2, np.sqrt(0.5)
print(f"真の事後分布   : N({mu_true:.3f}, {sigma_true**2:.3f})")

# ELBO = E_q[log p(x|z)] - KL(q || p(z))
# 第1項: 再構成項、第2項: reverse KL (= 正則化項)
def neg_elbo(params):
    mu_q, log_sigma_q = params
    sigma_q = np.exp(log_sigma_q)
    # E_q[log p(x|z)] = -0.5 ((x - mu_q)^2 + sigma_q^2) + const
    recon = -0.5 * ((x_obs - mu_q)**2 + sigma_q**2)
    # KL(N(mu_q, sigma_q^2) || N(0, 1)) の閉形式
    kl = 0.5 * (mu_q**2 + sigma_q**2 - 1 - 2 * log_sigma_q)
    return -(recon - kl)  # ELBO を最大化 = -ELBO を最小化

res = minimize(neg_elbo, x0=[0.0, 0.0], method='Nelder-Mead')
mu_q, sigma_q = res.x[0], np.exp(res.x[1])
print(f"変分近似事後   : N({mu_q:.3f}, {sigma_q**2:.3f})")
print(f"最終ELBO       : {-res.fun:.4f}")

zs = np.linspace(-2, 4, 500)
plt.figure(figsize=(8, 5))
plt.plot(zs, norm.pdf(zs, 0, 1), 'g--', alpha=0.6, label='Prior p(z) = N(0,1)')
plt.plot(zs, norm.pdf(zs, mu_true, sigma_true), 'k-',  lw=2,   label='True posterior')
plt.plot(zs, norm.pdf(zs, mu_q,    sigma_q),    'r:',  lw=2.5, label='VI approx q(z)')
plt.axvline(x_obs, color='blue', alpha=0.4, ls='--', label=f'Observation x={x_obs}')
plt.xlabel('z'); plt.ylabel('density')
plt.title('Variational inference with KL regularization')
plt.legend(); plt.grid(alpha=0.3)
plt.tight_layout()
plt.savefig('vi_kl_demo.png', dpi=140, bbox_inches='tight')
plt.show()

この簡易VAEの結果から、変分推論が真の事後分布をきれいに再現していることがわかります。観測 $x = 2$ によって事後分布の平均が事前 ($0$) と観測 ($2$) の中間 ($1$) にシフトし、観測情報により分散も狭く ($1 \to 0.5$ に) なっています。コード中で使ったKLの閉形式 0.5 * (mu**2 + sigma**2 - 1 - 2*log(sigma)) は、VAEのKL正則化項としてあらゆる実装で見る式そのものです。これが reverse KL であることに注意してください——$q_\phi$ で期待値を取る形なので、reparameterization trick によるサンプリングで勾配が伝えやすいのが実装上の利点です。

実装パートはここまで。最後に、KLが機械学習のどこで使われているかを応用先ごとに整理し、より発展的なトピックへのリンクを示します。

機械学習での役割

クロスエントロピー損失 (分類)

すでに見たとおり、分類タスクのクロスエントロピー損失は forward KL の最小化と等価です。ニューラルネットの最終層 softmax の出力 $\hat{p}_c(x)$ と真ラベル分布の KL を、ミニバッチごとに勾配降下で減らしているのが学習の正体です。

VAE のKL正則化項

変分オートエンコーダ (VAE) はELBO

$$ \mathcal{L}_{\text{ELBO}} = \underbrace{\mathbb{E}_{q_\phi(z|x)}[\log p_\theta(x|z)]}_{\text{再構成項}} – \underbrace{D_{KL}(q_\phi(z|x) \| p(z))}_{\text{KL正則化項}} $$

を最大化します。第2項のKLは reverse KL で、$q_\phi(z|x)$ と $p(z)$ がともにガウスなら本記事で導出した閉形式で勾配が直接書けます。

VAEにおけるKL正則化項の役割を示すフロー図

変分推論一般

ベイズ推論で扱いにくい事後分布 $p(z|x)$ を、扱いやすい分布族 (mean-field ガウスなど) $q_\phi(z)$ で近似する方法を 変分推論 (variational inference) と呼びます。$D_{KL}(q_\phi \| p(z|x))$ を最小化する問題が、エビデンス下界 (ELBO) の最大化と等価であることがVI全体の出発点です。MCMC より高速かつ大規模データに強く、現代ベイズ統計の主流手法の一つです。

PPO のKL制約

強化学習の PPO (Proximal Policy Optimization) は方策勾配法の代表で、新しい方策 $\pi_\theta$ が古い方策 $\pi_{\theta_{\text{old}}}$ から大きく離れすぎないように、KLペナルティを損失に入れます。

$$ \mathcal{L}(\theta) = \mathbb{E}_t \!\left[ \frac{\pi_\theta(a_t|s_t)}{\pi_{\theta_{\text{old}}}(a_t|s_t)} A_t \right] – \beta \, D_{KL}(\pi_{\theta_{\text{old}}} \| \pi_\theta) $$

これは方策更新時の「安全装置」として機能し、強化学習の悪名高い学習不安定性を大幅に和らげます。RLHF (Reinforcement Learning from Human Feedback) で大規模言語モデルを人間の好みに合わせる際にも事実上の標準アルゴリズムです。

PPOにおけるKL信頼領域による方策更新の概念図

情報量規準と統計的推論

KLダイバージェンスは赤池情報量規準 (AIC) の基礎にもなっています。AIC は「真の分布とモデル分布の KL を推定してモデル選択に使う」発想で、過学習を防ぐ古典的な手法として今も広く使われています。仮説検定の文脈でも、尤度比検定の検定統計量は本質的にKLの推定量です。

相互情報量との関係

情報理論のもう一つの重要量、相互情報量 (mutual information) も実はKLダイバージェンスで書けます。

相互情報量はKLの特殊ケース

2つの確率変数 $X, Y$ の結合分布を $p(x, y)$、周辺分布をそれぞれ $p(x), p(y)$ とするとき、相互情報量 は次で定義されます。

$$ I(X; Y) = \sum_{x, y} p(x, y) \log \frac{p(x, y)}{p(x)\, p(y)} $$

この式を見ると、$D_{KL}(P\|Q)$ の定義 $\sum_x p(x)\log\frac{p(x)}{q(x)}$ と全く同じ構造をしています。$P$ を結合分布 $p(x,y)$、$Q$ を独立を仮定したときの積分布 $p(x)p(y)$ に対応させれば、

$$ I(X; Y) = D_{KL}\!\left(p(x,y) \,\|\, p(x)p(y)\right) $$

と書けます。つまり 相互情報量 = 「実際の結合分布」と「独立を仮定した積分布」のKLダイバージェンス です。

直感的な意味

この式は「$X$ と $Y$ が独立でないことのコスト」を表しています。

  • $X$ と $Y$ が独立なら $p(x,y) = p(x)p(y)$(積分布と一致)なので、KL はゼロ → 相互情報量も $0$
  • $X$ と $Y$ に依存関係があるほど $p(x,y) \neq p(x)p(y)$ となり、KL が大きくなる → 相互情報量も大

「2つの変数がどれだけ互いに情報を持ち合っているか」を測る量が、Gibbsの不等式により常に非負になるのも、KLの非負性から自動的に保証されます。

H(X) と H(X, Y) による表現

クロスエントロピーとKLの関係 $D_{KL}(P\|Q) = H(P,Q) – H(P)$ を使うと、相互情報量はエントロピーの組み合わせとしても書けます。

$$ I(X; Y) = H(X) + H(Y) – H(X, Y) $$

ここで $H(X) = -\sum_x p(x)\log p(x)$ は $X$ のエントロピー(不確かさの量)、$H(X, Y)$ は結合エントロピーです。$X$ の不確かさ + $Y$ の不確かさ − ペアとして同時に見たときの不確かさ、この差分が「互いに共有している情報量」というわけです。

Pythonで確認

import numpy as np
import itertools

# 結合分布の例 (3x2 の離散分布)
p_xy = np.array([[0.30, 0.10],
                 [0.10, 0.20],
                 [0.05, 0.25]])

p_x = p_xy.sum(axis=1)  # 周辺分布 P(X)
p_y = p_xy.sum(axis=0)  # 周辺分布 P(Y)

# 方法1: I(X;Y) = KL(p(x,y) || p(x)*p(y))
mi_kl = sum(
    p_xy[i, j] * np.log(p_xy[i, j] / (p_x[i] * p_y[j]))
    for i, j in itertools.product(range(3), range(2))
    if p_xy[i, j] > 0
)

# 方法2: I(X;Y) = H(X) + H(Y) - H(X,Y)
H_X  = -np.sum(p_x * np.log(p_x))
H_Y  = -np.sum(p_y * np.log(p_y))
H_XY = -np.sum(p_xy * np.log(p_xy + 1e-300))
mi_h = H_X + H_Y - H_XY

print(f"I(X;Y) via KL : {mi_kl:.6f}")
print(f"I(X;Y) via H  : {mi_h:.6f}")
print(f"差 (丸め誤差) : {abs(mi_kl - mi_h):.2e}")

2つの計算方法が丸め誤差レベル ($\approx 10^{-16}$) で一致し、「相互情報量 = KL」の等価性を数値で確認できます。mi_kl が KL の定義式そのままであり、mi_h がエントロピーの加減算であることを見比べると、情報理論の各量が同じ基盤から派生していることが実感できます。独立な分布($p_{xy}$ の行を一様にした場合など)では mi_kl = 0 に収束することも試してみてください。

KLダイバージェンスがエントロピー・交差エントロピー・相互情報量をつなぐ中心的な量であることがわかったところで、最後に応用先を整理します。

まとめ

本記事では、確率分布の差を測る最重要量 KLダイバージェンス について、定義・直感的意味・性質・閉形式・応用までを通しで解説しました。

  • 定義: $D_{KL}(P \| Q) = \sum_x p(x) \log \frac{p(x)}{q(x)} = \mathbb{E}_{x \sim P}[\log p(x)/q(x)]$ — 「$P$ から $x$ をサンプルしたときの対数尤度比の期待値」
  • 符号化的意味: $D_{KL}(P\|Q) = H(P, Q) – H(P)$ — 「$P$ から出るデータを誤った $Q$ で符号化したときの余分なビット数」(相対エントロピー)
  • Gibbsの不等式: $\log x \leq x – 1$ から $D_{KL} \geq 0$ を導き、等号は $P = Q$ のときに限る
  • 非対称性: forward KL は mode-covering で最尤推定と等価、reverse KL は mode-seeking で変分推論で使う
  • クロスエントロピー損失: 一点分布 (ワンホット) との forward KL に等しい
  • ガウス分布間のKL: 閉形式 $\log(\sigma_2/\sigma_1) + (\sigma_1^2 + (\mu_1-\mu_2)^2)/(2\sigma_2^2) – 1/2$ がVAEで頻出
  • 相互情報量: $I(X;Y) = D_{KL}(p(x,y) \| p(x)p(y))$ — 結合分布と積分布のKL。独立なら0、依存があるほど大きい
  • 応用: クロスエントロピー損失・VAE のKL正則化・変分推論・PPO・AIC など、現代の機械学習・統計の至るところに登場

Python実装では、定義式どおりの計算、scipyのrel_entr との一致、ガウス間KLの閉形式と数値積分の一致、forward / reverse KL の最適化結果の挙動の違いの可視化、変分推論の入門例まで一通り体験しました。とくに「同じ真分布に対してforward / reverseで異なる近似に収束する」可視化は、KLを使うあらゆる現場で押さえておきたい重要な事実です。

より発展的な内容へ

本記事はKLダイバージェンスの入門・基礎編として、定義・直感・性質と最尤推定/VAE への応用に焦点を絞りました。さらに踏み込んだ内容——JSダイバージェンスによる対称化、Wasserstein距離との比較、GAN/WGAN への応用、勾配消失問題の理論的根拠——については、別記事で深掘り解説しています。

画像なし
KLダイバージェンスとJSダイバージェンス — 確率分布間の距離と機械学習への応用
KLの対称化版JSダイバージェンス、Wasserstein距離との比較、GANの勾配消失問題とWGAN、t-SNEへの応用までを発展的に解説します。
相互情報量とは?定義と性質をわかりやすく解説
相互情報量の定義・性質をエントロピーやKLダイバージェンスとの関係から解説。条件付き相互情報量、結合エントロピーとのベン図的理解、Pythonでの計算まで。
確率変数のエントロピーとは?確率分布における情報量まとめ
エントロピー・自己情報量・ジョイントエントロピーを定義から導出し、KLダイバージェンスや相互情報量との関係をわかりやすく解説します。

次のステップとして、以下の記事も参考にしてください。