ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 빅데이터 분석기사 4) 카이제곱 분포와 검정(chi-squared test)
    데이터 사이언스(DS)와 통계 2024. 7. 27. 22:25

    카이 제곱 분포(χ2 분포)는 k개의 서로 독립적인 확률 변수 x에 대해 제곱하여 더한 것이다.

    이를 식으로 표현하면, 변수 𝑋1, 𝑋2,  ⋯,𝑋𝑘에 대해서

    카이제곱 분포는 (𝑋1)^2 + (𝑋2)^2  ⋯, (𝑋𝑘)^2가 된다.

     

    그리고 카이 제곱(χ2) 통계량은 아래와 같다.

    카이제곱 분포 (출처 : 나무위키)

    - s : 표본의 표준편차
    - σ : 모집단의 표준편차
    - 자유도는 n-1 (자유도에 대한 설명 :  빅데이터 분석기사 2) 중심 극한 정리와 t 검정 (t-test)

     

    카이 제곱 통계량의 모습을 보고 유추할 수 있겠지만,

    카이제곱 통계량과 분포는 '표본의 분산'을 통해 '모집단의 분산'을 '추정'할 때 활용될 수 있다.

     

    (이 밖에도 카이제곱은 비율(portion)을 검정하기 위한, 적합도/독립성 검정에도 활용될 수 있다.

     이는 추후에 다루도록 하겠다)

     

    그럼 이해를 돕기 위한 예제를 바로 확인해보자.

    예제) 
    PCB 기판 1만개 중 20개를 샘플링하여 얻은 PCB의 두께(mm)는 아래와 같이 확인된다.
    
    [50, 45, 52, 48, 49, 53, 47, 46, 51, 50, 48, 49, 52, 54, 47, 46, 50, 49, 48, 51]
    
    위 표본을 통해, PCB 기판 두께의 분산이 8mm보다 작다고 할 수 있는지 검정하여라.

     

    import numpy as np
    from scipy import stats
    import matplotlib.pyplot as plt
    
    # 귀무 가설: 분산 >= 8
    # 대립 가설: 분산 < 8
    
    # PCB 기판 두께 데이터 (예시)
    data = np.array([50, 45, 52, 48, 49, 53, 47, 46, 51, 50, 48, 49, 52, 54, 47, 46, 50, 49, 48, 51])
    
    # 자유도
    df = len(data) - 1
    
    # 표본 분산
    sample_var = np.var(data, ddof = 1)
    
    # 카이제곱 통계량 구하기
    chi_stats = df * sample_var / 8
    
    # 단측 검정 (p-value 계산)
    p_value = stats.chi2.cdf(chi_stats, df)
    
    # 시각화 및 p-value에 해당하는 영역 색칠
    x = np.linspace(0, 30, 100)
    plt.plot(x, stats.chi2.pdf(x, df))
    plt.axvline(x=chi_stats, color='r', linestyle='--')
    x_fill = np.linspace(0, chi_stats, 100)
    plt.fill_between(x_fill, stats.chi2.pdf(x_fill, df), color='red', alpha=0.5)
    
    plt.title('Chi-Square Distribution (One-tailed Test)')
    plt.xlabel('Chi-square statistic')
    plt.ylabel('Probability density')
    plt.show()
    
    print(f"Chi-square statistics: {chi_stats:.5f}")
    print(f"P-value: {p_value:.5f}")

     

    출력 결과는 아래와 같다.

    >> Chi-square statistics: 14.21875

    >> P-value: 0.22921

     

    유의 수준 5%로 결론을 내보자

    >> p-value 값은 0.2292로 0.05보다 크다.

    >> 즉, 귀무가설(=분산이 8보다 크다)을 기각할만큼 p-value 값이 작은게 아니다.

    >> 따라서 귀무가설을 기각할 수 없다.

    >> 귀무가설을 기각할 수 없으므로, 귀무가설을 채택한다.

    >>  ∴ 위 data를 통해 추정시, 분산이 8보다 작다고 볼 수 없다.

     

     

    ※ 카이제곱 검정은 샘플이 정규할 때 적용 가능하므로,

        정규성 검정을 수행한뒤 카이제곱 검정을 수행하는 것이 바람직하다.

     

    ※ 만일, 예제가 바뀌어 '분산이 8보다 작은지'에 대해 검정하는 것이 아니라,

       '분산이 8인가?' 라는 질문으로 바뀐다면 다음과 같이 수행하면 된다.

    import pandas as pd
    import numpy as np
    from scipy import stats
    import matplotlib.pyplot as plt
    
    data = np.array([50, 45, 52, 48, 49, 53, 47, 46, 51, 50, 48, 49, 52, 54, 47, 46, 50, 49, 48, 51])
    
    # 정규성 확인
    norm = stats.shapiro(data)
    
    # 자유도 구하기
    freedom = len(data) - 1
    
    # 카이제곱 통계량 구하기
    chi_stats = (freedom * np.var(data, ddof = 1)) / 8
    
    # 양측 검정 (p-value 계산)
    p_value = 2 * min(stats.chi2.cdf(chi_stats, freedom), 1 - stats.chi2.cdf(chi_stats, freedom))
    
    # 카이제곱 그래프 시각화
    x = np.linspace(0, 30, 100)
    plt.plot(x, stats.chi2.pdf(x, freedom))
    
    # chi_stats 값 표시
    plt.axvline(x=chi_stats, color='r', linestyle='--')
    
    # p-value에 해당하는 영역 색칠
    x_fill_left = np.linspace(0, stats.chi2.ppf(p_value/2, freedom), 100)
    x_fill_right = np.linspace(stats.chi2.ppf(1-p_value/2, freedom), 30, 100)
    plt.fill_between(x_fill_left, stats.chi2.pdf(x_fill_left, freedom), color='red', alpha=0.5)
    plt.fill_between(x_fill_right, stats.chi2.pdf(x_fill_right, freedom), color='red', alpha=0.5)
    
    plt.show()
    
    print(f"Chi-square statistics: {chi_stats:.5f}")
    print(f"P-value: {p_value:.5f}")

     

    출력 결과는 다음과 같다.

    >> Chi-square statistics: 14.21875

    >> P-value: 0.45841

     

    # 양측 검정 (p-value 계산)
    p_value = 2 * min(stats.chi2.cdf(chi_stats, freedom), 1 - stats.chi2.cdf(chi_stats, freedom))

     

    시각화 쪽을 제외하고, 위 부분만 변경되었다.

    카이제곱 분포는 t분포, 정규분포와는 달리 좌우 대칭이 아니다.

    그럼에도 불구하고, 양측 가설시 stats.chi2.cdf(chi_stats, freedom)과 1 - stats.chi2.cdf(chi_stats, freedom)) 중에서

    더 작은 면적 값의 2배로써 p-value를 구한다.

    728x90
Designed by Tistory.