多変量正規分布(多次元ガウス分布)は、機械学習・統計学・信号処理において最も重要な確率分布の一つです。その特に強力な性質として、「多変量正規分布を変数のグループに分割したとき、周辺分布も条件付き分布も正規分布になる」というものがあります。
この性質は、ガウス過程回帰、カルマンフィルタ、ベイズ線形回帰など、多くのアルゴリズムの理論的基盤を提供しています。
本記事では、ブロック行列の逆行列とシューア補行列を使って、周辺分布と条件付き分布の公式を完全に導出します。
本記事の内容
- 多変量正規分布の分割表現
- 周辺分布が正規分布になることの導出
- 条件付き分布の導出(シューア補行列を使った完全な証明)
- 条件付き平均 $\bm{\mu}_{a|b}$ と条件付き共分散 $\bm{\Sigma}_{a|b}$ の公式
- ガウス過程回帰への接続
- Pythonで2変量正規分布の可視化
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
多変量正規分布の分割表現
分割の設定
$n$ 次元の確率変数ベクトル $\bm{x}$ を、$n_a$ 次元の $\bm{x}_a$ と $n_b$ 次元の $\bm{x}_b$($n_a + n_b = n$)に分割します。
$$ \bm{x} = \begin{pmatrix} \bm{x}_a \\ \bm{x}_b \end{pmatrix} $$
対応して、平均ベクトルと共分散行列も分割します。
$$ \bm{\mu} = \begin{pmatrix} \bm{\mu}_a \\ \bm{\mu}_b \end{pmatrix}, \quad \bm{\Sigma} = \begin{pmatrix} \bm{\Sigma}_{aa} & \bm{\Sigma}_{ab} \\ \bm{\Sigma}_{ba} & \bm{\Sigma}_{bb} \end{pmatrix} $$
ここで、
- $\bm{\mu}_a \in \mathbb{R}^{n_a}$, $\bm{\mu}_b \in \mathbb{R}^{n_b}$: 各グループの平均ベクトル
- $\bm{\Sigma}_{aa} \in \mathbb{R}^{n_a \times n_a}$: $\bm{x}_a$ の共分散行列
- $\bm{\Sigma}_{bb} \in \mathbb{R}^{n_b \times n_b}$: $\bm{x}_b$ の共分散行列
- $\bm{\Sigma}_{ab} = \bm{\Sigma}_{ba}^T \in \mathbb{R}^{n_a \times n_b}$: $\bm{x}_a$ と $\bm{x}_b$ の交差共分散行列
多変量正規分布の確率密度関数
$$ p(\bm{x}) = \frac{1}{(2\pi)^{n/2} |\bm{\Sigma}|^{1/2}} \exp\left( -\frac{1}{2} (\bm{x} – \bm{\mu})^T \bm{\Sigma}^{-1} (\bm{x} – \bm{\mu}) \right) $$
シューア補行列
条件付き分布の導出で重要な役割を果たすのがシューア補行列(Schur complement)です。
定義
ブロック行列 $\bm{M} = \begin{pmatrix} \bm{A} & \bm{B} \\ \bm{C} & \bm{D} \end{pmatrix}$ に対して、
- $\bm{D}$ に関する $\bm{M}$ のシューア補行列: $\bm{M}/\bm{D} = \bm{A} – \bm{B}\bm{D}^{-1}\bm{C}$
- $\bm{A}$ に関する $\bm{M}$ のシューア補行列: $\bm{M}/\bm{A} = \bm{D} – \bm{C}\bm{A}^{-1}\bm{B}$
ブロック行列の逆行列
$\bm{\Sigma}$ の逆行列(精度行列)$\bm{\Lambda} = \bm{\Sigma}^{-1}$ をブロック形式で求めます。
$$ \bm{\Lambda} = \bm{\Sigma}^{-1} = \begin{pmatrix} \bm{\Sigma}_{aa} & \bm{\Sigma}_{ab} \\ \bm{\Sigma}_{ba} & \bm{\Sigma}_{bb} \end{pmatrix}^{-1} = \begin{pmatrix} \bm{\Lambda}_{aa} & \bm{\Lambda}_{ab} \\ \bm{\Lambda}_{ba} & \bm{\Lambda}_{bb} \end{pmatrix} $$
ブロック行列の逆行列の公式を導出します。$\bm{\Sigma}\bm{\Lambda} = \bm{I}$ より、
$$ \begin{pmatrix} \bm{\Sigma}_{aa} & \bm{\Sigma}_{ab} \\ \bm{\Sigma}_{ba} & \bm{\Sigma}_{bb} \end{pmatrix} \begin{pmatrix} \bm{\Lambda}_{aa} & \bm{\Lambda}_{ab} \\ \bm{\Lambda}_{ba} & \bm{\Lambda}_{bb} \end{pmatrix} = \begin{pmatrix} \bm{I}_{n_a} & \bm{0} \\ \bm{0} & \bm{I}_{n_b} \end{pmatrix} $$
これを4つのブロック方程式に分解します。
$$ \begin{align} \bm{\Sigma}_{aa}\bm{\Lambda}_{aa} + \bm{\Sigma}_{ab}\bm{\Lambda}_{ba} &= \bm{I}_{n_a} \tag{1} \\ \bm{\Sigma}_{aa}\bm{\Lambda}_{ab} + \bm{\Sigma}_{ab}\bm{\Lambda}_{bb} &= \bm{0} \tag{2} \\ \bm{\Sigma}_{ba}\bm{\Lambda}_{aa} + \bm{\Sigma}_{bb}\bm{\Lambda}_{ba} &= \bm{0} \tag{3} \\ \bm{\Sigma}_{ba}\bm{\Lambda}_{ab} + \bm{\Sigma}_{bb}\bm{\Lambda}_{bb} &= \bm{I}_{n_b} \tag{4} \end{align} $$
(3) より $\bm{\Lambda}_{ba} = -\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba}\bm{\Lambda}_{aa}$ を (1) に代入:
$$ \begin{align} \bm{\Sigma}_{aa}\bm{\Lambda}_{aa} – \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba}\bm{\Lambda}_{aa} &= \bm{I}_{n_a} \\ (\bm{\Sigma}_{aa} – \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba})\bm{\Lambda}_{aa} &= \bm{I}_{n_a} \end{align} $$
したがって、
$$ \boxed{\bm{\Lambda}_{aa} = (\bm{\Sigma}_{aa} – \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba})^{-1} = (\bm{\Sigma}/\bm{\Sigma}_{bb})^{-1}} $$
同様に (2) より $\bm{\Lambda}_{ab} = -\bm{\Sigma}_{aa}^{-1}\bm{\Sigma}_{ab}\bm{\Lambda}_{bb}$ を (4) に代入:
$$ \begin{align} -\bm{\Sigma}_{ba}\bm{\Sigma}_{aa}^{-1}\bm{\Sigma}_{ab}\bm{\Lambda}_{bb} + \bm{\Sigma}_{bb}\bm{\Lambda}_{bb} &= \bm{I}_{n_b} \\ (\bm{\Sigma}_{bb} – \bm{\Sigma}_{ba}\bm{\Sigma}_{aa}^{-1}\bm{\Sigma}_{ab})\bm{\Lambda}_{bb} &= \bm{I}_{n_b} \end{align} $$
$$ \boxed{\bm{\Lambda}_{bb} = (\bm{\Sigma}_{bb} – \bm{\Sigma}_{ba}\bm{\Sigma}_{aa}^{-1}\bm{\Sigma}_{ab})^{-1} = (\bm{\Sigma}/\bm{\Sigma}_{aa})^{-1}} $$
非対角ブロックは:
$$ \bm{\Lambda}_{ab} = -\bm{\Lambda}_{aa}\bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}, \quad \bm{\Lambda}_{ba} = -\bm{\Lambda}_{bb}\bm{\Sigma}_{ba}\bm{\Sigma}_{aa}^{-1} $$
行列式の公式
ブロック行列の行列式は、シューア補行列を用いて
$$ |\bm{\Sigma}| = |\bm{\Sigma}_{bb}| \cdot |\bm{\Sigma}_{aa} – \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba}| $$
と書けます。この公式は後の導出で使います。
周辺分布の導出
定理
$\bm{x} = (\bm{x}_a^T, \bm{x}_b^T)^T \sim \mathcal{N}(\bm{\mu}, \bm{\Sigma})$ のとき、
$$ \boxed{\bm{x}_a \sim \mathcal{N}(\bm{\mu}_a, \bm{\Sigma}_{aa})} $$
$$ \boxed{\bm{x}_b \sim \mathcal{N}(\bm{\mu}_b, \bm{\Sigma}_{bb})} $$
証明
周辺分布 $p(\bm{x}_a)$ は、同時分布 $p(\bm{x}_a, \bm{x}_b)$ を $\bm{x}_b$ について積分することで得られます。
$$ p(\bm{x}_a) = \int p(\bm{x}_a, \bm{x}_b) \, d\bm{x}_b $$
指数部分の二次形式を $\bm{x}_b$ について平方完成します。$\bm{y}_a = \bm{x}_a – \bm{\mu}_a$, $\bm{y}_b = \bm{x}_b – \bm{\mu}_b$ と変数変換すると、
$$ Q = (\bm{x} – \bm{\mu})^T \bm{\Sigma}^{-1} (\bm{x} – \bm{\mu}) = \begin{pmatrix} \bm{y}_a \\ \bm{y}_b \end{pmatrix}^T \begin{pmatrix} \bm{\Lambda}_{aa} & \bm{\Lambda}_{ab} \\ \bm{\Lambda}_{ba} & \bm{\Lambda}_{bb} \end{pmatrix} \begin{pmatrix} \bm{y}_a \\ \bm{y}_b \end{pmatrix} $$
展開すると、
$$ Q = \bm{y}_a^T \bm{\Lambda}_{aa} \bm{y}_a + 2\bm{y}_a^T \bm{\Lambda}_{ab} \bm{y}_b + \bm{y}_b^T \bm{\Lambda}_{bb} \bm{y}_b $$
$\bm{y}_b$ について平方完成します。
$$ \begin{align} Q &= \bm{y}_b^T \bm{\Lambda}_{bb} \bm{y}_b + 2\bm{y}_a^T \bm{\Lambda}_{ab} \bm{y}_b + \bm{y}_a^T \bm{\Lambda}_{aa} \bm{y}_a \\ &= (\bm{y}_b + \bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba}\bm{y}_a)^T \bm{\Lambda}_{bb} (\bm{y}_b + \bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba}\bm{y}_a) \\ &\quad + \bm{y}_a^T (\bm{\Lambda}_{aa} – \bm{\Lambda}_{ab}\bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba}) \bm{y}_a \end{align} $$
ここで $\bm{\Lambda}_{ab} = \bm{\Lambda}_{ba}^T$ を使いました。平方完成のステップを詳しく示します。
$\bm{y}_b$ の二次形式 $\bm{y}_b^T \bm{\Lambda}_{bb} \bm{y}_b + 2\bm{y}_a^T \bm{\Lambda}_{ab} \bm{y}_b$ を完成させます。
$$ \begin{align} &\bm{y}_b^T \bm{\Lambda}_{bb} \bm{y}_b + 2\bm{y}_a^T \bm{\Lambda}_{ab} \bm{y}_b \\ &= \bm{y}_b^T \bm{\Lambda}_{bb} \bm{y}_b + \bm{y}_b^T \bm{\Lambda}_{ba}\bm{y}_a + \bm{y}_a^T \bm{\Lambda}_{ab} \bm{y}_b \\ &= (\bm{y}_b + \bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba}\bm{y}_a)^T \bm{\Lambda}_{bb} (\bm{y}_b + \bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba}\bm{y}_a) – \bm{y}_a^T \bm{\Lambda}_{ab}\bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba}\bm{y}_a \end{align} $$
したがって、
$$ Q = \underbrace{(\bm{y}_b + \bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba}\bm{y}_a)^T \bm{\Lambda}_{bb} (\bm{y}_b + \bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba}\bm{y}_a)}_{\text{(I): } \bm{y}_b \text{に依存}} + \underbrace{\bm{y}_a^T (\bm{\Lambda}_{aa} – \bm{\Lambda}_{ab}\bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba}) \bm{y}_a}_{\text{(II): } \bm{y}_a \text{のみに依存}} $$
$\bm{x}_b$ について積分すると、(I) の部分がガウス積分になります。$\bm{z} = \bm{y}_b + \bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba}\bm{y}_a$ と置換すると(ヤコビアンは $1$)、
$$ \int \exp\left(-\frac{1}{2}\bm{z}^T\bm{\Lambda}_{bb}\bm{z}\right) d\bm{z} = (2\pi)^{n_b/2} |\bm{\Lambda}_{bb}|^{-1/2} $$
したがって、
$$ p(\bm{x}_a) = \frac{(2\pi)^{n_b/2} |\bm{\Lambda}_{bb}|^{-1/2}}{(2\pi)^{n/2} |\bm{\Sigma}|^{1/2}} \exp\left(-\frac{1}{2}\bm{y}_a^T (\bm{\Lambda}_{aa} – \bm{\Lambda}_{ab}\bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba}) \bm{y}_a\right) $$
正規化定数を整理します。$n = n_a + n_b$ なので $(2\pi)^{n_b/2} / (2\pi)^{n/2} = (2\pi)^{-n_a/2}$ です。
ブロック行列の逆行列から $\bm{\Lambda}_{bb} = (\bm{\Sigma}_{bb} – \bm{\Sigma}_{ba}\bm{\Sigma}_{aa}^{-1}\bm{\Sigma}_{ab})^{-1}$ であり、行列式の公式より
$$ |\bm{\Sigma}| = |\bm{\Sigma}_{aa}| \cdot |\bm{\Sigma}_{bb} – \bm{\Sigma}_{ba}\bm{\Sigma}_{aa}^{-1}\bm{\Sigma}_{ab}| = |\bm{\Sigma}_{aa}| \cdot |\bm{\Lambda}_{bb}|^{-1} $$
したがって $|\bm{\Lambda}_{bb}|^{-1/2} / |\bm{\Sigma}|^{1/2} = 1 / |\bm{\Sigma}_{aa}|^{1/2}$ です。
また、$\bm{\Lambda}_{aa} – \bm{\Lambda}_{ab}\bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba} = \bm{\Sigma}_{aa}^{-1}$ であることを示します。
ブロック行列の逆行列の公式から、$\bm{\Lambda}_{aa} = (\bm{\Sigma}_{aa} – \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba})^{-1}$ であり、$\bm{\Lambda}_{ab} = -\bm{\Lambda}_{aa}\bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}$, $\bm{\Lambda}_{ba} = -\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba}\bm{\Lambda}_{aa}$ です。
$$ \begin{align} \bm{\Lambda}_{ab}\bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba} &= (-\bm{\Lambda}_{aa}\bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1})\bm{\Lambda}_{bb}^{-1}(-\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba}\bm{\Lambda}_{aa}) \\ &= \bm{\Lambda}_{aa}\bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}(\bm{\Sigma}_{bb} – \bm{\Sigma}_{ba}\bm{\Sigma}_{aa}^{-1}\bm{\Sigma}_{ab})\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba}\bm{\Lambda}_{aa} \end{align} $$
ここで $\bm{\Lambda}_{bb}^{-1} = \bm{\Sigma}_{bb} – \bm{\Sigma}_{ba}\bm{\Sigma}_{aa}^{-1}\bm{\Sigma}_{ab}$ を代入しました。これを展開すると長くなるため、別のアプローチを使います。
$(\bm{\Sigma}^{-1})$ 全体の逆行列の $(a,a)$ ブロックのシューア補行列を考えます。
$$ (\bm{\Lambda}/\bm{\Lambda}_{bb})^{-1} = (\bm{\Lambda}_{aa} – \bm{\Lambda}_{ab}\bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba})^{-1} $$
$\bm{\Lambda} = \bm{\Sigma}^{-1}$ なので、$(\bm{\Lambda}/\bm{\Lambda}_{bb})^{-1}$ は $\bm{\Sigma}$ の $(a,a)$ ブロック、すなわち $\bm{\Sigma}_{aa}$ に等しくなります。
これはブロック行列の逆行列の一般的な性質です。$\bm{M}^{-1}$ のブロック $(1,1)$ のシューア補行列は、$\bm{M}$ のブロック $(1,1)$ そのものです。
$$ \bm{\Lambda}_{aa} – \bm{\Lambda}_{ab}\bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba} = \bm{\Sigma}_{aa}^{-1} $$
以上をまとめると、
$$ p(\bm{x}_a) = \frac{1}{(2\pi)^{n_a/2}|\bm{\Sigma}_{aa}|^{1/2}} \exp\left(-\frac{1}{2}(\bm{x}_a – \bm{\mu}_a)^T \bm{\Sigma}_{aa}^{-1} (\bm{x}_a – \bm{\mu}_a)\right) $$
これは $\mathcal{N}(\bm{\mu}_a, \bm{\Sigma}_{aa})$ の密度関数です。 $\square$
条件付き分布の導出
定理
$$ \boxed{\bm{x}_a \mid \bm{x}_b \sim \mathcal{N}(\bm{\mu}_{a|b}, \bm{\Sigma}_{a|b})} $$
ここで、
$$ \boxed{\bm{\mu}_{a|b} = \bm{\mu}_a + \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}(\bm{x}_b – \bm{\mu}_b)} $$
$$ \boxed{\bm{\Sigma}_{a|b} = \bm{\Sigma}_{aa} – \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba}} $$
証明
条件付き分布は $p(\bm{x}_a \mid \bm{x}_b) = p(\bm{x}_a, \bm{x}_b) / p(\bm{x}_b)$ で定義されます。$p(\bm{x}_b)$ は $\bm{x}_a$ に依存しないので、$\bm{x}_a$ に関する関数形を見れば十分です。
同時分布の指数部分の二次形式を再び考えます。先ほどの平方完成の結果を使います。
$$ Q = (\bm{y}_b + \bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba}\bm{y}_a)^T \bm{\Lambda}_{bb} (\bm{y}_b + \bm{\Lambda}_{bb}^{-1}\bm{\Lambda}_{ba}\bm{y}_a) + \bm{y}_a^T \bm{\Sigma}_{aa}^{-1} \bm{y}_a $$
ただし、ここでは $\bm{x}_b$ を固定して $\bm{x}_a$ について平方完成したいので、別の分解を行います。
$Q$ を $\bm{y}_a$ について整理します。
$$ Q = \bm{y}_a^T \bm{\Lambda}_{aa} \bm{y}_a + 2\bm{y}_a^T \bm{\Lambda}_{ab}\bm{y}_b + \bm{y}_b^T \bm{\Lambda}_{bb} \bm{y}_b $$
$\bm{y}_a$ について平方完成します。
$$ \begin{align} Q &= (\bm{y}_a + \bm{\Lambda}_{aa}^{-1}\bm{\Lambda}_{ab}\bm{y}_b)^T \bm{\Lambda}_{aa} (\bm{y}_a + \bm{\Lambda}_{aa}^{-1}\bm{\Lambda}_{ab}\bm{y}_b) \\ &\quad + \bm{y}_b^T (\bm{\Lambda}_{bb} – \bm{\Lambda}_{ba}\bm{\Lambda}_{aa}^{-1}\bm{\Lambda}_{ab}) \bm{y}_b \end{align} $$
平方完成のステップを詳しく示します。
$$ \begin{align} &\bm{y}_a^T \bm{\Lambda}_{aa} \bm{y}_a + 2\bm{y}_a^T \bm{\Lambda}_{ab}\bm{y}_b \\ &= \bm{y}_a^T \bm{\Lambda}_{aa} \bm{y}_a + \bm{y}_a^T \bm{\Lambda}_{ab}\bm{y}_b + \bm{y}_b^T \bm{\Lambda}_{ba}\bm{y}_a \\ &= (\bm{y}_a + \bm{\Lambda}_{aa}^{-1}\bm{\Lambda}_{ab}\bm{y}_b)^T \bm{\Lambda}_{aa} (\bm{y}_a + \bm{\Lambda}_{aa}^{-1}\bm{\Lambda}_{ab}\bm{y}_b) – \bm{y}_b^T\bm{\Lambda}_{ba}\bm{\Lambda}_{aa}^{-1}\bm{\Lambda}_{ab}\bm{y}_b \end{align} $$
条件付き分布では第2項($\bm{y}_b$ のみに依存する項)は正規化定数に吸収されるので、$\bm{x}_a$ に依存する部分だけを取り出すと、
$$ p(\bm{x}_a \mid \bm{x}_b) \propto \exp\left(-\frac{1}{2}(\bm{y}_a + \bm{\Lambda}_{aa}^{-1}\bm{\Lambda}_{ab}\bm{y}_b)^T \bm{\Lambda}_{aa} (\bm{y}_a + \bm{\Lambda}_{aa}^{-1}\bm{\Lambda}_{ab}\bm{y}_b)\right) $$
これは $\bm{x}_a$ に関する正規分布の形をしています。
条件付き共分散:
精度行列が $\bm{\Lambda}_{aa}$ なので、共分散行列は
$$ \bm{\Sigma}_{a|b} = \bm{\Lambda}_{aa}^{-1} = \bm{\Sigma}_{aa} – \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba} $$
ここで $\bm{\Lambda}_{aa} = (\bm{\Sigma}_{aa} – \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba})^{-1}$ を使いました。
条件付き平均:
$\bm{y}_a = \bm{x}_a – \bm{\mu}_a$, $\bm{y}_b = \bm{x}_b – \bm{\mu}_b$ を代入すると、中心は $\bm{y}_a = -\bm{\Lambda}_{aa}^{-1}\bm{\Lambda}_{ab}\bm{y}_b$ で、つまり
$$ \begin{align} \bm{x}_a – \bm{\mu}_a &= -\bm{\Lambda}_{aa}^{-1}\bm{\Lambda}_{ab}(\bm{x}_b – \bm{\mu}_b) \end{align} $$
$\bm{\Lambda}_{aa}^{-1}\bm{\Lambda}_{ab}$ を $\bm{\Sigma}$ の成分で表します。
$$ \bm{\Lambda}_{ab} = -\bm{\Lambda}_{aa}\bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1} $$
なので、
$$ -\bm{\Lambda}_{aa}^{-1}\bm{\Lambda}_{ab} = \bm{\Lambda}_{aa}^{-1}\bm{\Lambda}_{aa}\bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1} = \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1} $$
したがって、
$$ \bm{\mu}_{a|b} = \bm{\mu}_a + \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}(\bm{x}_b – \bm{\mu}_b) \qquad \square $$
結果のまとめと解釈
条件付き分布の公式をまとめます。
$$ \bm{x}_a \mid \bm{x}_b \sim \mathcal{N}(\bm{\mu}_{a|b}, \bm{\Sigma}_{a|b}) $$
条件付き平均:
$$ \bm{\mu}_{a|b} = \bm{\mu}_a + \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}(\bm{x}_b – \bm{\mu}_b) $$
- $\bm{\mu}_a$: 事前の平均
- $\bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}$: 回帰係数行列
- $\bm{x}_b – \bm{\mu}_b$: 観測の偏差
- 条件付き平均は $\bm{x}_b$ の線形関数
条件付き共分散:
$$ \bm{\Sigma}_{a|b} = \bm{\Sigma}_{aa} – \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba} $$
- $\bm{\Sigma}_{aa}$: 事前の共分散
- $\bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba}$: $\bm{x}_b$ の観測によって減少する不確実性
- 条件付き共分散は $\bm{x}_b$ の値に依存しない(正規分布の重要な性質)
具体例: 2変量正規分布
2変量正規分布 $\bm{x} = (x_1, x_2)^T$ で具体的に計算します。
$$ \bm{\mu} = \begin{pmatrix} 0 \\ 1 \end{pmatrix}, \quad \bm{\Sigma} = \begin{pmatrix} 1 & 0.8 \\ 0.8 & 2 \end{pmatrix} $$
$x_2 = 2$ が観測されたときの $x_1$ の条件付き分布を求めます。
条件付き平均:
$$ \mu_{1|2} = 0 + 0.8 \cdot 2^{-1} \cdot (2 – 1) = 0.4 $$
条件付き分散:
$$ \sigma_{1|2}^2 = 1 – 0.8 \cdot 2^{-1} \cdot 0.8 = 1 – 0.32 = 0.68 $$
したがって $x_1 \mid x_2 = 2 \sim \mathcal{N}(0.4, 0.68)$ です。
ガウス過程回帰への接続
ガウス過程回帰の設定
ガウス過程回帰(Gaussian Process Regression, GPR)は、本記事の条件付き分布の公式をそのまま適用したものです。
$n$ 個の訓練データ $(\bm{X}, \bm{y})$ と $n_*$ 個のテストデータ $\bm{X}_*$ が与えられたとき、
$$ \begin{pmatrix} \bm{y} \\ \bm{f}_* \end{pmatrix} \sim \mathcal{N}\left( \begin{pmatrix} \bm{0} \\ \bm{0} \end{pmatrix}, \begin{pmatrix} \bm{K} + \sigma_n^2 \bm{I} & \bm{K}_* \\ \bm{K}_*^T & \bm{K}_{**} \end{pmatrix} \right) $$
ここで $\bm{K}$, $\bm{K}_*$, $\bm{K}_{**}$ はカーネル行列です。
条件付き分布の公式を適用すると、
$$ \bm{f}_* \mid \bm{y} \sim \mathcal{N}(\bm{\mu}_*, \bm{\Sigma}_*) $$
$$ \bm{\mu}_* = \bm{K}_*^T (\bm{K} + \sigma_n^2 \bm{I})^{-1} \bm{y} $$
$$ \bm{\Sigma}_* = \bm{K}_{**} – \bm{K}_*^T (\bm{K} + \sigma_n^2 \bm{I})^{-1} \bm{K}_* $$
これはまさに先ほどの $\bm{\mu}_{a|b}$ と $\bm{\Sigma}_{a|b}$ の公式そのものです。
Pythonでの可視化
2変量正規分布の周辺分布と条件付き分布
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import multivariate_normal, norm
# パラメータの設定
mu = np.array([0, 1])
Sigma = np.array([[1.0, 0.8],
[0.8, 2.0]])
# 条件付き分布の計算
def conditional_normal(mu, Sigma, x_b, idx_a=0, idx_b=1):
"""
多変量正規分布の条件付き分布を計算
x_a | x_b の平均と分散を返す
"""
mu_a = mu[idx_a]
mu_b = mu[idx_b]
sigma_aa = Sigma[idx_a, idx_a]
sigma_bb = Sigma[idx_b, idx_b]
sigma_ab = Sigma[idx_a, idx_b]
# 条件付き平均
mu_cond = mu_a + sigma_ab / sigma_bb * (x_b - mu_b)
# 条件付き分散
sigma_cond = sigma_aa - sigma_ab**2 / sigma_bb
return mu_cond, sigma_cond
# メッシュグリッドの作成
x1 = np.linspace(-3, 3, 200)
x2 = np.linspace(-3, 5, 200)
X1, X2 = np.meshgrid(x1, x2)
pos = np.dstack((X1, X2))
# 同時分布の密度
rv = multivariate_normal(mu, Sigma)
Z = rv.pdf(pos)
# 条件付き分布の例(x2 = 2)
x2_cond = 2.0
mu_cond, sigma_cond = conditional_normal(mu, Sigma, x2_cond)
print(f"条件付き分布: x1 | x2={x2_cond}")
print(f" 平均: {mu_cond:.4f}")
print(f" 分散: {sigma_cond:.4f}")
print(f" 標準偏差: {np.sqrt(sigma_cond):.4f}")
# 可視化
fig = plt.figure(figsize=(14, 10))
# メインの等高線プロット
ax_main = fig.add_axes([0.15, 0.15, 0.55, 0.55])
ax_main.contourf(X1, X2, Z, levels=20, cmap='Blues', alpha=0.7)
ax_main.contour(X1, X2, Z, levels=10, colors='steelblue', linewidths=0.5)
# 条件付けの線
ax_main.axhline(x2_cond, color='red', linewidth=2, linestyle='--',
label=f'$x_2 = {x2_cond}$')
# 条件付き分布の平均を点で表示
ax_main.plot(mu_cond, x2_cond, 'ro', markersize=8)
ax_main.set_xlabel('$x_1$', fontsize=13)
ax_main.set_ylabel('$x_2$', fontsize=13)
ax_main.set_title('Bivariate normal distribution', fontsize=14)
ax_main.legend(fontsize=11, loc='lower right')
# 上側: x1の周辺分布
ax_top = fig.add_axes([0.15, 0.72, 0.55, 0.2])
# 周辺分布 p(x1)
marginal_x1 = norm(mu[0], np.sqrt(Sigma[0, 0]))
ax_top.plot(x1, marginal_x1.pdf(x1), 'b-', linewidth=2,
label=f'$p(x_1)$: $\\mathcal{{N}}({mu[0]}, {Sigma[0,0]})$')
# 条件付き分布 p(x1|x2=2)
cond_dist = norm(mu_cond, np.sqrt(sigma_cond))
ax_top.plot(x1, cond_dist.pdf(x1), 'r-', linewidth=2,
label=f'$p(x_1|x_2={x2_cond})$: $\\mathcal{{N}}({mu_cond:.2f}, {sigma_cond:.2f})$')
ax_top.fill_between(x1, cond_dist.pdf(x1), alpha=0.2, color='red')
ax_top.set_xlim(-3, 3)
ax_top.set_ylabel('Density', fontsize=11)
ax_top.legend(fontsize=10)
ax_top.set_title('Marginal and conditional distribution of $x_1$', fontsize=12)
# 右側: x2の周辺分布
ax_right = fig.add_axes([0.72, 0.15, 0.2, 0.55])
marginal_x2 = norm(mu[1], np.sqrt(Sigma[1, 1]))
ax_right.plot(marginal_x2.pdf(x2), x2, 'b-', linewidth=2,
label=f'$p(x_2)$')
ax_right.axhline(x2_cond, color='red', linewidth=1.5, linestyle='--')
ax_right.set_ylim(-3, 5)
ax_right.set_xlabel('Density', fontsize=11)
ax_right.legend(fontsize=10)
ax_right.set_title('Marginal $p(x_2)$', fontsize=12)
plt.show()
条件付き分布の変化
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
# パラメータの設定
mu = np.array([0, 1])
Sigma = np.array([[1.0, 0.8],
[0.8, 2.0]])
def conditional_normal_1d(mu, Sigma, x_b):
"""x1 | x2 = x_b の条件付き分布"""
mu_cond = mu[0] + Sigma[0, 1] / Sigma[1, 1] * (x_b - mu[1])
sigma_cond = Sigma[0, 0] - Sigma[0, 1]**2 / Sigma[1, 1]
return mu_cond, sigma_cond
# さまざまなx2の値での条件付き分布
x2_values = [-1, 0, 1, 2, 3]
x1_range = np.linspace(-4, 4, 300)
fig, axes = plt.subplots(1, 2, figsize=(14, 6))
# 左: 条件付き分布の密度関数
ax = axes[0]
colors = plt.cm.viridis(np.linspace(0, 1, len(x2_values)))
# 周辺分布をグレーで表示
marginal = norm(mu[0], np.sqrt(Sigma[0, 0]))
ax.plot(x1_range, marginal.pdf(x1_range), 'k--', linewidth=2,
alpha=0.5, label='Marginal $p(x_1)$')
for x2_val, color in zip(x2_values, colors):
mu_c, sigma_c = conditional_normal_1d(mu, Sigma, x2_val)
cond = norm(mu_c, np.sqrt(sigma_c))
ax.plot(x1_range, cond.pdf(x1_range), color=color, linewidth=2,
label=f'$x_2 = {x2_val}$: $\\mu = {mu_c:.2f}$')
ax.set_xlabel('$x_1$', fontsize=12)
ax.set_ylabel('Density', fontsize=12)
ax.set_title('Conditional distribution $p(x_1 | x_2)$', fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)
# 右: 相関係数の影響
ax = axes[1]
rho_values = [0.0, 0.3, 0.6, 0.9]
x2_fixed = 2.0
sigma1, sigma2 = 1.0, np.sqrt(2.0)
for rho in rho_values:
Sigma_rho = np.array([[sigma1**2, rho * sigma1 * sigma2],
[rho * sigma1 * sigma2, sigma2**2]])
mu_c = mu[0] + Sigma_rho[0, 1] / Sigma_rho[1, 1] * (x2_fixed - mu[1])
sigma_c = Sigma_rho[0, 0] - Sigma_rho[0, 1]**2 / Sigma_rho[1, 1]
cond = norm(mu_c, np.sqrt(sigma_c))
ax.plot(x1_range, cond.pdf(x1_range), linewidth=2,
label=f'$\\rho = {rho}$: $\\mu = {mu_c:.2f}$, $\\sigma^2 = {sigma_c:.2f}$')
marginal = norm(mu[0], sigma1)
ax.plot(x1_range, marginal.pdf(x1_range), 'k--', linewidth=2,
alpha=0.5, label='Marginal ($\\rho = 0$)')
ax.set_xlabel('$x_1$', fontsize=12)
ax.set_ylabel('Density', fontsize=12)
ax.set_title(f'Effect of correlation $\\rho$ ($x_2 = {x2_fixed}$)', fontsize=13)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
3次元での可視化(等高線 + 条件付きスライス)
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import multivariate_normal, norm
from mpl_toolkits.mplot3d import Axes3D
# パラメータの設定
mu = np.array([0, 1])
Sigma = np.array([[1.0, 0.8],
[0.8, 2.0]])
# メッシュグリッド
x1 = np.linspace(-3, 3, 150)
x2 = np.linspace(-3, 5, 150)
X1, X2 = np.meshgrid(x1, x2)
pos = np.dstack((X1, X2))
rv = multivariate_normal(mu, Sigma)
Z = rv.pdf(pos)
# 3Dプロット
fig = plt.figure(figsize=(14, 6))
# 左: 3D表面プロット
ax1 = fig.add_subplot(121, projection='3d')
ax1.plot_surface(X1, X2, Z, cmap='viridis', alpha=0.7,
edgecolor='none')
# 条件付き分布のスライス (x2=2)
x2_cond = 2.0
mu_c = mu[0] + Sigma[0, 1] / Sigma[1, 1] * (x2_cond - mu[1])
sigma_c = Sigma[0, 0] - Sigma[0, 1]**2 / Sigma[1, 1]
cond_pdf = norm(mu_c, np.sqrt(sigma_c)).pdf(x1)
# p(x1, x2=2) = p(x1|x2=2) * p(x2=2) のスケーリング
p_x2 = norm(mu[1], np.sqrt(Sigma[1, 1])).pdf(x2_cond)
joint_slice = cond_pdf * p_x2
ax1.plot(x1, np.full_like(x1, x2_cond), joint_slice,
color='red', linewidth=3, label=f'Slice at $x_2={x2_cond}$')
ax1.set_xlabel('$x_1$', fontsize=11)
ax1.set_ylabel('$x_2$', fontsize=11)
ax1.set_zlabel('$p(x_1, x_2)$', fontsize=11)
ax1.set_title('Joint density with conditional slice', fontsize=13)
ax1.view_init(elev=25, azim=-60)
# 右: 周辺分布と条件付き分布のまとめ
ax2 = fig.add_subplot(122)
# さまざまなx2の値で条件付き平均と95%信頼区間を表示
x2_range = np.linspace(-2, 4, 100)
mu_conds = mu[0] + Sigma[0, 1] / Sigma[1, 1] * (x2_range - mu[1])
sigma_cond = Sigma[0, 0] - Sigma[0, 1]**2 / Sigma[1, 1]
std_cond = np.sqrt(sigma_cond)
ax2.plot(x2_range, mu_conds, 'r-', linewidth=2,
label='Conditional mean $\\mu_{1|2}$')
ax2.fill_between(x2_range, mu_conds - 1.96 * std_cond,
mu_conds + 1.96 * std_cond,
alpha=0.2, color='red', label='95% credible interval')
ax2.fill_between(x2_range, mu_conds - std_cond,
mu_conds + std_cond,
alpha=0.3, color='red', label='68% credible interval')
# サンプル点を表示
np.random.seed(42)
samples = np.random.multivariate_normal(mu, Sigma, 200)
ax2.scatter(samples[:, 1], samples[:, 0], alpha=0.3, s=15, color='steelblue',
label='Samples')
ax2.axhline(mu[0], color='blue', linewidth=1, linestyle=':', alpha=0.5)
ax2.set_xlabel('$x_2$', fontsize=12)
ax2.set_ylabel('$x_1$', fontsize=12)
ax2.set_title('Conditional mean and credible interval', fontsize=13)
ax2.legend(fontsize=10, loc='upper left')
ax2.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
多変量の場合の数値検証
import numpy as np
from scipy.stats import multivariate_normal
# 4次元の多変量正規分布
np.random.seed(42)
n = 4
n_a = 2 # x_a は最初の2次元
n_b = 2 # x_b は残りの2次元
# 正定値対称行列を生成
A = np.random.randn(n, n)
Sigma = A @ A.T + np.eye(n)
mu = np.array([1.0, 2.0, -1.0, 0.5])
print("=== パラメータ ===")
print(f"mu = {mu}")
print(f"Sigma =\n{Sigma}")
# ブロックに分割
Sigma_aa = Sigma[:n_a, :n_a]
Sigma_ab = Sigma[:n_a, n_a:]
Sigma_ba = Sigma[n_a:, :n_a]
Sigma_bb = Sigma[n_a:, n_a:]
mu_a = mu[:n_a]
mu_b = mu[n_a:]
# 条件付き分布の解析解
x_b_obs = np.array([0.0, 1.0]) # 観測値
mu_cond = mu_a + Sigma_ab @ np.linalg.solve(Sigma_bb, x_b_obs - mu_b)
Sigma_cond = Sigma_aa - Sigma_ab @ np.linalg.solve(Sigma_bb, Sigma_ba)
print(f"\n=== 条件付き分布(解析解)===")
print(f"x_b の観測値: {x_b_obs}")
print(f"条件付き平均: mu_a|b = {mu_cond}")
print(f"条件付き共分散:\n{Sigma_cond}")
# モンテカルロ法による検証
n_samples = 1000000
samples = np.random.multivariate_normal(mu, Sigma, n_samples)
x_a_samples = samples[:, :n_a]
x_b_samples = samples[:, n_a:]
# x_b が x_b_obs に近いサンプルを抽出
tolerance = 0.1
mask = np.all(np.abs(x_b_samples - x_b_obs) < tolerance, axis=1)
x_a_conditional = x_a_samples[mask]
print(f"\n=== モンテカルロ法による検証 ===")
print(f"条件を満たすサンプル数: {mask.sum()} / {n_samples}")
print(f"条件付き平均(MC): {x_a_conditional.mean(axis=0)}")
print(f"条件付き平均(解析): {mu_cond}")
print(f"条件付き共分散(MC):\n{np.cov(x_a_conditional.T)}")
print(f"条件付き共分散(解析):\n{Sigma_cond}")
# 周辺分布の検証
print(f"\n=== 周辺分布の検証 ===")
print(f"周辺平均(MC): {x_a_samples.mean(axis=0)}")
print(f"周辺平均(解析): {mu_a}")
print(f"周辺共分散(MC):\n{np.cov(x_a_samples.T)}")
print(f"周辺共分散(解析):\n{Sigma_aa}")
まとめ
本記事では、多変量正規分布の周辺分布と条件付き分布を厳密に導出しました。
- 周辺分布: $\bm{x}_a \sim \mathcal{N}(\bm{\mu}_a, \bm{\Sigma}_{aa})$($\bm{x}_b$ を積分消去すると、ブロック共分散がそのまま残る)
- 条件付き分布: $\bm{x}_a \mid \bm{x}_b \sim \mathcal{N}(\bm{\mu}_{a|b}, \bm{\Sigma}_{a|b})$
- 条件付き平均: $\bm{\mu}_{a|b} = \bm{\mu}_a + \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}(\bm{x}_b – \bm{\mu}_b)$
- 条件付き共分散: $\bm{\Sigma}_{a|b} = \bm{\Sigma}_{aa} – \bm{\Sigma}_{ab}\bm{\Sigma}_{bb}^{-1}\bm{\Sigma}_{ba}$
- シューア補行列: ブロック行列の逆行列を求める上で不可欠な道具
- ガウス過程回帰: 条件付き分布の公式がそのまま予測分布の公式になる
条件付き平均が $\bm{x}_b$ の線形関数であること、条件付き共分散が $\bm{x}_b$ の値に依存しないことは、正規分布の最も重要な性質です。この性質がカルマンフィルタ、ベイズ線形回帰、ガウス過程など、多くのアルゴリズムを解析的に扱えるものにしています。
次のステップとして、以下の記事も参考にしてください。