java - Kolmogorov-Smirnov 2 样本测试 Java 给出 0 p 值

标签 java math random kolmogorov-smirnov

我正在使用 Apache Commons Math Kolmogorov-Smirnov 测试来确定我的 RNG 生成的样本是否是均匀分布。

我使用 UniformIntegerDistribution 生成均匀分布,并获得 2000000 个整数的样本。然后我将它们放入 double[]

我也从我的 RNG 2000000 号码中生成并将它们放入 double[] 中。

我绘制了样本,发现它是均匀的,但 K-S 检验给出的 p 值为 0.0,这表明从同一分布(即均匀分布)得出的两者的原假设无效。这意味着我的 RNG 样本不符合均匀分布。

double alpha = test.kolmogorovSmirnovTest(a, b); 给我alpha = 0.0

该方法的 Javadoc 如下:

Computes the p-value, or observed significance level, of a two-sample Kolmogorov-Smirnov test evaluating the null hypothesis that x and y are samples drawn from the same probability distribution.

因此,鉴于我看到绘图明显均匀,我预计 p 值会很高。

    IntegerDistribution uniform = new UniformIntegerDistribution(1, 81);

    ArrayList<Integer> lis = new ArrayList<>();
    int i = 0;
    while (i < 100000) {

        //Creates a list of 20 numbers ε [1,80]
        List<Integer> l = ls.createRandomNumbersInclusive(80, 20);
        lis.addAll(l);
        Assertions.assertFalse(l.stream().anyMatch(it -> it > 80));
        Assertions.assertFalse(l.stream().anyMatch(it -> it < 1));

        i++;
    }

    KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();

    var sample = uniform.sample(2000000);

    List<Integer> ll = new ArrayList<>();
    double[] a = new double[2000000];

    for(var j = 0; j<2000000; j++) {
        a[j] = sample[j];
    }

    double[] b = lis.stream().map(it -> Double.valueOf(it)).mapToDouble(Double::doubleValue).toArray();

    var alpha = test.kolmogorovSmirnovTest(a, b); 

    System.out.println("Alpha "+ alpha); //This gives me 0.0

     /** I am doing the below to get the count per numbers [1,80] and plot them.
     * I see them being uniform 
     * 1 ===
     * 2 ===
     *  ...
     * 80 === 
     */
     Map<Integer, Long> result = lis.stream().collect(Collectors.groupingBy(it -> it, Collectors.counting()));

令我担心的是,如果我创建一个新的 UniformIntegerDistribution 并获取 sample2 ,然后将其放入 test.kolmogorovSmirnovTest(a, b); ,我确实得到了接近 1 的 p 值,这正是我所期望的。

我要么在 Java 上做错了什么,要么是 RNG 生成的数字中有一些我没有得到的东西。

createRandomNumbersInclusive 的代码是

public List<Integer> fetchNumberList(final int drawNumberMin, final int drawNumberMax, final int drawNumberCount) {

    final List<Integer> range = new ArrayList<Integer>();
    for (int i = drawNumberMin; i <= drawNumberMax; i++) {
        range.add(i);
    }

    Collections.shuffle(range, rng);

    return new ArrayList<Integer>(range.subList(0, drawNumberCount));
}

RNG 是 rng = SecureRandom.getInstance("NativePRNGNonBlocking");

最佳答案

我找到了问题背后的原因。我最初使用的 UniformRealDistributionkolmogorovSmirnovTest(RealDistribution distribution, double[] data)

一起使用

但是,出于某种原因,UniformIntegerDistribution 是包含-排除的。

当我将 IntegerDistributionuniform = new UniformIntegerDistribution(1, 81); 更改为 IntegerDistributionuniform = new UniformIntegerDistribution(1, 80); 它起作用了。

关于java - Kolmogorov-Smirnov 2 样本测试 Java 给出 0 p 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61394774/

相关文章:

java - 一个不使用compare.To按字母顺序对字符串进行排序的程序(Java)

java - 将 UUID 与 EclipseLink 和 PostgreSQL 一起使用

javascript - 实现用于输入数学公式的 GUI 的简单方法?

c# - 序列不包含任何元素

java - 使用 Play Framework 代替 Tomcat 的初始上下文

java - Camel-CXF 中如何处理 SOAP header ?

Python:使用线程求解多个线性系统

javascript - WebGL - 沿行进方向旋转对象

algorithm - 为程序游戏内容生成六边形内的随机点

java - 如何使用 Java 从属性文件中选择一组 5 个随机值?