確率的生成モデルのグラフィカル表現を LaTeX(TikZ)で描く
はじめに
確率的生成モデルを説明するとき、確率変数どうしの依存関係をグラフィカルモデル(プレート記法)で描くと一目で伝わります。これを本文と同じ品質で組むなら、LaTeX の TikZ が向いています。フォントも数式も本文とそろい、ベクターで拡大に強い図になります。同じ TikZ で、圏論の可換図式や制御系のブロック線図も描けます。
何を描くか
グラフィカルモデルの構成要素は決まっています。
| 要素 | 記法 |
|---|---|
| 確率変数(潜在) | 白い円 |
| 確率変数(観測済み) | 塗りつぶした円 |
| 定数・ハイパーパラメータ | 円で囲まない(または小さな点) |
| 依存関係 | 有向辺(矢印) |
| 繰り返し | プレート(角丸の長方形)と右下の反復回数 |
tikz-bayesnet を使う
tikz-bayesnet パッケージが、この記法に必要なスタイルとマクロを用意しています。
\usepackage{tikz}
\usetikzlibrary{bayesnet} % tikz-bayesnet が提供
主なマクロは次のとおりです。
\node[latent] (z) {$z$};… 潜在変数(白い円)\node[obs] (x) {$x$};… 観測変数(塗り円)\node[const] (a) {$\alpha$};… 定数\edge {z} {x};… 有向辺z → x\plate {p} {(z)(x)} {$N$};… 指定ノードを囲むプレート、ラベル $N$\factor,\factoredge… 因子グラフ用
最小の例
\begin{tikzpicture}
\node[const] (mu) {$\mu$};
\node[latent, right=of mu] (theta) {$\theta$};
\node[obs, right=of theta](x) {$x$};
\edge {mu} {theta};
\edge {theta} {x};
\plate {} {(x)} {$N$};
\end{tikzpicture}
right=of ... は positioning ライブラリの配置指定です(bayesnet 読み込み時に一緒に使えます)。上のコードを standalone クラスでコンパイルすると、次の図が得られます。
出力例:最小のグラフィカルモデル。白い円が潜在変数 $\theta$、灰色の円が観測変数 $x$、角丸の枠がプレート。
プレートの入れ子(LDA の例)
潜在ディリクレ配分(LDA)を書くと、プレートの重なりが分かります。
\begin{tikzpicture}
\node[const] (alpha) {$\alpha$};
\node[latent, right=of alpha] (theta) {$\theta_d$};
\node[latent, right=of theta] (z) {$z_{d,n}$};
\node[obs, right=of z] (w) {$w_{d,n}$};
\node[latent, above=of w] (phi) {$\varphi_k$};
\node[const, above=of phi] (beta) {$\beta$};
\edge {alpha} {theta};
\edge {theta} {z};
\edge {z} {w};
\edge {beta} {phi};
\edge {phi} {w};
\plate {pN} {(z)(w)} {$N$}; % 文書内の語
\plate {pD} {(theta)(z)(w)(pN)}{$D$}; % 文書
\plate {pK} {(phi)} {$K$}; % トピック
\end{tikzpicture}
内側のプレート pN を外側 pD の囲み対象に含めると、入れ子がきれいに描けます。
出力例:LDA のグラフィカルモデル。観測されるのは単語 $w$ だけ(灰色)。$N$ は文書内の語、$D$ は文書、$K$ はトピックの繰り返し。
素の TikZ で描く
パッケージを増やしたくない場合は、fit と positioning で同等のことができます。
\usetikzlibrary{fit, positioning}
\tikzset{
rv/.style = {circle, draw, minimum size=9mm, inner sep=1pt},
obs/.style = {rv, fill=gray!25},
plate/.style= {draw, rounded corners, inner sep=8pt},
}
\begin{tikzpicture}[node distance=14mm]
\node[rv] (theta) {$\theta$};
\node[obs, right=of theta] (x) {$x_n$};
\draw[->] (theta) -- (x);
\node[plate, fit=(x)] (plate) {};
\node[anchor=south east, inner sep=3pt] at (plate.south east) {$N$};
\end{tikzpicture}
\node[plate, fit=(a)(b) ...] で複数ノードを囲み、その south east(右下の角)に反復回数のノードを重ねます。label=below right: だと枠の外側に出てしまうので、プレートを名前付きノードにして anchor=south east で内側に置くのがコツです。
出力例:tikz-bayesnet を使わず、fit と positioning だけで描いた同等の図。
見た目は tikz-bayesnet 版とほぼ同じで、円の大きさや線の細部が自前スタイル次第になります。
レイアウトのコツ
- 格子に載せる:
node distanceを決め、right=of/above=ofで直交配置にすると崩れにくい - プレートのラベルは右下:慣例に合わせる。
\plateの第 3 引数、素の TikZ ならlabel=below right: - 辺のアンカー:円どうしは自動で外周に接続される。曲げたいときは
\edge[bend left]やto[bend right] - 観測ノードの塗り:
fill=gray!25程度。濃くしすぎると文字が読めない - 記号は数式モードで:
$z_{d,n}$のように本文の数式と字体をそろえる
図を別ファイルにする
図が増えてきたら、1 枚ずつ独立した .tex にして本文から取り込みます。
% fig-lda.tex
\documentclass[tikz, border=2pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{bayesnet}
\begin{document}
\begin{tikzpicture}
% ... 上の LDA の図 ...
\end{tikzpicture}
\end{document}
% 本文側
\begin{figure}
\centering
\input{fig-lda} % または \includegraphics{fig-lda.pdf}
\caption{LDA のグラフィカルモデル}
\end{figure}
TikZ の図はコンパイルが重くなりがちなので、\usetikzlibrary{external} で図をキャッシュするか、standalone で個別にビルドします。ビルドの回し方は latexmk、環境の固定は TeX Live 入りコンテナの記事にまとめてあります。
関連記事
- 圏論の可換図式を TikZ で描く — tikz-cd で矢印中心の図を組む
- 制御系のブロック線図を TikZ で描く — ブロックと配線の記法
- 深層学習の代表的なモデル図を TikZ で描く —
\foreachでニューロンや層を並べる - 状態遷移図を TikZ で描く — automata ライブラリで状態と遷移を描く
- latexmk — TikZ を含む文書のビルドを回す
- TeX Live 入りコンテナと Makefile — 図のコンパイル環境を固定する
まとめ
- グラフィカルモデルは「潜在=白円/観測=塗り円/定数=裸/依存=矢印/繰り返し=プレート」で描く。
tikz-bayesnetの\node[latent|obs|const]、\edge、\plateを使えば短く書ける。- パッケージ無しでも
fit+positioningと自前スタイルで同じ図が作れる。 - 図は
standaloneで別ファイル化し、externalでキャッシュするとビルドが軽くなる。
数式・記号が本文と完全にそろうのが、TikZ でモデル図を描く一番の利点です。