Образец теста Колмогорова-Смирнова 2 Java дает 0 р-значение - PullRequest
0 голосов
/ 23 апреля 2020

Я использую тест Apache Commons Math Kolmogorov-Smirnov, чтобы определить, является ли образец, который производит мой ГСЧ, равномерным распределением.

Я использую UniformIntegerDistribution для получения равномерного распределения и Я получаю образец 2000000 целых чисел. Затем я помещаю их в double[]

, который я производю из своих номеров RNG 2000000, и помещаю их в double[].

. Я нанес на график образец и вижу, что он однородный. но тест KS дает мне p-значение 0,0, которое указывало бы на то, что нулевая гипотеза о двух взятых из одного и того же распределения (т. е. Uniform) является недействительной. Это означает, что мой образец RNG не соответствует равномерному распределению.

double alpha = test.kolmogorovSmirnovTest(a, b); дает мне alpha = 0.0

И Javado c метода читает:

Вычисляет значение p или наблюдаемый уровень значимости теста Колмогорова-Смирнова с двумя выборками, оценивая нулевую гипотезу о том, что x и y являются выборками, взятыми из одного и того же распределения вероятности.

Таким образом, я ожидаю, что значение 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()));

Меня беспокоит то, что если я создам new UniformIntegerDistribution и получить sample2, а затем поместить его в test.kolmogorovSmirnovTest(a, b);, я действительно получаю значение p, близкое к 1, что я и ожидаю.

Я либо делаю что-то не так с Java или в числах, производимых ГСЧ, есть что-то, чего я не получаю.

Код для 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 = SecureRandom.getInstance("NativePRNGNonBlocking");

1 Ответ

0 голосов
/ 25 апреля 2020

Я нашел причину проблемы. UniformRealDistribution, который я использовал изначально, так как он работает с kolmogorovSmirnovTest(RealDistribution distribution, double[] data)

По какой-то причине, однако, UniformIntegerDistribution является inclusinve-эксклюзивным.

Когда я изменил IntegerDistribution uniform = new UniformIntegerDistribution(1, 81); на IntegerDistribution uniform = new UniformIntegerDistribution(1, 80); это сработало.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...