如何使用 TikZ 或类似工具生成 John Kruschke 的贝叶斯模型图?

如何使用 TikZ 或类似工具生成 John Kruschke 的贝叶斯模型图?

在一个2012 年 5 月博文 John Kruschke讨论了他如何喜欢用图表惯例来表示贝叶斯模型而不是传统方法。

您可以在下图中看到他的方法的一个示例:

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;因此可以将节点的第一个参数称为M3M3.parameter 1其他。然后,可以通过以下方式绘制从 M1 到 M3 参数的箭头\draw[->] (M1.south) -- (M3.parameter 1);

另一个问题是在方程式中(在包含 beta 的方程式中)绘制指向参数的箭头。我现在还不知道该怎么做,但我不是 TikZ 专家。

总之,尽管开发这个可能需要一些工作和专业知识(正如预期的那样),但我确实认为 TikZ 包能够自动完成绘制这些图表的大量工作。

*) 我也不知道我是否使用了正确的编码约定,例如 pgfkeys——欢迎发表评论。

相关内容