2014-01-18 3 views
10

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를 사용하는 경우는 출력한다 :Perl을위한 더 나은 카이 제곱 테스트?

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

그래서뿐만 아니라 그것은 나쁜 인터페이스 (I 직접 다시 그 숫자를 얻을 수 없다)하지만, 반올림 오류가 중요하다.

더 나쁜 것은, 6 면체 주사위 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 

Statistics::ChiSquare used to have a chisquare_nonuniform() function하지만 제거 : 특정 번호를 얻기의 확률이다.

그래서 숫자가 반올림되어 불규칙한 분포로 사용할 수 없습니다. 실제 빈도 목록과 예상 빈도 목록이 주어지면 Perl에서 카이 제곱 검정을 계산하는 가장 좋은 방법은 무엇입니까? CPAN에서 찾은 다양한 모듈이 도움이되지 않아 뭔가 확실한 것을 놓친 것 같아요.

+1

는 카이 테스트 제곱의 코드 아마도 20 라인에서 직접 구현하기 수학적으로 간단하다, 난 그냥 그렇게 할 것입니다보다 직접적인 컨트롤을 원하는 대부분의 사람들이 예상된다. 1 %, 5 % 등의 오류 범위는 계산하기가 더 어렵 기 때문에 간단한 유틸리티는 P <0.01, P <0.05 등의 값을 하드 코딩합니다. http://search.cpan.org/~mikek/Statistics-Distributions-1.02/Distributions.pm –

답변

13

자신을 구현하는 것은 너무 간단해서이 작업을 위해 또 다른 통계 모듈을 업로드하고 싶지는 않습니다.

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

+1

amon과 같은 일반 통계 모듈에서 더 나은 카이 제곱 테스트를 찾는 데 너무 놀라지 않을 것입니다. 감사합니다. 저건 완벽 해. 나는 그 자신을 구현하려했지만, 나는'$ chi_squared'를 계산할 때 작은 수학 오류를 만들었다. 도와 줘서 고마워! – Ovid

+3

그리고 궁금하다면 다음 글을 작성하십시오. http://blogs.perl.org/users/ovid/2014/01/testing-random-dice-rolls.html – Ovid

+0

@amon : 나는 보지 못했습니다. 'delete x // croak' 명령문을 사용하십시오. [docs] (http://perldoc.perl.org/perlop.html#Logical-Defined-Or)는 // 값으로 사용할 수없는 값을 반환한다고합니다. 그래서'delete'는 기술적으로 여기서 lvalue가 아닌 값에서만 작동해야하기 때문에 여기서 올바르게 작동합니까? –

관련 문제