ディリクレ分布とは?LDAをわかりやすく解説
ディリクレ分布
ディリクレ分布の応用範囲は広く、自然言語処理ではトピックモデルにおいてディリクレ分布が用いられていますね。
また、カテゴリカル分布や多項分布の事前分布として用いられることが多いですね。
ディリクレ分布は、$K$次元のシンプレックス上の確率密度関数として定義されます。
そして確率密度関数は、$K$次元のシンプレックス上で定義されます。

シンプレックスとは、非負の成分の和が1となる$K$次元ベクトルの集合のことです。
つまり、$\boldsymbol{\theta} = (\theta_1, \theta_2, \ldots, \theta_K)$が$K$次元のシンプレックス上のベクトルであるためには、$\theta_i \geq 0$かつ$\sum_{i=1}^K \theta_i = 1$を満たす必要があります。
ディリクレ分布の確率密度関数
ディリクレ分布は、多項分布の確率パラメータ(カテゴリの確率)の事前分布としてよく用いられる確率分布です。確率ベクトル ${\boldsymbol{\theta} = (\theta_1, \theta_2, \ldots, \theta_K)}$に対して、以下の確率密度関数を持ちます。
$$\text{Dir}(\boldsymbol{\theta}|\boldsymbol{\alpha}) = \frac{\Gamma\left(\sum_{i=1}^K\alpha_i\right)}{\prod_{i=1}^K\Gamma(\alpha_i)}\prod_{i=1}^K\theta_i^{\alpha_i-1}$$
$\boldsymbol{\alpha} = (\alpha_1, \alpha_2, \ldots, \alpha_K)$はディリクレ分布のパラメータベクトルであり、$\Gamma(\cdot)$はガンマ関数を表します。
濃度パラメータ
各${\alpha_i}$は、対応する${\theta_i}$の分布の形を決める役割を持ちます。
- ${\alpha_i}$が大きい → ${\theta_i}$の値が 大きくなりやすい(そのカテゴリが選ばれやすくなる)。
- ${\alpha_i}$が ${1}$ に近い → 各 ${\theta_i}$ は 一様分布に近い(特定のカテゴリに偏らない)。
- ${\alpha_i}$が 1 より小さい → ${\theta_i}$の値は 極端になりやすい(0 または 1 に近づきやすい)。
ディリクレ分布の平均と分散
ディリクレ分布に従う確率変数 ${\boldsymbol{\theta} = (\theta_1, \theta_2, \ldots, \theta_K)}$の各成分について、平均と分散は以下の式で表されます。
$$\begin{align*}
\mathbb{E}[\theta_i] &= \frac{\alpha_i}{\sum_{j=1}^K\alpha_j} \\
\mathbb{V}[\theta_i] &= \frac{\alpha_i\left(\sum_{j\neq i}\alpha_j\right)}{\left(\sum_{j=1}^K\alpha_j\right)^2\left(\sum_{j=1}^K\alpha_j+1\right)}
\end{align*}$$

期待値は、各カテゴリの確率の期待値が、濃度パラメータの比率によって決まることを示しています。分散は、${\alpha_i}$が大きいほど小さくなり、確率が安定することを意味します。
ディリクレ分布の性質:共役事前分布としての利用
この分布の嬉しい点は、ある確率分布がディリクレ分布に従うと仮定し、その分布からサンプルを観測した場合、その確率分布の事後分布もディリクレ分布になる、という点です。
例えば、カテゴリカル分布$\text{Cat}(x|\boldsymbol{\theta})$の事前分布として$\boldsymbol{\theta} \sim \text{Dir}(\boldsymbol{\alpha})$を仮定し、$\boldsymbol{n} = (n_1, n_2, \ldots, n_K)$がカテゴリカル分布からの観測値の計数であるとします。この場合、$\boldsymbol{\theta}$の事後分布は、
$$\boldsymbol{\theta}|\boldsymbol{n} \sim \text{Dir}(\boldsymbol{\alpha}+\boldsymbol{n})$$
と求められます。つまり、観測データをそのまま濃度パラメータに足すだけで更新できる という簡潔な形になるため、ベイズ推論の計算が容易になります。
これにより、観測値を考慮した$\boldsymbol{\theta}$の更新された分布が得られます。
例えば、$K=3$の場合、$\boldsymbol{\alpha} = (2, 5, 3)$とすると、$\theta_2$の値が比較的大きくなる傾向があります。
具体的に、$\boldsymbol{\theta}$の平均値は$\mathbb{E}[\boldsymbol{\theta}] = \left(\frac{2}{10}, \frac{5}{10}, \frac{3}{10}\right)$となり、分散は\(\mathbb{V}[\theta_1] = \frac{2\times8}{10^2\times11} \approx 0.015\)、\(\mathbb{V}[\theta_2] = \frac{5\times5}{10^2\times11} \approx 0.023\)、\(\mathbb{V}[\theta_3] = \frac{3\times7}{10^2\times11} \approx 0.018\)となります。
このように、${\alpha_i}$の値が大きいほど、そのカテゴリの確率のばらつきが小さくなり、確率が安定することが確認できます。
ここまでのまとめ
ディリクレ分布は、確率ベクトルを対象とする確率分布で、カテゴリカル分布や多項分布の事前分布として使われる。
- ${\alpha_i}$(濃度パラメータ)が大きいほど、対応する確率 ${\theta_i}$が高くなりやすい。
- ベイズ推論において、カテゴリカル分布の事前分布として用いると、事後分布もディリクレ分布の形を保つ(共役性)。確率分布の更新が簡単に行える
潜在ディリクレ過程(LDA)
LDAは、文書集合内の単語の共起パターンを分析し、潜在的なトピックを推定する統計モデルです。まず、各文書は複数のトピックの混合として表され、各トピックは特定の単語分布を持つと仮定されます。LDAでは、ディリクレ分布を用いてトピック分布と単語分布の事前分布を設定し、単語の出現データから文書ごとのトピック分布を推定します。
勘違いしやすいのは、文書がトピックに関連しているかどうかを直接分析するのではなく、単語の共起パターンからトピックを推定し、そのトピックが文書ごとにどのような割合で現れるかを推定する、という点ですね。
LDAの目的
「各文書は複数のトピック(政治とか経済とか)の混合である」「各トピックは単語の確率分布である」という前提に基づき、観測された単語から潜在変数${z}$の事後分布を推定すること
LDA的なクラスタリングの適用方法|ある細胞集団での遺伝配列のカウント数の分布
細胞集団ごとの遺伝子配列の発生率を多項分布と考えるて、LDAを使ったクラスタリングをしてみましょう。LDAは文書の単語分布を多項分布とみなし、単語(遺伝子配列に対応)と文書(細胞集団に対応)の関係を学習するモデルなので応用できそうです。
1. モデルの定式化
- 細胞集団(サンプル) を「文書」とみなす
- 遺伝子配列を「単語」とみなす
- 配列の発生率 を「文書中の単語の出現頻度」とみなす
- 配列の発生パターン(潜在的なグループ) を「トピック」とみなす
- 例えば、「この配列はある集団に特異的」「この配列はどの集団にも等しく出現」などのグループ化が可能

このように考えると、LDAの前提である「文書中の単語の出現は多項分布に従う」が自然に満たされ、適用できそうです。
2. 具体的なアプローチ
- データの準備
- 各細胞集団ごとに遺伝子配列のカウントデータを用意
- ${X_{ij}}$を「細胞集団 ${i}$における配列 ${j}$ のカウント」とする
- LDAを適用
- Variational Inference(変分推論)またはGibbs Sampling(ギブスサンプリング)で学習
- 事前分布としてディリクレ分布を適用し、遺伝子配列の発生パターン(トピック)を推定
- 結果の解釈
- 各配列がどの「発生パターン」に属するかを解析
- 細胞集団ごとに特徴的な遺伝子配列のセットを抽出可能
from sklearn.decomposition import LatentDirichletAllocation
import numpy as np
import pandas as pd
# 設定
num_cells = 15 # 細胞集団の数
num_genes = 1000
# カウント行列の作成(スパースらしい。ほとんど0、ランダムに少数の値を付与)
np.random.seed(42)
X = np.random.poisson(lam=2, size=(num_cells, num_genes)) # ポアソン分布で発生
X[np.random.rand(num_cells, num_genes) > 0.1] = 0 # 90%をゼロにする
gene_labels = [f"GENE_{i+1}" for i in range(num_genes)]
cell_labels = [f"cell_{i+1}" for i in range(num_cells)]
df = pd.DataFrame(X, index=cell_labels, columns=gene_labels)
df
実態に即して、0が多めのカウントデータを作ってみます。
実際の研究では、このあたりのゼロデータの処理が必要な気がします。


どの細胞集団に、どういった配列が何回観測されたかのデータが作れました。
import matplotlib.pyplot as plt
import japanize_matplotlib
lda = LatentDirichletAllocation(n_components=3, random_state=42)
topics = lda.fit_transform(X)
topics_df = pd.DataFrame(topics, columns=[f"Topic_{i+1}" for i in range(lda.n_components)])
topics_df.index = cell_labels
# 配列が最も関連するトピックを取得
gene_topic_assignment = np.argmax(lda.components_, axis=0)
# 各トピックごとにプロット
for i in range(lda.n_components):
plt.figure(figsize=(8, 6))
topic_genes = np.where(gene_topic_assignment == i)[0]
for j in topic_genes:
plt.plot(cell_labels, X[:, j], label=f"gene {j+1}")
plt.title(f"Topic {i+1} の配列カウント(細胞集団ごと)")
plt.xlabel("細胞集団")
plt.ylabel("配列カウント数")
plt.tight_layout()
plt.show()
今回、トピックとしているのは、各遺伝子配列の細胞集団における発生パターン、なので3トピックに分けてみます。



トピック1の配列たちは、細胞5や11でよく発生するっぽいですね。
トピック2の配列は、後半の細胞でよくみられるようです。
トピック3の配列は、前半の細胞多めって感じですかね。

どの細胞集団に、どういった配列が何回観測されたかのデータが作れました。
このLDAによって作られたトピックについての解釈、つまり「カウントデータから、どんな傾向が語れるのか、どんな示唆があるのか、というのは」はまさに分析者が行う部分ですね。
あくまでLDAだと整理までしかできません。
ロジック
具体例はここまで!ロジックの解説に入ります。
そもそもトピックとは?
LDAにおける「トピック」とは、単語分布の確率モデル です。
つまり、各トピック ${k}$は「どの単語がどの程度出現しやすいか」を表す分布${\phi_k}$を持っています。
たとえば、
- トピック1(スポーツ): 「ゴール 0.3」「チーム 0.2」「選手 0.15」「試合 0.1」 …
- トピック2(政治): 「議会 0.25」「法案 0.2」「選挙 0.15」「首相 0.1」 …
のような確率分布になっていると考えます。
文書ごとのトピック分布 ${\theta_d}$とは?
LDAでは、「文書は1つのトピックだけに属する」のではなく、「複数のトピックの混合」として考えます。
この混合比率を表すのが 文書ごとのトピック分布 ${\theta_d}$です。
たとえば、
- 文書A: 「スポーツ 70%」「政治 30%」
- 文書B: 「スポーツ 20%」「政治 80%」
のような確率分布を持つことになります。
各単語のトピック割り当て${z_{di}}$
実際の単語${w_{di}}$は、その文書${d}$のトピック分布${\theta_d}$に基づいて、あるトピック${z_{di}}$をサンプリングし、
その後、選ばれたトピックの単語分布 ${\phi_{z_{di}}}$から単語が生成されます。
ここまでの話をまとめると、こうなります。
- トピックごとの単語分布の生成
- 各トピック ${k}$ に対して、単語分布 ${\phi_k \sim \text{Dir}(\beta)}$ を生成。
- 文書ごとのトピック分布の生成
- 各文書 ${d}$ に対して、トピック分布 ${\theta_d \sim \text{Dir}(\alpha)}$ を生成。
- 単語ごとのトピック割り当てと単語の生成
- 各単語位置 ${i}$ に対して、
- トピック ${z_{di} \sim \text{Multinomial}(\theta_d)}$ を選択。
- これは「文書 ${d}$ の単語位置 ${i}$ のトピックが ${\theta_d}$ に従う多項分布からサンプリングされる」ことを意味します。
- 最後に、単語 ${w_{di} \sim \text{Multinomial}(\phi_{z_{di}})}$ を生成。
→「選ばれたトピックの単語分布 ${\phi_{z_{di}}}$ から実際の単語がサンプリングされる」ことを示す。
もう少し日本語的に理解するとこんな感じです。
LDAを国語的に理解
- 文書そのものが特定のトピックに「従う」のではなく、文書は複数のトピックの混合として表現される
- 各文書には「このトピックがどれくらい含まれるか」を表すトピック分布 ${\theta_d}$がある
- 単語はその文書のトピック分布に基づいてトピックが割り当てられ、トピックごとの単語分布${\phi_k}$から生成される
LDAの結合確率分布は以下のように表現されます
$${p(\mathbf{w}, \mathbf{z}, \mathbf{\theta}, \mathbf{\phi}|\alpha, \beta) = \prod_{k=1}^K p(\phi_k|\beta) \prod_{d=1}^M p(\theta_d|\alpha) \prod_{i=1}^{N_d} p(z_{di}|\theta_d)p(w_{di}|\phi_{z_{di}})}$$
ややこしくて意味がわからないと思いますが、これはLDAモデルにおける全ての変数の同時分布を表しています。
- ${p(\phi_k|\beta)}$: 各トピック ${k}$ の単語分布。
- ${p(\theta_d|\alpha)}$: 各文書 ${d}$ のトピック分布。
- ${p(z_{di}|\theta_d)}$: 文書 ${d}$ の ${i}$ 番目の単語のトピック割り当て。
- ${p(w_{di}|\phi_{z_{di}})}$: トピック ${z_{di}}$ に基づく単語 ${w_{di}}$ の生成確率。
これは変分推論やギプスサンプリングなどの手法で近似的に解くことができます。
今回は、ギプスサンプリングで解説します。
補足|ギプスサンプリング
さて、LDAの目的を再確認すると各単語に割り当てられたトピックzを推定することです。
で、ギプスサンプリングは他の全ての変数が与えられたときの、各変数の条件付き確率分布から サンプリングを繰り返す方法なので
完全条件付き分布からサンプリングを行います。
$${p(z_{di} = k|z_{-di}, \mathbf{w}) \propto \frac{n_{dk}^{-di} + \alpha_k}{\sum_{k’} (n_{dk’}^{-di} + \alpha_{k’})} \cdot \frac{n_{kv}^{-di} + \beta_v}{\sum_{v’} (n_{kv’}^{-di} + \beta_{v’})}}$$
- ${n_{dk}}$ は文書 ${d}$ でトピック ${k}$ に割り当てられた単語数。
- ${n_{kv}}$ はトピック ${k}$ に割り当てられた単語 ${v}$ の数。
- 上付きの ${-di}$ は、現在の単語を除外することを意味する。
この式の意味を簡単に説明すると、
- 左側の分数: 文書 ${d}$ におけるトピック ${k}$ の出現割合。
- 右側の分数: トピック ${k}$ における単語 ${v}$ の出現割合。
つまり、左側の分数は現在の文書${d}$におけるトピック${k}$の割合を表し、右側の分数はトピック${k}$における単語${v}$の割合を表します。
これ、結局は「他の全ての単語のトピック割り当て(${z_{-di}}$)と全ての観測された単語(${\mathbf{w}}$)が与えられたとき、現在の単語 ${w_{di}}$ にトピック ${k}$ を割り当てる確率」と言えます。(大事)
ギブスサンプリングでは、この条件付き確率を使って各単語のトピックを繰り返しサンプリングすることで、結果的に結合確率から潜在変数 ${z}$ の事後分布をサンプリングします。(だからあくまでも近似的。)
では、なぜ今の条件付き確率で「近似的」と言えるのでしょうか?
どこかに上述した変数の同時分布との比例関係があると言える必要があります。
実は、ベイズの定理を使うと、この条件付き確率は結合確率を用いて以下のように表現できます
$${p(z_{di} = k|z_{-di}, \mathbf{w}) \propto p(\mathbf{w}, \mathbf{z}, \mathbf{\theta}, \mathbf{\phi}|\alpha, \beta)}$$
つまり、ギブスサンプリングで使用する条件付き確率は、結合確率を特定の変数について周辺化したものと比例関係にあります。
これにより、複雑な結合確率から直接サンプリングすることなく、より簡単な条件付き確率を用いてLDAの潜在変数を効率的に推定することができます。
この辺りはMCMC法の考えやベイズ法の考えが必要になります。
詳しくは、こちらをどうぞ!