-
통계-9 모수 검정, 비모수 검정, 윌콕슨 부호순위 검정, 오류와 보정통계 2023. 5. 30. 14:39
1. 모수검정과 비모수 검정
모수검정은 모집단의 모수에 대하여 가정을 하여 검정하는 것이고 비모수 검정은 가정을 하지 않고 검정하는 것이다.
모수 검정은 모집단이 정규분포이며 집단 내의 분산이 같아야 한다. 모수 검정의 장점은 유의미한 검정을 도출할 가능성이 높다.
비모수 검정은 모집단의 형태와 관계없이 주어진 데이터에서 직접 확률을 계산한다. 비모수 검정의 장점은 평균에 특화된 모수 검정과 달리 중위수에 특화되었기 때문에 데이터의 경향을 더 잘 파악할 수 있다. 또한 표본 크기가 너무 작거나 이상치가 있을 때도 사용할 수 있다.
따라서 평균이 분포의 중심을 더 정확하게 나타내며 데이터의 크기가 작지 않다면 검정력이 강한 모수검정을 사용한다. 하지만 중위수가 분포의 중심을 더 정확하게 나타낸다면 비모수 검정을 사용한다.
np.random.seed(42) n=100 mu1,mu2 = 0, 0.5 sigma = 1 data1 = np.random.normal(mu1, sigma, n) data2 = np.random.normal(mu2, sigma, n) m=30 data3 = np.random.uniform(0,1,m) data4 = np.random.uniform(0.5,1.5,m) t_stats, p_val = stats.ttest_ind (data1, data2) print('t_statistic: {:.3f}, p-value: {:.3f}'.format(t_stats,p_val)) t_statistic: -4.755, p-value: 0.000
n=100, mu1을 0, mu2를 0.05, sugma를 1로 설정하여 데이터 1,2를 생성한다. unifom 함수를 사용하여 0~1, 0.5~1.5 사이의 균일한 값을 30개 리턴하는 데이터 3,4를 생성한다.
그다음 모수검정의 방법인 t검정을 실행한다. t-statistic의 값이 작을수록 두 집단 사이의 차이가 작다는 것을 의미한다.
p-value가 0.05 이하 이기 때문에 두 집단 간의 차이가 유의미하다고 말할 수 있다.
u_stats, p_val = stats.mannwhitneyu (data3, data4) print('u_statistic: {:.3f}, p-value: {:.3f}'.format(u_stats,p_val)) u_statistic: 145.000, p-value: 0.000
비모수 검정의 방벙인 u 검정을 실행한다. 두 개의 독립적인 data3,4에 대하여 실행하며 p-value가 0.05 이하이기 때문에 두 집단 간의 차이가 유의미하다고 말할 수 있다.
2. 부호 검정
부호검정은 두 표본들의 같은 분포를 가지고 있는지를 검정하는 비모수적 검정방법이다.
두개의 집단에서 차이가 0인경우에는 부호를 생략하고 차이가 0보다 큰 경우에 +, 작은 경우에는 - 기호를 붙인 다음 각각의 개수를 세어 이항 검정을 진행한다.
np.random.seed(42) n=20 mu=9 data = np.random.normal(mu,size=n) print(data) mu0 = 9 n_above_mu0 = sum(data>mu0) p_value = binom_test(n_above_mu0, n=n) print(f'data above mu0:{n_above_mu0}') print(f'binom test result: {p_value}') [ 9.49671415 8.8617357 9.64768854 10.52302986 8.76584663 8.76586304 10.57921282 9.76743473 8.53052561 9.54256004 8.53658231 8.53427025 9.24196227 7.08671976 7.27508217 8.43771247 7.98716888 9.31424733 8.09197592 7.5876963 ] data above mu0:8 binom test result: 0.5034446716308594
9를 기준으로 20개의 랜덤한 데이터를 생성한다. 검정할 값 mu0를 9로 설정하고 9보다 큰 경우를 기대하는 binpm_test 함수를 실행한다. p-value의 값이 0.05보다 큰 0.5이므로 기준 값인 9보다 큰 비율이 유의미하게 높지 않다고 말할 수 있다.
3. 윌콕슨 부호순위 검정(Wilcoxon signed-rank test))
윌콕슨 부호순위 검정은 중앙값을 비교하는 검정이다.
data1 = [20,25,30,35,45,45,50,55,60,65] data2= [10,20,25,30,35,40,45,50,55,60] stat, p = wilcoxon(data1,data2) print('stat',stat) print('p-value', p) if p > 0.05: print('same distribution') else: print('diffent distribution, reject h0') stat 0.0 p-value 0.001953125 diffent distribution, reject h0
윌콕슨 검정의 일반적인 귀무가설은 중앙값이 같다이다. 윌콕슨 검정을 진행한 결과 p-value가 0.05보다 낮기 때문에 귀무가설을 기각한다. 귀무가설을 기각했기 때문에 서로 다른 중앙값을 가지고 있으며 유의미하다.
wilcoxon 함수에서 추출할 수 있는 p-value 외의 stat 값은 두 집단 간의 순위의 차이를 의미한다. 위의 문제에서는 순위의 차이가 없다고 판단한 모습이다.
pre_treatment = np.random.randint(1,10,size=20) post_treatment =np.random.randint(-3,4,size=20) data = pd.DataFrame({'pre_treatment': pre_treatment, 'post_treatment':post_treatment}) data.to_csv('../data/treatment_data.csv',index=False,encoding= 'utf-8')
1~10, -3~4까지의 랜덤값을 20개씩 생성하고 데이터프레임을 저장한다.
treat_data = pd.read_csv('../data/treatment_data.csv') stat, p = wilcoxon(data['pre_treatment'], data['post_treatment']) print('stat',stat) print('p-value', p) if p > 0.05: print('same distribution') else: print('diffent distribution') stat 0.0 p-value 1.9073486328125e-06 same distribution
데이터를 윌콕슨 검정을 실시하면 분포는 같으나 p-value가 유의 수준을 넘어가기 때문에 귀무가설을 기각하지 않고 중앙값의 모집단은 기댓값과 같다는 것을 알 수 있다. 전 후 점수 간의 평균값의 차이가 없다.
fig, ax = plt.subplots() data.boxplot(['pre_treatment', 'post_treatment'], ax=ax) ax.set_title('Boxplot of Pre-treatment and Post-treatment') ax.set_ylabel('Treatment Score') plt.show() fig, ax = plt.subplots() data['diff'] = data['post_treatment'] - data['pre_treatment'] ax.hist(data['diff'], bins=10) ax.set_title('Distribution of Differences') ax.set_xlabel('Difference') ax.set_ylabel('Frequency') plt.show()
박스플롯으로 위의 데이터를 시각화할 수 있다.
두 집단 간의 차이를 막대 그래프로 그리면 정규분포를 따르지 않는다는 것을 알 수 있다.
윌콕슨 검정은 이렇게 정규성을 따르지 않는 데이터에 많이 사용된다.
4. 다중 검정(1종오류, 2종오류)
다중 검정은 하나의 데이터 집합에 대해 여러 개의 가설 검정을 동시에 수행하는 것이다.
여러 개의 가설을 검정하므로 오류가 발생할 가능성이 높아지며 1종오류와 2종오류로 구분된다.
1종오류: 귀무가설이 참이지만 귀무가설을 기각하는 오류이다.
귀무가설의 p-value가 유의 수준보다 크기 때문에 기각했는데 alpha 구간에 해당할 확률이다.
2종오류: 귀무가설이 거짓이지만 귀무가설을 채택하는 오류이다.
귀무가설의 p-value가 유의수준보다 작기 때문에 채택했는데 beta 구간에 해당할 확률이다.
5. bonferroni 보정, benjamini-hochberg 보정
위의 오류들을 줄이기 위해 등장한 것이 본페로니 보정과 benjamini-hochberg보정이다.
본페로니 보정: 검정하는 가설의 개수가 늘어날수록 1종오류가 발생할 확률을 가설의 개수만큼 배로 커지게 된다. 이를 보정하기 위해서 유의 수준을 가설의 개수로 나눠주는 것이다.
본페로니 검정의 문제점은 1종오류를 보정할 수 있지만 유의수준을 가설의 개수로 나눠주기 때문에 결국 가설의 숫자가 늘어날수록 귀무가설을 채택할 확률이 극도로 낮아져 검정력을 상실하게 된다.
benjamini-hochberg 보정: 본페로니 보정의 단점을 보완하기 위해 각각의 가설 검정의 p-value를 내림차순 정렬한다. 그다음 각 p-value에 고유한 번호를 매겨 (유의 수준/가설의 개수 * 고유한 번호)처럼 고유한 번호를 곱해주는 것이다.
bh 보정은 다른 방법들에 비해 덜 보수적이면서(기각할 확률이 그렇게 높지 않다.) 가설의 수가 많을 때 사용한다.
data = pd.read_csv("../data/treatment_data.csv") p_values = [] for i in range(10) : sample = data.sample(frac=0.5) st, p = wilcoxon(sample['pre_treatment'], sample['post_treatment']) print("sample", i+1, ':') print('statistic : ', st) print('p-value', p) p_values.append(p) if p > 0.05 : print("fail to reject HO") else : print("reject HO") alpha 0.05= rejects_bonf, corrected_p_bonf, _, _ = multipletests(p_values, alpha=alpha, method='fdr_bh') print("Bonferroni") for i in range(len(rejects_bonf)) : if rejects_bonf[i] : print(f"sample : {i+1} : reject HO" ) else : print(f"sample : {i+1} : fail to reject HO") sample 1 : statistic : 8.0 p-value 0.15417425672344237 fail to reject HO sample 2 : statistic : 12.0 p-value 0.3883232289789247 fail to reject HO sample 3 : statistic : 12.5 p-value 0.43320586241890346 fail to reject HO sample 4 : statistic : 2.0 p-value 0.022613287888229715 reject HO sample 5 : statistic : 17.0 p-value 0.8856765410584817 fail to reject HO sample 6 : statistic : 16.0 p-value 0.4351611799066696 fail to reject HO sample 7 : statistic : 17.0 p-value 0.8866897393567406 fail to reject HO sample 8 : statistic : 2.0 p-value 0.039591763236690385 reject HO sample 9 : statistic : 13.0 p-value 0.4772893402694307 fail to reject HO sample 10 : statistic : 7.5 p-value 0.5236085643722508 fail to reject HO Bonferroni sample : 1 : fail to reject HO sample : 2 : fail to reject HO sample : 3 : fail to reject HO sample : 4 : fail to reject HO sample : 5 : fail to reject HO sample : 6 : fail to reject HO sample : 7 : fail to reject HO sample : 8 : fail to reject HO sample : 9 : fail to reject HO sample : 10 : fail to reject HO
data.sample의 frac 메소드로 50프로인 10개의 데이터만 리턴한다. 이것을 윌콕슨 함수를 넣고 10번 반복한다.
이것을 반복했을 때 1종 오류가 발생할 수 있고 이것을 본페로니 함수에 넣어 보정할 수 있다. 귀무가설이 참이지만 귀무가설을 기각하는 오류를 보정한 것이다.
alpha = 0.05 rejects_bh, corrected_p_bh, _, _ = multipletests(p_values, alpha=alpha, method='fdr_bh') print("Bebjamini-Hochberg corrrection:") for i in range(len(rejects_bonf)) : if rejects_bh[i] : print(f"sample : {i+1} : reject HO" ) else : print(f"sample : {i+1} : fail to reject HO") Bebjamini-Hochberg corrrection: sample : 1 : fail to reject HO sample : 2 : fail to reject HO sample : 3 : fail to reject HO sample : 4 : fail to reject HO sample : 5 : fail to reject HO sample : 6 : fail to reject HO sample : 7 : fail to reject HO sample : 8 : fail to reject HO sample : 9 : fail to reject HO sample : 10 : fail to reject HO
bh 보정을 실시하여도 동일하게 수정된 값을 얻을 수 있다.
'통계' 카테고리의 다른 글
통계-11 크루스칼 왈리스 검정, 프리드만 검정 (0) 2023.05.31 통계-10 윌콕슨 순위합 검정 (0) 2023.05.31 통계-8 확률 분포 (0) 2023.05.30 통계-7 상관 분석 (0) 2023.05.29