목차
카이제곱분포
Z1~Zn이 서로 독립이고 정규분포를 따를 때, 그 제곱합의 확률분포가 자유도 n인 분포 뜻한다. 제곱의 분포이기 때문에 카이제곱분포는 모두 0이상인 실수 값을 취한다.
자유도 n에 따라 분포 형태가 달라지는데, n이 커질 수록 정규분포 형태에 가까운 좌우대칭 모습을 보인다.
< 카이제곱분포 파이썬 코드 실습 >
1) 확률변수, 표본 생성
♡ stats.norm() 평균0, 표준편차1인 정규분포를 나타내는 확률변수 생성하는 함수
♡ 확률변수.rvs((n, samplesize) 지정된 확률분포에서 생성한 확률변수 중 무작위 표본을 생성하는 데 사용함.
n은 생성할 표본의 차원, samplesize는 각 차원별로 생성할 표본의 수
import scipy.stats as stats
import numpy as np
n= 5
# 평균0, 표준편차1인 정규분포 나타내는 확률변수 rv 생성
rv= stats.norm()
sample_size = int(1e6)
# rv 확률변수를 가지고 n개의 데이터포인트를 가지는 sample_size만큼의 표본생성
sample = rv.rvs((n, sample_size))
print(sample, sample.shape)
[[-1.52891528 -0.16281112 1.80195481 ... 0.34023286 -0.94406641
-0.54157451]
[-0.97497131 0.33135952 -0.10609955 ... -0.18197411 0.91626508
-0.02048008]
[ 0.82110965 -0.32006243 -0.16010214 ... -0.88200433 1.29107342
1.79579892]
[-0.43804507 -0.6907185 1.64244492 ... 0.60641174 -0.64371888
-1.3820642 ]
[ 0.56834445 -1.03830114 0.38470201 ... -2.5745323 -0.39780183
0.33746464]] (5, 1000000)
2) 카이제곱 샘플 생성
chi2_sample =np.sum(sample**2, axis=0)
chi2_sample, chi2_sample.shape
(array([4.47727094, 1.79390785, 6.1295519 , ..., 7.92275638, 3.97029395,
5.54259998]),
(1000000,))
3) 확률밀도 계산하기
참고 >>> ♡ pdf() 확률변수를 확률밀도값으로 계산함
n= 3
rv = stats.chi2(n)
rv.pdf([1,2,3])
array([0.24197072, 0.20755375, 0.15418033])
4)카이제곱분포 시각화하기
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(10,6))
ax= fig.add_subplot(111)
# 카이제곱분포 시각화 : 히스토그램
# density: 정규화되어 막대 높이의 총 합이 1, alpha : 투명도
ax.hist(chi2_sample, bins=50, density =True, alpha=0.5, label='chi2_sample')
# 확률밀도함수 시각화 : 선그래프
xs= np.linspace(0, 30, 100)
# 자유도 n 인 카이제곱분포 , 밀도가 정규화되어 막대 높이의 총 합이 1
rv_true = stats.chi2(n)
# pdf() 확률밀도값으로 계산함
ax.plot(xs, rv_true.pdf(xs), label=f'chi2{n}', color='red')
ax.legend()
ax.set_xlim(0,30)
plt.show()
자유도 n이 커질 수록 좌우대칭에 가까워짐
fig = plt.figure(figsize=(10, 6))
ax= fig.add_subplot(111)
xs= np.linspace(0, 20, 500)
# 실선, 이중대시, 점선
linestyles = ['-', '--', ':']
# 자유도 n에 따라 달라지는 분포형
for n, line in zip([3,5,10], linestyles):
rv= stats.chi2(n)
ax.plot(xs, rv.pdf(xs), label= f'chi2{n}', ls=line, color='gray')
ax.legend()
plt.show()
5) 신뢰구간 구하기
♡ isf() >>Inverse Survival Function 역생존함수, 상위 백분위수 함수 : 특정 확률에 해당하는 분포의 값의 역을 반환함
# 신뢰구간 구하기
# 확률분포의 상위 0.05(5%) 임계값 찾기
rv.isf(0.05)
18.30703805327515
카이제곱검정
- 카이제곱분포를 쓴다.
- ♡ 범주형변수
두 개이상의 범주형 변수 간의 관련성을 검정하는데 사용되는 통계분석방법이다. 두 범주형 변수가 서로 관련되어 있는지(적합성 검정) 또는 독립적인지(독립성 검정) 확인한다. 다시말해 두 범주형 변수 간의 차이가 우연인지, 아니면 특정 관계로인지 두 데이터세트를 비교함으로써 알아내는 것이다.
독립변수 | 범주형 변수 | 명목변수(순서 x, 성별, 혈액형) |
종속변수 | 순서변수(순서 o, 만족도, 학점) |
- 방법 >> Count
기본원리는 빈도(기대빈도, 관찰빈도)를 토대로 한다. 기대하는 결과(E)와 관찰한 결과(O)가 잘 맞는지 여부를 '차이'를 통해 판단한다. 해당 차이가 통계적으로 유의미한지 아닌지를 조사한다.
다시말해 실제 데이터와 예측 데이터 간의 차이가 우연으로 인한 것인지, 변수의 상관관계로 인한 것인지 확인한다. 이로써 두 범주형 변수간의 연결을 이해하고 해석하는데 도움이 된다.
기대빈도 ( E ) | 범주형 자료의 특성을 표현하는 가설이나 가정이 참이라면, 각각의 범주에 대해 기대하는 빈도가 있음 ex) 남:여 비율이 0.5이라는 가설이 참이라면, 100명 중 남자는 50명이고 여자도 50명일 것. 이것이 기대빈도임. |
관찰빈도 ( O ) | 표본으로부터 실제 측정한 값이다. ex) 실제로 남,여 100명을 조사해봤더니 남자는 30명, 여자는 70명. 이것이 관찰빈도임. |
- 교차분석표
데이터를 표로 나타내면 그룹들 간의 차이와 관계를 파악하는데 도움을 준다.
- 한계
표본의 크기에 매우 민감하다. 충분히 큰 표본을 사용하면 중요하지 않은 관계도 통계적으로 유의미하다고 나타날 수 있다. 따라서 카이제곱 검정에서 통계적으로 유의하다는 것이 항상 의미있다는 것을 뜻하지는 않는다는 것을 유념하자.
카이제곱은 두 변수가 서로 관련있는지만 확인하는 것이지, 인과관계가 있다는 것을 의미하지 않는다.
카이제곱검정 종류
1. 적합성 검정 Goodness-of-fit Test
- 각 범주에 따른 데이터의 관찰빈도가 기대빈도를 따르는가?
- 데이터의 값이 우리의 아이디어에 충분히 적합한지, 다시 말해 전체 모집단을 대표하는 적합한 샘플 데이터인지를 결정하는 방법이다.
- 관측 데이터를 예상 데이터와 비교하며 관측 데이터가 예상 분포에 얼마나 잘 맞는지 평가한다.
ex) 주사위를 굴렸을 때 관찰빈도가 기대빈도(1/6)와 같은지 검정
H0: 주사위를 던졌을 때 1이 나올 확률은 1/6이다.
H1: 주사위를 던졌을 때 1이 나올 확률은 1/6이라 할 수 없다.
< chi square test 적합성검정 파이썬 실습 >
1) 가설설정
H0: 타이타닉 생존자 중 남자는 50%, 여자는 50%이다.
H1: 타이타닉 생존자 중 남자는 50%, 여자는 50%가 아니다.
2) 데이터 테이블 만들기
-원본데이터
- 카이제곱에 맞게 정선된 데이터
# 관찰빈도
chi_data = data[['sex', 'survived']]
survived_data = chi_data[chi_data['survived']==1]
table = survived_data['sex'].value_counts()
table
female 233
male 109
Or 교차표 생성하기
cross_table = pd.crosstab(data['sex'], data['survived'])
print(cross_table)
print('------------')
table = cross_table[1]
print(table)
survived 0 1
sex
female 81 233
male 468 109
------------
sex
female 233
male 109
Name: 1, dtype: int64
3) 카이제곱 검정하기
# 카이제곱 검정하기
import scipy.stats as stats
chi= stats.chisquare(f_obs=table, f_exp=[171,171])
print(chi)
Power_divergenceResult(statistic=44.95906432748538, pvalue=2.0119672574477235e-11)
2. 독립성 검정
- 모집단이 두 개의 변수 A, B에 의해 그룹화되었을 때, 두 변수들의 관계가 독립인지 검정하는 것
- 두 변수가 상관이 있는지 없는지에 대해 초점 맞춤
- 교차분석표를 활용
ex) 채식여부와 건강등급은 독립인지 아닌지 검정
1) 가설설정
H0: 채식여부와 건강등급은 독립이다.
H1: 채식여부와 건강등급은 독립이 아니다.
건강등급1 | 건강등급2 | 건강등급3 | 합 | |
채식 0 | 4 | 2 | 2 | 8 |
채식 X | 1 | 1 | 3 | 5 |
합 | 5 | 3 | 5 |
▼
▼
2) 기대값 계산
- P(A ∩ B) = P(A)*P(B) ---> 독립이라면 ---> 기대값의 식이 성립함
건강등급1 | 건강등급2 | 건강등급3 | 합 | |
채식 0 | 4 | 2 | 2 | 8 |
기대값 | 5/13 *8/13 *13 = 40/13 | 3/13* 8 /13 *13 = 24/13 | 5/13*8/13*13= 40/13 | |
채식 X | 1 | 1 | 3 | 5 |
기대값 | 5/13 * 5/13 *13 =25/13 | 3/13*5/13*13= 15/13 | 5 /13*5 /13*13= 25/13 | |
합 | 5 | 3 | 5 | 13 |
3) 각 셀에 대해 (O-E)2/E 계산
4) 카이제곱값은 위의 모든 값의 합계
5) 자유도 = (열의 개수 -1)(행의 개수-1)
2*1 = 2
6) 판단
- 방법1 : 검정통계량 X2을 카이제곱 분포표의 임계값과 비교
카이제곱표에서 알파 수준이 0.05, 자유도 2인 경우 임계 통계는 5.991이다. 얻은 통계값이 이것보다 크다면 귀무가설을 기각할 충분한 증거가 있음을 의미한다.
- 방법 2 : 검정통계량 X2의 p값을 선택한 알파 수준 0.05와 비교
< chi square test 독립성검정 파이썬 실습 1 >
1) 가설 세우고, 교차표 만들기
H0: 채식여부와 건강등급은 독립이다.
H1: 채식여부와 건강등급은 독립이 아니다.
건강등급1 | 건강등급2 | 건강등급3 | 합 | |
채식 0 | 4 | 2 | 2 | 8 |
채식 X | 1 | 1 | 3 | 5 |
합 | 5 | 3 | 5 |
data = {
'채식여부' : ['0', '0', '0', 'X', 'X', 'X'],
'건강등급' : ['1급', '2급', '3급','1급', '2급', '3급'],
'빈도' : [4,2,2, 1, 1, 3]
}
df = pd.DataFrame(data)
df
# 빈도만큼 각 행을 늘려줌
df= df.loc[df.index.repeat(df['빈도'])]
df
♡ df.index : 데이터프레임의 인덱스를 가져옴
♡ repeat() : df['빈도'] 열을 참조하여 지정된 횟수만큼 반복함
♡ df.loc : 인덱스를 기반으로 데이터프레임에서 특정행을 선택함. 여기서는 repeat함수를 통해 반복하여 생성된 인덱스 목록을 사용하여, 원본 데이터프레임에서 해당하는 행들을 모두 선택해줌
table = pd.crosstab(df['채식여부'], df['건강등급'])
table
▼
▼
2) 기대값 계산
- P(A ∩ B) = P(A)*P(B) ---> 독립이라면 ---> 기대값의 식이 성립함
건강등급1 | 건강등급2 | 건강등급3 | 합 | |
채식 0 | 4 | 2 | 2 | 8 |
기대값 | 5/13 *8/13 *13 = 40/13 | 3/13* 8 /13 *13 = 24/13 | 5/13*8/13*13= 40/13 | |
채식 X | 1 | 1 | 3 | 5 |
기대값 | 5/13 * 5/13 *13 =25/13 | 3/13*5/13*13= 15/13 | 5 /13*5 /13*13= 25/13 | |
합 | 5 | 3 | 5 | 13 |
from scipy.stats import chi2_contingency
chi, p, df, expect = chi2_contingency(table)
print("기댓값\n", expect)
기댓값
[[3.07692308 1.84615385 3.07692308]
[1.92307692 1.15384615 1.92307692]]
3) 각 셀에 대해 (O-E)2/E 계산
4) 카이제곱값은 위의 모든 값의 합계
chi, p, df, expect = chi2_contingency(table)
print("카이제곱통계량\n", chi)
카이제곱통계량
1.7333333333333334
5) 자유도 = (열의 개수 -1)(행의 개수-1)
2*1 = 2
chi, p, df, expect = chi2_contingency(table)
print("자유도", df)
자유도 2
6) 판단
chi, p, df, expect = chi2_contingency(table)
print("pvalue", p)
pvalue 0.4203503845086819
pvalue가 0.4이므로 유의수준 0.05보다 크다. 따라서 귀무가설을 기각할 수 없으므로, 채식여부와 건강등급은 독립이다.
< 실습 2 >
1) 가설세우고 교차표(Contingency table) 생성
H0: 좌석클래스와 생존은 독립이다.
H1: 좌석클래스와 생존은 독립이 아니다.
# 교차표생성
table = pd.crosstab(data['class'], data['survived'])
table
2) 독립성 검정 후 결과분석
♡ expect: 기대빈도로 각 범주에서 관츨될것으로 기대되는 빈도를 나타냄
♡ chi : 카이제곱 통계량, 관측된 빈도와 기대 빈도 간의 차이
♡ pvalue : 두 변수 간의 독립성 여부를 판단하는 기준.
♡ df: 검정에 사용된 변수의 수와 범주의 수를 반영함 (2-1) x(3-1) = 2
from scipy.stats import chi2_contingency
chi, p, df, expect = chi2_contingency(table)
print("기댓값\n", expect)
print("카이제곱통계량\n", chi)
print("---------------")
print("pvalue", p)
print("자유도", df)
기댓값
[[133.09090909 82.90909091]
[113.37373737 70.62626263]
[302.53535354 188.46464646]]
카이제곱통계량
102.88898875696056
---------------
pvalue 4.549251711298793e-23
자유도 2
>> PVALUE가 유의수준 0.05보다 작으므로 귀무가설을 기각한다. 즉 좌석등급과 생존은 유의수준 0.05하에서 독립이라 할 수 없다.
3. 동일성 검정
- 독립성 검정과 계산법, 검정방법이 동일함.
- 두 개의 범주를 대상으로 함.
- 두 개의 범주를 a, b라고 했을 때 범주 a와 동일하게, 범주 b의 유형들이 같은 빈도로 나타나는지 검정함
ex) 성별(남/여)에 따른 혈압군(저/중/고)의 빈도 비율이 같은지 검정
H0: 성별에 따른 혈압군의 차이가 없다. 같은 빈도로 나온다. 동일하다.
H1: 성별에 따른 혈압군의 차이가 있다. 동일하지 않다.
< 참고할 사이트 >
https://www.simplilearn.com/tutorials/statistics-tutorial/chi-square-test
https://olivia-blackcherry.tistory.com/627