수식이 깨질 경우 새로고침을 눌러주세요.
가설과 검정 ③¶
One-Tailed Test(단측 검정) vs Two-Tailed Test(양측 검정)¶
One-Tailed Test(단측 검정)¶
$$\alpha = 0.05\;인\; 경우 \;\; critical\; value는\; \text{CDF}(1-\alpha) = \text{CDF}(0.95) $$부호가 결정되어 있는 경우 $$H_0\;:\; \mu \leq 0\;:\;\; \mu가\; 양수이면서\; 희귀한\; 검정통계량\; 값이\; 나오는\; 경우에만\; 기각 $$
$$H_0\;:\; \mu \geq 0\;:\;\; \mu가\; 음수이면서\; 희귀한\; 검정통계량\; 값이\; 나오는\; 경우에만\; 기각 $$$$\alpha = 0.05\;인\; 경우 \;\; critical\; value는\; \text{CDF}(\alpha) = \text{CDF}(0.05) $$
Two-Tailed Test(양측 검정)¶
$$ H_0\;:\;\; \mu = 0\;:\;\; 부호와\; 상관없이\; 크기가\; 더\; 희귀한\; 검정통계량\; 값이\; 나오는\; 경우\; 기각 $$$$\alpha = 0.05\;인\; 경우 \;\; critical\; value는\; \text{CDF}(\alpha/2) = \text{CDF}(0.025)\; 와 \;\text{CDF}(1-\alpha/2) = \text{CDF}(0.975) $$# -*- coding: utf-8 -*-
import seaborn as sns
import pandas as pd
import scipy as sp
import matplotlib as mpl
import matplotlib.pylab as plt
import numpy as np
%matplotlib inline
from matplotlib.patches import Polygon
x = np.linspace(-5, 5, 100)
y = sp.stats.norm.pdf(x)
def plot_tailed(f, subplot, alpha, title=None):
ax = f.add_subplot(subplot)
ax.plot(x, y, linewidth=2)
plt.hold(True)
# critical point
cr1 = sp.stats.norm.ppf(alpha)
## np.sign(x) -> -1, 0 으로 출력(x < 0 → -1, 나머지 경우는 0)
cr2 = cr1 + np.sign(cr1) * 10
ix = np.linspace(cr1, cr2, 100)
iy = sp.stats.norm.pdf(ix)
verts = [(cr1, 0)] + list(zip(ix, iy)) + [(cr2, 0)]
poly = Polygon(verts)
ax.add_patch(poly)
plt.xlim(-5, 5)
if title is not None:
plt.title(title)
alpha = 0.05
f = plt.figure(figsize=(20, 5))
plot_tailed(f, 131, alpha, "Negative One-Tailed")
plot_tailed(f, 133, 1 - alpha, "Positve One-Tailed")
plot_tailed(f, 132, alpha/2)
plot_tailed(f, 132, 1 - alpha/2, "Two-Tailed")
자주 쓰이는 검정 유형¶
이산 분포 파라미터 테스트
- Bernoilli 분포의 파라미터 값이 theha인가 아닌가
- Binomial Test
- Categorical 분포의 파라미터 값이 theta vector인가 아닌가
- Chi-Square Test
정규 분포 파라미터 테스트
- 정규 분포의 mean 값이 0인가 아닌가
- One-sample z-test (분산값을 아는 경우)
- One-sample t-test (분산값을 모르는 경우)
- 두 독립 정규 분포의 mean 값이 같은가 다른가
- Independent-Two-sample t-test
- 두 Paired 정규 분포의 mean 값이 같은가 다른가
- Paired-Two-sample t-test
- 두 정규 분포의 variance 값이 같은가 다른가
- Equal-Variance test
분포 확인 테스트
- 분포가 정규 분포인가 아닌가
- Normality test
- 두 분포가 같은 분포인가 아닌가 ← 기준이 되는 분포를 하나를 두고(대조군)
- Kolmogorov Smirnov test
기초적인 검정을 실습해보자.¶
이항 검정 (Binomial test)¶
이항 검정은 이항 분포를 이용하여 Bernoulli 분포 모수 theta에 대한 가설을 조사하는 검정 방법이다.
- SciPy stats 서브패키지의
binom_test
를 사용한다.- 디폴트 귀무 가설은 theta = 0.5
- scipy.stats.binom_test
N = 10
theta = 0.5
np.random.seed(0)
x = sp.stats.bernoulli(theta).rvs(N)
n = np.count_nonzero(x)
n
# N번 시행 중 n번 성공할 확률
sp.stats.binom_test(n, N)
유의 확률(p-value) = 34%로 높으므로 다음 귀무 가설을 기각할 수 없다.¶
$$ H_0 : \theta = 0.5 $$$$ ex \;2)\; 데이터\; 갯수\; N=100,\; 실제\; 모수\; \theta = 0.5인\; 경우,\; 이항\; 검정을\; 해보자. $$
N = 100
theta = 0.5
np.random.seed(0)
x = sp.stats.bernoulli(theta).rvs(N)
n = np.count_nonzero(x)
n
sp.stats.binom_test(n, N)
유의 확률(p-value) = 92%로 높으므로 다음 귀무 가설을 기각할 수 없다.¶
$$ H_0 : \theta = 0.5 $$$$ ex \;3)\; 데이터\; 갯수\; N=100,\; 실제\; 모수\; \theta = 0.35인\; 경우,\; 이항\; 검정을\; 해보자. $$
N = 100
theta = 0.35
np.random.seed(0)
x = sp.stats.bernoulli(theta).rvs(N)
n = np.count_nonzero(x)
n
sp.stats.binom_test(n, N)
유의 확률(p-value)이 0.018%로 낮으므로 다음 귀무 가설을 기각한다.¶
$$ H_0 : 기각 → \theta \neq 0.5 $$카이 제곱 검정 (Chi-square test)¶
카이 제곱 검정은 goodness of fit 검정이라고도 부른다.
Multinoulli 시도시 성공한 횟수로 파라미터 theta 벡터가 정해진 값을 만족하는지 검사한다. $$ 카테고리\; 분포의\; 모수\; \theta=(\theta_1, \ldots, \theta_K)에\; 대한\; 가설을\; 조사하는\; 검정\; 방법이다. $$
SciPy stats 서브패키지의
chisquare
명령을 사용한다.
디폴트 귀무 가설은 $\theta = \left(\frac{1}{K}, \ldots, \frac{1}{K} \right)$이다.
N = 10
K = 4
theta = np.ones(K)/K
np.random.seed(0)
# k개의 카테고리에서 p의 확률로, 이를 10번 수행해라.
x = np.random.choice(K, N, p=theta)
n = np.bincount(x, minlength=K)
n
# 카테고리로 나눠진 어레이를 인풋으로 넣어준다.
sp.stats.chisquare(n)
유의 확률(p-value)이 15.7%로 높으므로 귀무 가설을 기각할 수 없다.¶
$$ 따라서\; H_0 : \theta \;=\; (0.25,\; 0.25,\; 0.25,\; 0.25)이다. $$$$ ex 2)\;\;데이터\; 개수\; N=100,\; 실제\; 모수\; \theta\;=\;(0.35,\; 0.20,\; 0.20,\; 0.15)인\; 경우\; 카이\; 제곱\; 검정을\; 해보자. $$
N = 100
K = 4
theta = np.array([0.35, 0.30, 0.20, 0.15])
np.random.seed(0)
# k개의 카테고리에서 p의 확률로, 이를 10번 수행해라.
x = np.random.choice(K, N, p=theta)
n = np.bincount(x, minlength=K)
n
sp.stats.chisquare(n)
유의 확률(p-value)이 0.087%이므로 귀무 가설을 기각할 수 있다.¶
$$ 따라서\;H_0 : 기각 → \;\theta \neq (0.25,\; 0.25,\; 0.25,\; 0.25)이다. $$단일 표본 z-검정 (One-sample z-test)¶
단일 표본 z-검정은 모분산의 값을 정확히 알고 있는 정규 분포의 표본에 대해 기대값을 조사하는 검정 방법이다.
- 단, 실제로 이런 경우는 없어 사용할 일이 없다.
단일 표본 z-검정의 경우에는 SciPy에 별도의 함수가 준비되어 있지 않으므로
norm
명령의cdf
메서드를 사용하여 직접 구현해야 한다.
N = 10
mu = 0
np.random.seed(0)
x = sp.stats.norm(mu).rvs(N)
x
def z_test_1_sampling(x, sigma_2=1, mu=0):
z = (x.mean() - mu)/ np.sqrt(sigma_2 / len(x))
p_value = 2 * sp.stats.norm().sf(np.abs(z))
return (z, p_value)
z_test_1_sampling(x)
유의 확률(p-value) = 0.0196 이므로 유의 수준 = 0.05 이라면 귀무 가설을 기각할 수 있다.¶
$$H_0 : 기각 → \mu \neq 0$$이 경우는 검정 결과가 오류인 예라고 볼 수 있다.
- 검정 결과가 오류로 나온 이유는 데이터 수가 10개로 부족하기 때문이다.
- 제 1종 오류(Type 1 Error) : 귀무 가설이 참임에도 기각하는 경우
N = 100
mu = 0
np.random.seed(0)
x = sp.stats.norm(mu).rvs(N)
z_test_1_sampling(x)
유의 확률(p-value) = 0.5497 이므로 귀무 가설을 기각할 수 없다.¶
$$ H_0 : \mu = 0 $$단일 표본 t-검정 (One-sample t-test)¶
정규 분포의 표본에 대해 기대값을 조사하는 검정 방법이다.
scipy의 stats 서브 패키지의
ttest_1samp
을 사용한다.
ttest_1samp
명령의 경우에는 디폴트 모수가 없으므로popmean
인수를 사용하여 직접 지정해야 한다.- scipy.stats.ttest_1samp
N = 10
mu = 0
np.random.seed(0)
x = sp.stats.norm(mu).rvs(N)
sns.distplot(x, kde=False, fit=sp.stats.norm)
plt.show()
sp.stats.ttest_1samp(x, popmean=0)
p-value = 0.0468 이므로 유의 수준 = 0.05일 때 귀무가설을 기각할 수 있다.¶
$$H_0 : 기각 → \mu \neq 0 $$마찬가지로 제 1종 오류(귀무가설이 참일 때 기각할 오류, 샘플수가 적기 때문이다.)
N = 100
mu = 0
np.random.seed(0)
x = sp.stats.norm(mu).rvs(N)
sns.distplot(x, kde=False, fit=sp.stats.norm)
plt.show()
sp.stats.ttest_1samp(x, popmean=0)
p-value = 0.5562 이므로 유의 수준 = 0.05일 때 귀무가설을 기각할 수 없다.¶
$$H_0 : \mu = 0 $$독립 표본 t-검정 (Independent-two-sample t-test)¶
Independent-two-sample t-test는 간단하게 two sample t-test라고도 한다.
- 두 개의 독립적인 정규 분포에서 나온 두 개의 데이터 셋을 사용하여 두 정규 분포의 기대값이 동일한지를 검사한다.
- scipy stats 서브패키지의
ttest_ind
를 사용한다.- 독립 표본 t-검정은 두 정규 분포의 분산값이 같은 경우와 같지 않은 경우에 사용하는 검정 통계량이 다르다.
equal_var
인수를 사용하여 이를 지정해 주어야 한다.- scipy.stats.ttest_ind
N_1 = 10; mu_1 = 0; sigma_1 = 1
N_2 = 10; mu_2 = 0.5; sigma_2 = 1
np.random.seed(0)
x1 = sp.stats.norm(mu_1, sigma_1).rvs(N_1)
x2 = sp.stats.norm(mu_2, sigma_2).rvs(N_2)
plt.figure(figsize=(12,6))
sns.distplot(x1, kde=False, fit=sp.stats.norm)
sns.distplot(x2, kde=False, fit=sp.stats.norm)
plt.show()
sp.stats.ttest_ind(x1, x2, equal_var=True)
N_1 = 50; mu_1 = 0; sigma_1 = 1
N_2 = 100; mu_2 = 0.5; sigma_2 = 1
np.random.seed(0)
x1 = sp.stats.norm(mu_1, sigma_1).rvs(N_1)
x2 = sp.stats.norm(mu_2, sigma_2).rvs(N_2)
plt.figure(figsize=(12,6))
sns.distplot(x1, kde=False, fit=sp.stats.norm)
sns.distplot(x2, kde=False, fit=sp.stats.norm)
plt.show()
sp.stats.ttest_ind(x1, x2, equal_var=True)
p-value = 0.0081 이므로 유의 수준 = 0.05일 때 귀무가설을 기각할 수 있다.¶
$$H_0 : 기각 → \mu_1 \neq \mu_2 $$대응 표본 t-검정 (Paired-two-sample t-test)¶
대응 표본 t-검정은 독립 표본 t-검정을 두 집단의 샘플이 1대1 대응하는 경우에 대해 수정한 것이다.
즉, 독립 표본 t-검정과 마찬가지로 두 정규 분포의 기대값이 같은 지 확인하기 위한 검정
- 예를 들어 어떤 반의 학생들이 특강을 수강하기 전과 수강한 이후에 각각 시험을 본 시험 점수의 경우에는 같은 학생의 두 점수는 대응할 수 있다.
- 이 대응 정보를 알고 있다면 보통의 독립 표본 t-검정에서 발생할 수 있는 샘플 간의 차이의 영향을 없앨 수 있기 때문에 특강 수강의 영향을 보다 정확하게 추정할 수 있다.
- scipy.stats.ttest_rel
N = 5
mu_1 = 0
mu_2 = 0.5
np.random.seed(1)
x1 = sp.stats.norm(mu_1).rvs(N)
# 표준편차 = 0.1 추가로 설정
x2 = x1 + sp.stats.norm(mu_2, 0.1).rvs(N)
plt.figure(figsize=(12,6))
sns.distplot(x1, kde=False, fit=sp.stats.norm)
sns.distplot(x2, kde=False, fit=sp.stats.norm)
plt.show()
sp.stats.ttest_rel(x1, x2)
p-value = 0.002 이므로 유의 수준 = 0.05일 때 귀무가설을 기각할 수 있다.¶
$$H_0 : 기각 → \mu_1 \neq \mu_2 $$5 개의 데이터만으로도 두 평균이 다르다는 것을 알아낼 수 있다.
카이 제곱 분산 검정 (Chi-Square Test for the Variance)¶
지금까지는 정규 분포의 기대값을 비교하는 검정을 살펴보았다. 이제는 정규 분포의 분산에 대해 살펴보자.
카이 제곱 분산 검정(Chi-Square Test for the Variance)은 정규 분포의 샘플 분산값은 정규화하면 카이 제곱 분포를 따른다는 점을 이용하는 검정 방법이다.
scipy는 카이 제곱 분산 검정에 대한 명령이 없으므로
chi2
클래스를 사용하여 직접 구현해야 한다.
def chi2var_test(x, sigma2=1):
v = x.var(ddof=1)
t = (len(x) - 1)*v/sigma2
p_value = sp.stats.chi2(df=len(x)-1).sf(np.abs(t))
return (t, p_value)
N = 10
mu_0 = 0
sigma_0 = 1.1
np.random.seed(0)
x = sp.stats.norm(mu_0, sigma_0).rvs(N)
plt.figure(figsize=(12,6))
sns.distplot(x, kde=False, fit=sp.stats.norm)
plt.show()
x.std()
chi2var_test(x)
p-value = 0.2546 이므로 유의 수준 = 0.05일 때 귀무가설을 기각할 수 없다.¶
$$H_0 : 채택 → \sigma_0 = 1.1 $$등분산 검정 (Equal-variance test)¶
등분산 검정은 두 정규 분포로부터 생성된 두 개의 데이터 집합으로부터 두 정규 분포의 분산 모수가 같은지 확인하기 위한 검정이다.
- 가장 기본적인 방법은 F분포를 사용하는 것이지만 실무에서는 이보다 더 성능이 좋은 bartlett, fligner, levene 방법을 주로 사용한다.
- scipy의 stats 서브패키지는 이를 위한
bartlett
,fligner
,levene
명령을 제공한다.- scipy.stats.bartlett
- scipy.stats.fligner
- scipy.stats.levene
N1 = 100
N2 = 100
sigma_1 = 1
sigma_2 = 1.2
np.random.seed(0)
x1 = sp.stats.norm(0, sigma_1).rvs(N1)
x2 = sp.stats.norm(0, sigma_2).rvs(N2)
plt.figure(figsize=(12,6))
sns.distplot(x1, kde=False, fit=sp.stats.norm)
sns.distplot(x2, kde=False, fit=sp.stats.norm)
plt.show()
x1.std(), x2.std()
sp.stats.bartlett(x1, x2)
sp.stats.fligner(x1, x2)
sp.stats.levene(x1, x2)
bartlett | fligner | levene | |
---|---|---|---|
p-value | 0.03917 | 0.0071 | 0.0061 |
위에서 보듯이 세 가지의 등분산 검정 결과 모두 귀무 가설을 기각할 수 있다.¶
$$H_0 : 기각 → \sigma_1 \neq \sigma_2 $$
statsmodels에서 제공하는 정규성 검정 명령어¶
- Omnibus Normality test
- Jarque–Bera test
- Kolmogorov-Smirnov test
- Lilliefors test
scipy 에서 제공하는 정규성 검정 명령어¶
- Kolmogorov-Smirnov test
- Shapiro–Wilk test
- Anderson–Darling test
- D'Agostino's K-squared test
이 중에서 Kolmogorov-Smirnov 검정은 정규 분포에 국한되지 않고 두 샘플이 같은 분포를 따르는지 확인할 수 있는 방법이다.¶
np.random.seed(0)
N1 = 50
N2 = 100
x1 = sp.stats.norm(0, 1).rvs(N1)
x2 = sp.stats.norm(0.5, 1.5).rvs(N2)
plt.figure(figsize=(12,6))
sns.distplot(x1)
sns.distplot(x2)
plt.show()
sp.stats.ks_2samp(x1, x2)