在一个2012 年 5 月博文 John Kruschke讨论了他如何喜欢用图表惯例来表示贝叶斯模型而不是传统方法。
您可以在下图中看到他的方法的一个示例:
有几个人评论如果有某种方法可以自动创建此类图,他们愿意采用该惯例。我目前对各种 TeX 相关绘图工具(如 TikZ)的经验很少。
1. TikZ 是制作此类图表的合适工具吗?或者有其他工具更适合?
此外,这些模型经常会随着时间的推移而进行调整。因此,自动化或半自动化绘图过程是可取的。
2. TikZ 或类似工具可以在多大程度上促进绘制此类图表的自动化或重用?
最后,我对任何现有的类似例子感兴趣。
3. 因此,是否有任何 TikZ 代码示例可以执行类似操作?或者,如果有人愿意展示类似操作的模板代码,我们将不胜感激。
答案1
我认为 TikZ 非常适合这个,但你可能需要为它编写一个包。我做了一些实验,下面是一些基本功能。(我使用了一些代码TikZ/PGF 中的钟形曲线/高斯函数/正态分布)
序言中的代码定义了一个新命令,\randomvar
它可以在tikzpicture
环境中用来定义随机变量。在主文档代码中,您可以看到如何使用它。可以指定分布、变量名称等。代码定义了四个随机变量,它们显示为 TikZ 节点,因此从它们绘制箭头和指向它们的箭头很容易。
\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
% --- this here would go into a package
\tikzset{bayes/pdf/.style={blue!50!white}}
\pgfmathdeclarefunction{gauss}{2}{%
\pgfmathparse{1/(#2*sqrt(2*pi))*exp(-((x-#1)^2)/(2*#2^2))}%
}
\pgfmathdeclarefunction{exponential}{1}{%
\pgfmathparse{(#1) * exp(-(#1) * x)}%
}
\pgfkeys{/tikz/bayes/label/.initial={}}
\pgfkeys{/tikz/bayes/name/.initial={}}
\pgfkeys{/tikz/bayes/distribution/.initial={0}}
\pgfkeys{/tikz/bayes/distribution name/.initial={}}
\tikzstyle{bayes/node}=[]
\newcommand\randomvar[2][1]{%
\begingroup
\pgfkeys{/tikz/bayes/.cd, #1}%
\pgfkeysgetvalue{/tikz/bayes/distribution}{\distribution}%
\pgfkeysgetvalue{/tikz/bayes/distribution name}{\distname}%
\pgfkeysgetvalue{/tikz/bayes/name}{\parname}%
\node[bayes/node] (#2) {
\tikz{
\begin{axis}[width=4cm, height=3cm,
axis x line=none,
axis y line=none, clip=false]
\addplot[blue!50!white, semithick, mark=none,
domain=-2:2, samples=50, smooth] {\distribution};
\addplot[black, yshift=-4pt] coordinates { (-2, 0) (2, 0) };
\node at (rel axis cs: 0.5, 0.5) {\parname};
\node[anchor=south] at (rel axis cs: 0.5, 0) {\sffamily\tiny\distname};
\end{axis}
}
};
\endgroup
}
% --- this here would be code written by the user
\begin{document}
\begin{tikzpicture}[node distance=3cm and 2cm, >=stealth]
\randomvar[distribution={gauss(0,0.5)},
name=$M_0$,
distribution name=normal]{M0}
\randomvar[distribution={gauss(0,0.5)},
distribution name=normal,
name=$M_1$,
node/.style={right of=M0}]{M1}
\node[below of=M1] (eqn) { $\beta_0 + \beta_1 \mathbf{x}_i$ };
\randomvar[distribution={exponential(3)},
distribution name=exponential,
name=$M_2$,
node/.style={right of=eqn}]{M2}
\randomvar[distribution={gauss(0,0.5)},
distribution name=normal,
node/.style={below of=eqn}]{M3}
\draw[->] (eqn) -- node [anchor=east] {$=$} (M3.center);
\draw[->] (M0.south) -- node [anchor=east] {$\sim$} (eqn.north west);
\draw[->] (M1.south) -- node [anchor=east] {$\sim$} (eqn);
\draw[->] (M2.south) -- node [anchor=east] {$\sim$} (M3);
\end{tikzpicture}
\end{document}
输出为:
这段代码可以作为软件包的开始,但显然缺少很多功能*。例如,应该可以向分布添加参数(例如正态分布的 tau),并为这些参数定义锚点,以便绘制指向它们的箭头(请注意,锚点的确切位置必须取决于分布才能看起来不错)。我认为可以添加更多锚点,例如.south west
;因此可以将节点的第一个参数称为M3
或M3.parameter 1
其他。然后,可以通过以下方式绘制从 M1 到 M3 参数的箭头\draw[->] (M1.south) -- (M3.parameter 1);
另一个问题是在方程式中(在包含 beta 的方程式中)绘制指向参数的箭头。我现在还不知道该怎么做,但我不是 TikZ 专家。
总之,尽管开发这个可能需要一些工作和专业知识(正如预期的那样),但我确实认为 TikZ 包能够自动完成绘制这些图表的大量工作。
*) 我也不知道我是否使用了正确的编码约定,例如 pgfkeys——欢迎发表评论。