Лучший тест на хи-квадрат для Perl? - программирование
Подтвердить что ты не робот

Лучший тест на хи-квадрат для Perl?

Скажем, я рулон 6-сторонней матрицы 60 раз, и я получаю 16, 5, 9, 7, 6, 15 ролей для чисел с 1 по 6 соответственно. Числа 1 и 6 отображаются слишком много, а там только 1,8% вероятность случайности. Если я использую Статистика:: ChiSquare, он печатает:

There a >1% chance, and a <5% chance, that this data is random.

Таким образом, это не только плохой интерфейс (я не могу получить эти числа обратно напрямую), но ошибка округления значительна.

Что хуже, если я скачу 2 шестигранных кубика? Шансы получить какое-либо конкретное число:

Sum Frequency   Relative Frequency 
2   1           1/36 
3   2           2/36                                                                                                                                                                                                               
4   3           3/36
5   4           4/36
6   5           5/36
7   6           6/36
8   5           5/36
9   4           4/36
10  3           3/36
11  2           2/36
12  1           1/36

Статистика:: У ChiSquare раньше была функция chisquare_nonuniform(), но она была удалена.

Таким образом, числа округлены плохо, и я не могу использовать его для неравномерного распределения. Учитывая список фактической частоты и список ожидаемой частоты, какой лучший способ расчета теста хи-квадрат в Perl? Различные модули, которые я нахожу в CPAN, мне не помогают, поэтому я предполагаю, что пропустил что-то очевидное.

4b9b3361

Ответ 1

Реализация этого сама настолько проста, что я бы не захотел загружать еще один статистический модуль только для этого.

use Carp qw< croak >;
use List::Util qw< sum >;
use Statistics::Distributions qw< chisqrprob >;

sub chi_squared_test {
  my %args = @_;
  my $observed = delete $args{observed} // croak q(Argument "observed" required);
  my $expected = delete $args{expected} // croak q(Argument "expected" required);
  @$observed == @$expected or croak q(Input arrays must have same length);

  my $chi_squared = sum map {
    ($observed->[$_] - $expected->[$_])**2 / $expected->[$_];
  } 0 .. $#$observed;
  my $degrees_of_freedom = @$observed - 1;
  my $probability = chisqrprob($degrees_of_freedom, $chi_squared);
  return $probability;
}

say chi_squared_test
  observed => [16, 5, 9, 7, 6, 17],
  expected => [(10) x 6];

Выход: 0.018360