분산 분석은 연속형 반응 변수와 범주형 설명 변수를 갖는 데이터를 분석하는 방법 중 하나입니다.
의사결정 흐름도는 다음과 같습니다.
따라서 일원 분산 분석은 연속형 target이 1개고 범주형 feature 1개를 갖는 데이터에서 그룹이 3개 이상인 경우 사용합니다.
동일한 조건에서 그룹이 2개인 경우에는 t-test를 사용합니다.
t-test에 대한 포스트는 여기를 참고하시면 됩니다.
2021.11.17 - [공부/통계학] - T-test (T 검정)
일원분산분석을 시행하는 경우, feature로 설명되지 않는 target 변수에 대한 정보로 error (오차)에 대한 가정이 존재합니다.
오차에 대한 가정 error ~ N(0,σ^2) (각 링크에 검정 방식을 소개합니다)
또한, 각 그룹의 모평균이 동일하다는 귀무가설을 기각하는 경우, 다중비교 (사후 검정)의 절차가 필요합니다.
분산 분석은 target의 변동(TSS : Total Sum of Squares)이 각 그룹 간 차이에 대한 target 변동(SST : Sum of Squares for Treatment) + 그룹 간 차이 외적인 변동(SSE : Sum of Squares for Error)으로 분해한 후, SST가 SSE보다 크면 클수록 그룹의 평균 차이가 통계적으로 유의하다고 할 수 있습니다.
One-way ANOVA 분산 분석표
요인 (factor) |
자유도 (degree of freedom) |
제곱합 (sum of square) |
평균제곱합 (Mean Square) |
F 값 |
Treatment | k-1 | SST | MST = SST/(k-1) | F = MST/MSE |
Error | n-k | SSE | MSE = SSE/(n-k) | |
Total | n-1 | TSS |
위의 식에서 k는 그룹의 개수를 의미하고 n은 전체 데이터 개수를 의미합니다.
먼저 Between Variance로 표현되는 MST는 전체평균 - 그룹평균의 제곱합을 자유도로 나눈 값입니다.
Within Variance로 표현되는 MSE는 그룹평균 - 샘플데이터의 제곱합을 자유도로 나눈 값입니다.
검정통계량은 F 값을 이용하는데, MST가 MSE보다 클수록, 그룹별 target 변수의 평균 차이가 유의하기 때문에 F 값이 커지게 되는 구조입니다. F 값이 커지게 된다면, 귀무가설을 기각할 정도의 p값이 나오게 될 것입니다. 따라서 유의 수준 (일반적으로 5%)에 대해 귀무가설을 기각할 수 있다는 결과를 가져올 수 있게 됩니다.
그렇다면 바로 코드를 시행해보도록 하겠습니다.
먼저 데이터는 iris 데이터입니다.
https://www.kaggle.com/uciml/iris
csv 다운로드
import pandas as pd
# csv파일이 있는 경로입니다.
path = '../dataset/'
data = pd.read_csv(path+'iris.csv', names=['sepal_length', 'sepal_width', 'petal_length', 'petal_width','target'])
data
>>>
sepal_length sepal_width petal_length petal_width target
0 5.1 3.5 1.4 0.2 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosa
2 4.7 3.2 1.3 0.2 Iris-setosa
3 4.6 3.1 1.5 0.2 Iris-setosa
4 5.0 3.6 1.4 0.2 Iris-setosa
.. ... ... ... ... ...
145 6.7 3.0 5.2 2.3 Iris-virginica
146 6.3 2.5 5.0 1.9 Iris-virginica
147 6.5 3.0 5.2 2.0 Iris-virginica
148 6.2 3.4 5.4 2.3 Iris-virginica
149 5.9 3.0 5.1 1.8 Iris-virginica
[150 rows x 5 columns]
그다음은 데이터의 정보와 기초통계입니다.
data.info()
data.describe()
>>>
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150 entries, 0 to 149
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 sepal_length 150 non-null float64
1 sepal_width 150 non-null float64
2 petal_length 150 non-null float64
3 petal_width 150 non-null float64
4 target 150 non-null object
dtypes: float64(4), object(1)
memory usage: 6.0+ KB
sepal_length sepal_width petal_length petal_width
count 150.000000 150.000000 150.000000 150.000000
mean 5.843333 3.054000 3.758667 1.198667
std 0.828066 0.433594 1.764420 0.763161
min 4.300000 2.000000 1.000000 0.100000
25% 5.100000 2.800000 1.600000 0.300000
50% 5.800000 3.000000 4.350000 1.300000
75% 6.400000 3.300000 5.100000 1.800000
max 7.900000 4.400000 6.900000 2.500000
일원분산분석을 적용하는 데이터는 꽃받침의 폭으로 각 그룹별로 꽃받침의 폭 평균이 유의한 차이를 보이는지 검정해보고자 합니다.
먼저 target 데이터에 대해 ANOVA 분산분석을 시행하기 앞서 ordinal encoding을 적용합니다.
(물론 굳이 할 필요는 없지만, 분석의 편의를 위해 시행함)
# target 변수에 대해 0,1,2로 라벨링 과정을 시행
from sklearn.preprocessing import OrdinalEncoder
encoder = OrdinalEncoder()
data = pd.DataFrame(encoder.fit_transform(data))
data.columns = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width','target']
이번엔 시각화를 통해 먼저 데이터를 확인해봅니다.
# 시각화 시행
sns.barplot(x= data['target'], y=data['sepal_width'])
plt.title('꽃 종류별 꽃 받침의 폭')
plt.show()
시각적으로도 평균이 다르다는 것을 알 수 있는데요, 통계적으로도 유의하게 다른지 검정해보겠습니다.
먼저 정규성검정을 합니다. (유의수준 5%로 설정한 shapiro 검정)
# 정규성 검정
# 귀무가설 : 정규분포를 따른다.
from scipy.stats import shapiro
for i in range(3):
p_value = shapiro(data.sepal_width[data.target==i])[1]
if p_value < 0.05:
print('정규분포를 따른다는 귀무가설을 유의수준 5%에서 기각할 수 있습니다. 따라서 정규성을 충족하지 못합니다.')
else:
print('정규분포를 따른다는 귀무가설을 유의수준 5%에서 기각할 수 없습니다. 따라서 정규성을 충족합니다.')
>>>
정규분포를 따른다는 귀무가설을 유의수준 5%에서 기각할 수 없습니다. 따라서 정규성을 충족합니다.
정규분포를 따른다는 귀무가설을 유의수준 5%에서 기각할 수 없습니다. 따라서 정규성을 충족합니다.
정규분포를 따른다는 귀무가설을 유의수준 5%에서 기각할 수 없습니다. 따라서 정규성을 충족합니다.
등분산성 검정
#등분산성 확인 - 레빈 검증 (귀무가설 : 등분산의 특징이 있다.)
from scipy.stats import levene
print(levene(data.sepal_width[data.target==0],
data.sepal_width[data.target==1],
data.sepal_width[data.target==2]))
#등분산성 확인 - 바틀렛 검증 (귀무가설 : 등분산의 특징이 있다.)
from scipy.stats import bartlett
print(bartlett(data.sepal_width[data.target==0],
data.sepal_width[data.target==1],
data.sepal_width[data.target==2]))
>>>
LeveneResult(statistic=0.6280767321673624, pvalue=0.5350428817228079)
BartlettResult(statistic=2.1232079705400917, pvalue=0.3459005457507166)
이제 등분산성과 정규성을 충족하였기 때문에 일원분산분석을 시행할 수 있습니다.
이를 시행하기 위해서는 statsmodel의 anova 매서드와 ols 매서드를 호출해줍니다.
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm, anova_single
model = ols('sepal_width ~ C(target)', data).fit()
anova_table = anova_lm(model)
if anova_table['PR(>F)'][0] < 0.05:
print(f'ANOVA 분석 결과, 5%의 유의수준으로 모든 수준에서 모평균이 동일하다는 귀무가설을 기각할 수 있습니다. 따라서 위 집단의 모평균이 다르다고 말할 수 있습니다.')
else:
print(f'ANOVA 분석 결과, 5%의 유의수준으로 모든 수준에서 모평균이 동일하다는 귀무가설을 기각할 수 없습니다.')
print(anova_table)
>>>
ANOVA 분석 결과, 5%의 유의수준으로 모든 수준에서 모평균이 동일하다는 귀무가설을 기각할 수 있습니다. 따라서 위 집단의 모평균이 다르다고 말할 수 있습니다.
df sum_sq mean_sq F PR(>F)
C(target) 2.0 1084.84 542.420000 47.733947 1.061054e-16
Residual 147.0 1670.42 11.363401 NaN NaN
이번에는 OLS 회귀 요약을 보도록합니다.
model.summary()
>>>
OLS Regression Results
==============================================================================
Dep. Variable: sepal_width R-squared: 0.394
Model: OLS Adj. R-squared: 0.385
Method: Least Squares F-statistic: 47.73
Date: Wed, 16 Feb 2022 Prob (F-statistic): 1.06e-16
Time: 16:37:13 Log-Likelihood: -393.61
No. Observations: 150 AIC: 793.2
Df Residuals: 147 BIC: 802.2
Df Model: 2
Covariance Type: nonrobust
====================================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------------
Intercept 13.1600 0.477 27.605 0.000 12.218 14.102
C(target)[T.1.0] -6.4400 0.674 -9.552 0.000 -7.772 -5.108
C(target)[T.2.0] -4.4200 0.674 -6.556 0.000 -5.752 -3.088
==============================================================================
Omnibus: 1.311 Durbin-Watson: 1.866
Prob(Omnibus): 0.519 Jarque-Bera (JB): 0.916
Skew: 0.043 Prob(JB): 0.633
Kurtosis: 3.373 Cond. No. 3.73
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
여기서 F값, prob를 보면 47.73, 1.06e-16인 것을 알 수 있습니다.
이 값이 바로 one-way anova로 도출한 F값과 p값 입니다.
결론입니다.
각 꽃 종류별 꽃받침의 폭의 평균이 동일하다는 귀무가설을 기각할 수 있기에 각 집단의 평균이 통계적으로 유의하게 다르다는 것도 증명할 수 있습니다.
'공부 > 통계학' 카테고리의 다른 글
선형회귀 기초 (0) | 2022.03.24 |
---|---|
로지스틱 회귀분석 (Logistic Regression) python (0) | 2022.02.21 |
기초 통계 (중심도 이해) python (0) | 2022.02.04 |
PACF (Partial Auto Correlation Function, 편자기상관함수) python (0) | 2022.01.20 |
ACF (auto-correlative function, 자기상관함수) python (0) | 2022.01.20 |
댓글