我是统计主题的新手,所以我想我在这里遗漏的东西可能很明显。
基本上,我想根据Apache Commons Math的统计测试double
来检查某些整数值数组(直方图)是否符合具有一定显着性水平的正态分布(指定平均值和标准差) 。
我已经了解的是,常见的方法是计算p 值,然后确定零假设是否为真。
我的第一个“婴儿”步骤是使用单向方差分析测试检查两个数组是否来自同一分布(第二部分取自文档中的示例):
double samples1[] = new double[100];
double samples2[] = new double[100];
Random rand = new Random();
for (int i = 0; i < 100000; i++) {
int index1 = (int) (rand.nextGaussian()*5 + 50);
int index2 = (int) (rand.nextGaussian()*5 + 50);
try {
samples1[index1-1]++;
}
catch (ArrayIndexOutOfBoundsException e) {}
try {
samples2[index2-1]++;
}
catch (ArrayIndexOutOfBoundsException e) {}
}
List classes = new ArrayList<>();
classes.add(samples1);
classes.add(samples2);
double pvalue = TestUtils.oneWayAnovaPValue(classes);
boolean fail = TestUtils.oneWayAnovaTest(classes, 0.05);
System.out.println(pvalue);
System.out.println(fail);
结果是:
1.0
false
假设显着性水平为 0.05,我可以推断假设为真(即两个数组来自相同的分布)p > 0.05
。
现在让我们进行 Kolmogorov-Smirnov 检验。文档中的示例代码显示了如何针对某个NormalDistribution
对象检查单个数组(这是我的目标)。然而,它也允许检查两个数组。在这两种情况下我都无法得到正确的结果。例如,让我们将上面的例子改编成 KS:
double samples1[] = new double[100];
double samples2[] = new double[100];
Random rand = new Random();
for (int i = 0; i < 100000; i++) {
int index1 = (int) (rand.nextGaussian()*5 + 50);
int index2 = (int) (rand.nextGaussian()*5 + 50);
try {
samples1[index1-1]++;
}
catch (ArrayIndexOutOfBoundsException e) {}
try {
samples2[index2-1]++;
}
catch (ArrayIndexOutOfBoundsException e) {}
}
double pvalue = TestUtils.kolmogorovSmirnovTest(samples1, samples2);
boolean fail = pvalue < 0.05;
System.out.println(pvalue);
System.out.println(fail);
结果是:
7.475142727031425E-11
true
我的问题是为什么本质上相同数据的 p 值现在这么小?这是否意味着该测试不适合此类数据?
我是不是该:
- 生成参考数组
NormalDistribution
(即具有指定的平均值和标准差),然后使用单向方差分析测试(或其他)将其与我的数组进行比较 - 以某种方式调整我的数据,然后使用 KS 将单个数组与
NormalDistribution
对象进行比较
?