일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 크롤링
- residuals
- 누락편의
- HTML
- 예제
- Python
- causal inference
- Instrumental Variable
- OVB
- LU분해
- 단순선형회귀
- 네이버 뉴스
- 인과추론
- confounder
- simple linear regression
- rct
- 최소제곱법
- 머신러닝
- 통계
- least square estimation
- 선형대수
- 사영
- 교란 변수
- Omitted Variable Bias
- 잔차의 성질
- backdoor adjustment
- Sharp RD
- 교란변수
- 회귀불연속설계
- 인과 추론
- Today
- Total
Always awake,
카이제곱 분포 모양 확인하기 본문
"본 포스팅은 카이제곱 분포의 모양을 개념적으로 확인하기 위한 포스팅입니다"
학부 때 통계 강의에서 이산확률 분포, 연속형 확률 분포를 배우며 아무렇지 않게 넘어갔던 분포의 모양에 갑자기 궁금해졌습니다.
특히, 일반적인 지수 분포, 정규분포 등은 수식을 통해서 모양을 이해할 수 있었지만 카이제곱 분포, F 분포 등은 추상적으로 분포의 모양을 이해했었습니다.
카이제곱 분포의 정의
i.i.d 한 (identically independent distributed) 한 k개의 표준 정규분포의 확률 변수를 제곱한 후 모두 더한 것은 자유도가 k인 카이제곱분포를 따른다.
모양은 아래와 같습니다.
출처 : http://blog.naver.com/PostView.nhn?blogId=mykepzzang&logNo=220852102307
카이제곱 분포 확률 계산? (표준정규분포 기반)
$Z \sim Norm(0,1)$인 표준 정규분포를 따른다고 하였을 때
$Z^2 \sim chisquare(1)$ : $Z^2$는 자유도가 1인 카이제곱 분포를 따릅니다.
자유도가 1인 카이제곱 분포의 확률변수가 1일 때의 확률은 $Z^2 = 1$이므로 $Z = ± 1$인 경우입니다.
(정규분포의 확률 변수 값이 +1, -1 일때의 확률을 더한 것과 같습니다)
즉, $Pr(Z=+1) + Pr(Z=-1)$이 됩니다.
카이제곱 분포 모양 추론 (확률변수 별 확률 계산)
카이제곱 분포의 각 확률변수 별 확률 값을 계산하여 분포의 모양을 추론하려 하였으나(표준 정규분포 확률변수로부터)
자유도가 높아지면 카이제곱분포의 확률 변수에 대응하는 각 표준정규분포의 확률변수 값의 조합이 너무 많아서
이 방법으로는 할 수 없겠다고 판단하였습니다 ㅜ
ex) 자유도가 2인 카이제곱 분포 → 확률변수 = 1일 때 확률
- i.i.d한 2개의 카이제곱 분포(자유도가 1인)의 확률변수가 각각 0.1, 0.9일 때도 가능하고, 0.2, 0.8일 때도 가능하고, 0.3, 0.7 일 때도 가능하고.... (무한한 경우의 수가 가능)
- 실수집합이므로 무한이 많은 경우의 수가 있다
- 이를 다 계산하는 것은 무리라고 생각하였습니다.
카이제곱 분포 모양 추론 (랜덤 확률변수 추출 후 빈도 기반 역추론)
그래서 생각한 방법은
분포에서 랜덤 확률 변수를 추출하여 역으로 시뮬레이션 하는 방법입니다.
- i.i.d 한 k개의 표준 정규분포에서 각각 10000개 정도씩 확률변수를 추출한다.
- 그리고 추출된 각 확률변수를 제곱하여 더하면 자유도가 k인 카이제곱 분포의 랜덤 변수가 10000개가 생길 것이다.
- 10000개의 랜덤 변수로 히스토그램을 그리면 자유도가 k인 카이제곱분포의 모양을 모양을 추론할 수 있을 것이다.
이것을 python으로 구현해보려고 합니다.
그렇다면 코드 작성 시 구체적으로 고려할 사항이 무엇이 있을지 생각해보았습니다.
- 각 표준정규분포는 서로 i.i.d 해야 한다
- → python의 표준정규분포에서 랜덤 확률 변수 추출 시 random_state 값을 다르게 설정하면 될 것 같다.
- 표준 정규 분포의 값을 제곱하여 합한 것이 카이제곱 분포이다
- → 각 시행(같은 no)에서 나온 확률변수의 값을 제곱하여 더해주면 된다.
이 두 가지를 고려하여 python의 scipy 패키지를 이용하여 코드를 작성해보았습니다.
코드 작성
패키지 importing
- scipy의 stats 모듈 : 통계 관련 함수가 있다. 여기서 정규분포 클래스를 사용합니다.
from scipy import stats as st
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import random
변수 초기화
- k_list : 확인하고자 하는 카이제곱 분포의 자유도 (1~9)
- random_state_list : 정규분포에서 랜덤 확률변수 추출 시 각 정규분포마다 사용될 random seed 값의 후보
- chi_dict
- key : 자유도(k)
- value : k개의 정규분포 랜덤 샘플 값, 제곱하여 더한 카이제곱 값이 담긴 Data frame (아래의 temp_df)
- rv : 정규분포 클래스
- chi_df : chi_dict의 각 자유도별 카이제곱 값이 담긴 Data frame
# degree of freedom for testing
k_list = [i for i in range(1, 10)]
# candidates of random state for i.i.d condition to each Normal Distribution sample
random_state_list = [i for i in range(1000)]
# key : degree of freedom, value : dataframe for 10000 sizes (columns = index column for each normal distribution sample set + chi square sample column )
chi_dict = {}
rv = st.norm(0,1)
# dataframe for chi sampled (each degree of freedom)
chi_df = pd.DataFrame()
카이제곱 분포 랜덤 확률 변수 생성
i.i.d 한 k개의 정규분포에서 10000개씩 랜덤 확률 변수를 생성 후 각각 제곱한 값을 더하여 카이제곱 랜덤 확률 변수를 생성합니다.
for k in k_list:
# value for chi_dict
temp_df = pd.DataFrame()
# sampling for each norm distribution(k replication)(i.i.d)
for i in range(1, k+1):
rand_state = random.choice(random_state_list)
random_state_list.remove(rand_state)
temp_df['%d norm sampled' % i] = rv.rvs(size = 10000, random_state = rand_state)
chi_val_colname = 'chi dof_{}_sampled'.format('0' + str(k) if k < 10 else k)
temp_df[chi_val_colname] = temp_df[['%d norm sampled' % i for i in range(1, k+1)]].apply(np.square).sum(axis = 1)
chi_dict[k] = temp_df
chi_df[chi_val_colname] = temp_df[chi_val_colname]
데이터의 생김새를 예시로 보면 다음과 같습니다.
- chi_dict[3] : k = 3인 카이제곱 분포 sample
- i.i.d 한 정규분포 k개(3개)에서 10000개씩 샘플링
- 제곱을 취한 후 합하여 chi dof_03_sampled 열 생성
- chi_df : 자유도(k)별로 생성된 카이제곱 sample
- k별로 chi_dict의 value 중 마지막 열(카이제곱 sample)을 합친 Data frame
카이제곱 분포 sample 분포 확인(Histogram)
이제 chi_df에서 자유도 별로 샘플링 된 값들을 히스토그램을 그려 분포의 모양을 확인해보겠습니다.
col_num = 3
row_num = (len(chi_df.columns) // col_num) + 1
fig, ax = plt.subplots(row_num, col_num , figsize = (col_num * 10, row_num * 5 ), sharey = True)
for idx, c in enumerate(chi_df.columns):
chi_df[c].hist(ax = ax.ravel()[idx], bins = 300)
ax.ravel()[idx].set_title(c[4:10], fontsize = 15)
fig.suptitle('chi square histogram by degree of freedom(1~9)', fontsize= 20)
이론과 어느정도 일치하는 것을 볼 수 있습니다.
마치며
피드백은 언제나 환영입니다~
▼ 글이 도움이 되셨다면 아래 클릭 한번 부탁드립니다 :) ▼
'통계' 카테고리의 다른 글
신뢰성 분석 (1) | 2021.10.11 |
---|---|
로지스틱 회귀(Logistic Regression) (3) | 2021.10.10 |
공분산과 상관계수 (11) | 2020.09.20 |
주성분 분석(PCA)의 개념적 이해 (0) | 2020.09.01 |
최대 우도 추정법(Maximum Likelihood Estimation) (5) | 2020.09.01 |