根据预期分布测试随机生成的数据

机器算法验证 分布 假设检验 随机生成
2022-02-11 19:46:14

我编写了一个生成随机数据的程序。如果程序正常工作,则该数据应遵循特定的已知概率分布。我想运行程序,对结果进行一些计算,然后得出一个 p 值。

在其他人说之前:我知道假设检验无法检测程序何时正确运行。它只能检测到它何时以特定方式运行不正确。(即便如此,测试“应该”失败 X% 的时间,这取决于您选择的显着性水平......)

因此,我试图了解哪些工具可能是合适的。尤其:

  • 我可以根据需要生成尽可能多的随机数据。我所要做的就是让程序运行足够长的时间。所以我不限于任何特定的样本量。

  • 我对产生 p 值的技术感兴趣。所以盯着图表说“是的,这看起来有点线性”并不是一个有趣的选择。除非有某种方法可以在图表的“不稳定”上加上一个硬数字。;-)

到目前为止我所知道的:

  • 我见过提到的三种主要类型的测试听起来可能适用:[Pearson] 卡方检验、Kolmogorov-Smirnov 检验和 Anderson-Darling 检验。

  • 卡方检验似乎适用于离散分布,而其他两个更适用于连续分布。(?)

  • 各种消息来源暗示 AD 测试比 KS 测试“更好”,但没有进一步详细说明。

最终,所有这些测试都可能检测到偏离指定零分布的“不同方式”。但我真的不知道有什么区别......总之,我正在寻找某种关于每种类型的测试最适用的一般描述,以及它最好检测到的问题类型。

3个回答

以下是对上述 3 种方法如何工作的一般描述。

卡方方法通过将 bin 中的观察数量与基于分布的 bin 中预期的数量进行比较来工作。对于离散分布,bin 通常是离散的可能性或这些可能性的组合。对于连续分布,您可以选择切割点来创建 bin。许多实现此功能的函数将自动创建 bin,但如果您想在特定区域进行比较,您应该能够创建自己的 bin。这种方法的缺点是不会检测到理论分布和仍然将值放在同一个 bin 中的经验数据之间的差异,例如四舍五入,如果理论上应该将 2 和 3 之间的数字分布在整个范围内(我们希望看到像 2.34296 这样的值),

KS 检验统计量是被比较的 2 个累积分布函数之间的最大距离(通常是理论和经验)。如果 2 个概率分布只有 1 个交点,则 1 减去最大距离是 2 个概率分布之间的重叠区域(这有助于某些人可视化正在测量的内容)。考虑在同一个图上绘制理论分布函数和 EDF,然后测量两条“曲线”之间的距离,最大的差异是测试统计量,当空值为真时,它与值的分布进行比较。这捕获差异是分布的形状或 1 个分布与另一个相比发生偏移或拉伸。1n. 此测试取决于您了解参考分布的参数,而不是从数据中估计它们(您的情况在这里似乎很好)。如果您从相同的数据估计参数,那么您仍然可以通过与您自己的模拟而不是标准参考分布进行比较来获得有效的测试。

Anderson-Darling 测试也像 KS 测试一样使用 CDF 曲线之间的差异,但它不是使用最大差异,而是使用两条曲线之间总面积的函数(它实际上是对差异进行平方,对它们进行加权,因此尾部有更大的影响,然后在分布的域上集成)。与 KS 相比,这给离群值更多的权重,并且如果存在一些小的差异(与 KS 强调的 1 个大差异相比),也会赋予更大的权重。这可能最终会压倒测试以找到您认为不重要的差异(温和的四舍五入等)。与 KS 测试一样,这假设您没有从数据中估计参数。

这是一个图表,显示了最后 2 个的一般想法:

在此处输入图像描述

基于此 R 代码:

set.seed(1)
tmp <- rnorm(25)
edf <- approxfun( sort(tmp), (0:24)/25, method='constant', 
    yleft=0, yright=1, f=1 )

par(mfrow=c(3,1), mar=c(4,4,0,0)+.1)
curve( edf, from=-3, to=3, n=1000, col='green' )
curve( pnorm, from=-3, to=3, col='blue', add=TRUE)

tmp.x <- seq(-3, 3, length=1000)
ediff <- function(x) pnorm(x) - edf(x)
m.x <- tmp.x[ which.max( abs( ediff(tmp.x) ) ) ]
ediff( m.x )  # KS stat
segments( m.x, edf(m.x), m.x, pnorm(m.x), col='red' )  # KS stat

curve( ediff, from=-3, to=3, n=1000 )
abline(h=0, col='lightgrey')    

ediff2 <- function(x) (pnorm(x) - edf(x))^2/( pnorm(x)*(1-pnorm(x)) )*dnorm(x)
curve( ediff2, from=-3, to=3, n=1000 )
abline(h=0)

上图显示了来自标准法线的样本的 EDF 与标准法线的 CDF 的比较,其中一条线显示了 KS 统计数据。然后中间的图表显示了 2 条曲线的差异(您可以看到 KS 统计数据出现的位置)。然后底部是平方的加权差,AD测试基于该曲线下的面积(假设我一切都正确)。

其他测试查看 qqplot 中的相关性,查看 qqplot 中的斜率,比较均值、var 和基于矩的其他统计数据。

+1 写一个清晰而详细的问题。我希望我的回答不会太令人沮丧。我认为假设检验在您的情况下不是合适的方法。当答案可能是或否时,零假设显着性检验是一件合理的事情,但您不知道是哪个(不幸的是,它实际上并没有告诉你哪个,但这是一个不同的问题。)在你的情况下,我收集,你想知道你的算法是否好。然而,众所周知(可以肯定),没有计算机程序可以从任何概率分布中生成真正的随机数据。首先这是正确的,因为所有计算机都是有限状态机,因此只能产生伪随机数. 此外(撇开缺乏真正的随机性不谈),生成的值不可能完全遵循任何连续分布。有几种方法可以理解这一点,但也许最简单的方法是在数轴上会有“间隙”,这对于任何连续随机变量都不是真的。此外,这些间隙并非都完全等宽或完全等距。在从事伪随机数生成工作的计算机科学家中,游戏的名称是改进算法,使差距更小、更均匀、周期更长(并且可以更快地生成更多值)。无论如何,这些事实证明假设检验是确定您的算法是否正确遵循“特定的已知概率分布”的错误方法,因为不是。(对不起。)

相反,更合适的框架是确定您的数据与理论分布的接近程度。为此,我建议重新考虑绘图,特别是qq-plotspp-plots. (再次,我认识到这一定令人沮丧,我为此道歉。)但是,您不必实际制作情节或查看它们,听起来很奇怪。相反,在适当地转换数据以进行绘图,并根据相关理论分布计算相应值后,您可以将它们关联起来。这会给你一个数字,特别是一个 r 分数,就像你想要的那样。此外,这个数字可以让您适当地衡量您的算法有多好。对于此过程,您可以生成任意数量的数据;更多数据将为您提供更高的测量精度。也就是说,我们已经将权力的概念从1β,拒绝一个真正的假空值(这是有保证的)的概率,以参数估计的角度来看的准确性。显然,您的目标是生成一种算法,让您尽可能接近r=1尽可能。对这两种类型的图执行此操作可能是值得的,因为它们具有不同的优势和劣势(具体而言,qq-plots 在分布的尾部提供更好的分辨率,而 pp-plots 在中心提供更好的分辨率)。

另一方面,关于评估算法的质量,您可能希望相对于其他标准 pRNG 对其进行计时。

希望这可以帮助。

我还没有完全阅读所有答案,但我确实看到它们非常彻底和准确。冒着重复一些埋在长答案中的风险,我只想说 v=卡方检验可用于连续数据。它可能不是最好的测试,并且像许多测试一样,它依赖于渐近理论,因此在具有稀疏细胞的小样本中可能不准确(这也取决于您如何进行分箱)。Anderson-Darling 在检验正态性方面比 KS 检验更强大,但 KS 对于其他连续分布可能更好。Lillefors 有一个专为指数分布设计的测试。