为什么 pgfplots 中的二项式概率计算错误?

为什么 pgfplots 中的二项式概率计算错误?

期间我的调查这个问题很好来自@Sentient,我发现了一个相当奇怪的问题:给定二项式参数 n=15和 p=0.7,@Sentient 的代码会产生一些概率值大于二! 这也可以通过其他参数来说明:

\documentclass{article}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}[
    scale=0.88,
    declare function={binom(\x,\n,\p)=\n!/(\x!*(\n-\x)!)*\p^\x*(1-\p)^(\n-\x);},
    declare function={normd(\x,\n,\p)=binom(\x*\n,\n,\p);},
    declare function={normaldensity(\x,\n,\p)=exp(-\n*(\x-\p)^2/(2*\p*(1-\p)))/sqrt(2*pi*\n*\p*(1-\p));}
]
\begin{axis}
    \addplot[cyan, domain=0:1, samples=26, smooth]{normd(x, 25, 0.72)};
    \addplot[orange, domain=0:1, smooth]{normaldensity(x, 25, 0.72)};
\end{axis}
\end{tikzpicture}\quad
\begin{tikzpicture}[
    scale=0.88,
    declare function={binom(\x,\n,\p)=\n!/(\x!*(\n-\x)!)*\p^\x*(1-\p)^(\n-\x);},
    declare function={normd(\x,\n,\p)=binom(\x*\n,\n,\p);},
    declare function={normaldensity(\x,\n,\p)=exp(-\n*(\x-\p)^2/(2*\p*(1-\p)))/sqrt(2*pi*\n*\p*(1-\p));}
]
\begin{axis}
    \addplot[cyan, domain=0:1, samples=27, smooth]{normd(x, 26, 0.72)};
    \addplot[orange, domain=0:1, smooth]{normaldensity(x, 26, 0.72)};
\end{axis}
\end{tikzpicture}
\end{document}

错误的二项式

在左边,我设定n=25和 p=0.72;在右边,我设定n=26和 p=0.72。橙色曲线是函数生成的高斯近似值normaldensity(公式可以在我之前的回答),它应该接近 normd两张图中的青色曲线(由“正则化二项式”生成)

然而,二项式概率的计算 normd在右边偏离很大,产生的概率值大于 3!相反,左边的计算完全没问题。我相信 @marmot 在写的时候已经注意到了这个问题这个优秀的答案,因为伽马函数方法产生曲线非常不一样来自@Sentient(但非常接近高斯曲线)。

我的问题是:为什么会出现这个计算错误(但只是有时,例如,n = 23, 24 or 26但不是n = 25),以及我该如何修复它?

答案1

我忘了我自己的看法关于 TeX 如何存储实数(真尴尬!)。长话短说,在 normd@Sentient 的原始函数中,\x*\n 被传递以进行阶乘计算。即使在我告诉PGFplots使用

\x = 0, 1/\n, 2/\n, ... , \n/\n

很可能结果\x*\n没有任何1到 的 整数 n-1。这会导致阶乘结果荒谬,进而导致概率大于一。

因此,一个明显的解决方法是使用整数 \x,然后像@marmot在评论中尝试的那样规范化x坐标。这种方法至少可以保证阶乘有一定的准确性。溢出问题是另一个我不想提起的麻烦。

\documentclass{article}
\usepackage{pgfplots}
\begin{document}
\section*{The correct left is by luck}
\begin{tikzpicture}[
    scale=0.88,
    declare function={binom(\x,\n,\p)=\n!/(\x!*(\n-\x)!)*\p^\x*(1-\p)^(\n-\x);},
    declare function={normd(\x,\n,\p)=binom(\x*\n,\n,\p);},
    declare function={normaldensity(\x,\n,\p)=exp(-\n*(\x-\p)^2/(2*\p*(1-\p)))/sqrt(2*pi*\n*\p*(1-\p));}
]
\begin{axis}
    \addplot[cyan, domain=0:1, samples=26, smooth]{normd(x, 25, 0.72)};
    \addplot[orange, domain=0:1, smooth]{normaldensity(x, 25, 0.72)};
    \addplot[red,only marks,samples at={0,1,...,25}](x/25,{binom(x, 25, 0.72)});
\end{axis}
\end{tikzpicture}\quad
\begin{tikzpicture}[
    scale=0.88,
    declare function={binom(\x,\n,\p)=\n!/(\x!*(\n-\x)!)*\p^\x*(1-\p)^(\n-\x);},
    declare function={normd(\x,\n,\p)=binom(\x*\n,\n,\p);},
    declare function={normaldensity(\x,\n,\p)=exp(-\n*(\x-\p)^2/(2*\p*(1-\p)))/sqrt(2*pi*\n*\p*(1-\p));}
]
\begin{axis}
    \addplot[cyan, domain=0:1, samples=27, smooth]{normd(x, 26, 0.72)};
    \addplot[orange, domain=0:1, smooth]{normaldensity(x, 26, 0.72)};
    \addplot[red,only marks,samples at={0,1,...,26}](x/26,{binom(x, 26, 0.72)});
\end{axis}
\end{tikzpicture}
\section*{One should use integers for factorial calculations}
\begin{tikzpicture}[
    scale=0.88,
    declare function={binom(\x,\n,\p)=\n!/(\x!*(\n-\x)!)*\p^\x*(1-\p)^(\n-\x);},
    declare function={normd(\x,\n,\p)=binom(\x*\n,\n,\p);},
    declare function={normaldensity(\x,\n,\p)=exp(-\n*(\x-\p)^2/(2*\p*(1-\p)))/sqrt(2*pi*\n*\p*(1-\p));}
]
\begin{axis}
%    \addplot[cyan, domain=0:1, samples=26, smooth]{normd(x, 25, 0.72)};
    \addplot[orange, domain=0:1, smooth]{normaldensity(x, 25, 0.72)};
    \addplot[red,only marks,samples at={0,1,...,25}](x/25,{binom(x, 25, 0.72)});
\end{axis}
\end{tikzpicture}\quad
\begin{tikzpicture}[
    scale=0.88,
    declare function={binom(\x,\n,\p)=\n!/(\x!*(\n-\x)!)*\p^\x*(1-\p)^(\n-\x);},
    declare function={normd(\x,\n,\p)=binom(\x*\n,\n,\p);},
    declare function={normaldensity(\x,\n,\p)=exp(-\n*(\x-\p)^2/(2*\p*(1-\p)))/sqrt(2*pi*\n*\p*(1-\p));}
]
\begin{axis}
%    \addplot[cyan, domain=0:1, samples=27, smooth]{normd(x, 26, 0.72)};
    \addplot[orange, domain=0:1, smooth]{normaldensity(x, 26, 0.72)};
    \addplot[red,only marks,samples at={0,1,...,26}](x/26,{binom(x, 26, 0.72)});
\end{axis}
\end{tikzpicture}
\end{document}

正确的二项式概率

作为一个经常与概率打交道的人,我PGFplots很少程序我的分布函数。我发现使用统计软件生成的数据来绘制更容易(也更准确)PGFplots

相关内容