##はじめに
pptの挿絵用にきれいにグラフィカルモデルを描きたい。
Pythonではdaftというパッケージで描けるようなのでやってみた。
(RではDiagrammeRで描けるらしい。)
参考:https://nzw0301.github.io/2016/02/daft
本内容のNotebookはこちら。
##実行環境
macOS
python 3.6.6
Jupyter notebook
##daft install
pip install daft
##daft でグラフィカルモデルを描画
- daft を読み込む
import daft
from matplotlib import rc
%matplotlib inline
- 描画する土台を作る
pgm = daft.PGM(shape=[13, 7], node_unit = 3)
ここにノードやエッジを追加していく。
shape=[x軸, y軸]
node_unitは全部のノードのサイズを制御可能。
- ノード作成
pgm.add_node(daft.Node("beta", r"$\beta$", 2, 5))
daft.Node("ノードの名前", "表示名", x軸, y軸)
(0,0)は土台の左下
- エッジ作成
pgm.add_edge("beta", "phi")
beta→phiへのエッジを貼る。
引数 directed=False を追加すれば無向グラフ(矢印なし)になる。
- プレート作成
pgm.add_plate(daft.Plate([3.5, 4, 4, 2], label_offset =[195, 13], label=r"K"))
daft.Plate([x軸, y軸, 横幅, 縦幅], label_offset =[x, y], label="表示名")
label_offset はプレートの左下からどの位置にラベルを置くかを指定可能。サイズはpt。
Latent Dirichlet Allocation
rc("font", family="sans-serif", size=40)
# PGM Object
pgm = daft.PGM(shape=[13,10], node_unit = 3)
# Nodes 名前, ラベル, 座標
pgm.add_node(daft.Node("beta", r"$\beta$", 2, 7))
pgm.add_node(daft.Node("phi", r"$\phi_k$", 5, 7))
pgm.add_node(daft.Node("alpha", r"$\alpha$", 1, 4))
pgm.add_node(daft.Node("theta", r"$\theta_d$", 4, 4))
pgm.add_node(daft.Node("z", r"$z_{d,n}$", 7, 4))
pgm.add_node(daft.Node("w", r"$w_{d,n}$", 10, 4, observed=True))
# Edges node1 → node2
pgm.add_edge("alpha", "theta")
pgm.add_edge("theta", "z")
pgm.add_edge("z", "w")
pgm.add_edge("beta", "phi")
pgm.add_edge("phi", "w")
# plate
pgm.add_plate(daft.Plate([2.5, 2.6, 10, 3], label_offset =[530,13], label=r"D"))
pgm.add_plate(daft.Plate([5.5, 3, 6.2, 2], label_offset =[300, 13], label=r"$N_d$"))
pgm.add_plate(daft.Plate([3.5, 6, 4, 2], label_offset =[195, 13], label=r"K"))
# Rendering
pgm.render()
pgm.figure.savefig("lda.pdf")
Topic Tracking Model
rc("font", family="sans-serif", size=25)
# PGM Object
pgm = daft.PGM(shape=[20, 8], node_unit = 4)
# Nodes 名前, ラベル, 座標
pgm.add_node(daft.Node("alpha_t-1", r"$\alpha_{t-1}$", 2, 6.5))
pgm.add_node(daft.Node("theta_t-1", r"$\theta_{t-1,d}$", 5, 6.5))
pgm.add_node(daft.Node("z_t-1", r"$z_{t-1,d,n}$", 8, 6.5))
pgm.add_node(daft.Node("w_t-1", r"$w_{t-1,d,n}$", 11, 6.5, observed=True))
pgm.add_node(daft.Node("phi_t-1", r"$\phi_{t-1,k}$", 14, 6.5))
pgm.add_node(daft.Node("beta_t-1", r"$\beta_{t-1}$", 17, 6.5))
pgm.add_node(daft.Node("alpha_t", r"$\alpha_{t}$", 2, 2.5))
pgm.add_node(daft.Node("theta_t", r"$\theta_{t,d}$", 5, 2.5))
pgm.add_node(daft.Node("z_t", r"$z_{t,d,n}$", 8, 2.5))
pgm.add_node(daft.Node("w_t", r"$w_{t,d,n}$", 11, 2.5, observed=True))
pgm.add_node(daft.Node("phi_t", r"$\phi_{t,k}$", 14, 2.5))
pgm.add_node(daft.Node("beta_t", r"$\beta_{t}$", 17, 2.5))
# Edges node1 → node2
pgm.add_edge("alpha_t-1", "theta_t-1")
pgm.add_edge("theta_t-1", "z_t-1")
pgm.add_edge("z_t-1", "w_t-1")
pgm.add_edge("beta_t-1", "phi_t-1")
pgm.add_edge("phi_t-1", "w_t-1")
pgm.add_edge("alpha_t", "theta_t")
pgm.add_edge("theta_t", "z_t")
pgm.add_edge("z_t", "w_t")
pgm.add_edge("beta_t", "phi_t")
pgm.add_edge("phi_t", "w_t")
pgm.add_edge("theta_t-1", "theta_t")
pgm.add_edge("phi_t-1", "phi_t")
# plate
pgm.add_plate(daft.Plate([0.2, 4.4, 12.3, 3.5], label_offset =[633,10], label=r"$D_{t-1}$"))
pgm.add_plate(daft.Plate([6.5, 5, 5.7, 2.8], label_offset =[238, 13], label=r"$N_{t-1,d}$"))
pgm.add_plate(daft.Plate([0.2, 0.4, 12.3, 3.5], label_offset =[663,10], label=r"$D_{t}$"))
pgm.add_plate(daft.Plate([6.5, 1, 5.7, 2.8], label_offset =[285, 10], label=r"$N_d$"))
pgm.add_plate(daft.Plate([12.8, 0.4, 5.5, 7.5], label_offset =[290, 10], label=r"K"))
# Rendering
pgm.render()
pgm.figure.savefig("ttm.pdf")
##所感
下付き文字がきれいにかけて嬉しい。
位置の設定がちょっと面倒。