2

我是统计主题的新手,所以我想我在这里遗漏的东西可能很明显。

基本上,我想根据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对象进行比较

?

4

0 回答 0