假设我将一个6面骰子掷了60次,分别获得了1到6的16、5、9、7、6、15个角色。数字1和6显示的太多了,显示为there's only about a 1.8% chance of that being random。如果我使用Statistics::ChiSquare,它会打印出:

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

因此,这不仅是一个不好的接口(interface)(我无法直接获得这些数字),而且舍入误差很大。

更糟糕的是,如果我滚动两个6面骰子怎么办?获得任何特定数字的几率是:
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

Statistics::ChiSquare used to have a chisquare_nonuniform() function,但已将其删除。

因此,数字四舍五入得很差,我不能将其用于非均匀分布。给定一个实际频率列表和一个预期频率列表,在Perl中计算卡方检验的最佳方法是什么?我在CPAN上找到的各种模块对我没有帮助,所以我猜我错过了一些明显的事情。

最佳答案

您自己实现此操作非常简单,因此我不想为此仅上传“另一个统计信息”模块。

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

09-06 05:17