빅데이터분석기사

[빅분기 실기] 데이터마님 - Scipy-stats 패키지 (1~10번)

프로그린 2024. 6. 18. 13:26

Scipy-stats 주요 모듈

scipy.stats
│
├── 01 T-test
│   │
│   ├── ttest_1samp         (단일표본 t검정)
│   ├── ttest_ind           (독립표본 t검정)
│   └── ttest_rel           (대응표본 t검정) 
│ 
├── 02 비모수 검정
│   │
│   ├── mannwhitneyu        (맨-휘트니 U 검정 - 중위수 , 윌콕슨 순위합 검정과 동일하다 볼 수 있음)
│   ├── ranksums            (윌콕슨 순위합 검정 - 중위수)
│   └── wilcoxon            (윌콕슨 부호 순위합 검정)
│ 
├── 03 정규정 검정
│   │
│   ├── anderson            (Anderson-Darling , 데이터수가 상대적으로 많을 때)
│   ├── kstest              (Kolmogorov-Smirnov , 데이터수가 상대적으로 많을 때)
│   ├── mstats.normaltest
│   └── shapiro             (shapiro, 노말분포 가장 엄격하게 검정, 데이터수가 상대적으로 적을때)
│   
├── 04 등분산 검정
│   │
│   ├── bartlett
│   ├── fligner
│   └── levene
│
├── 05 카이제곱검정
│   │
│   ├── chi2_contingency     (카이제곱독립검정, 독립성 검정)
│   ├── chisquare            (카이제곱검정 , 적합도 검정)
│   └── fisher_exact         (피셔 정확 검정 - 빈도수가 5개 이하 셀의 수가 전체 셀의 20% 이상일 경우 사용 )
│
└── 06 ANOVA (일원분산분석)
    │
    └── f_oneway (분산 분석은  statmodels 모듈 사용 추천 )

 

정규성 검정

01. 다음 데이터의 정규성을 검증하라.

import pandas as pd 
import matplotlib.pyplot as plt
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/normal1.csv')
plt.hist(df)
plt.show()

print('데이터 수: ', len(df))

from scipy.stats import shapiro
statistic, p_value = shapiro(df)
print(shapiro(df))
if p_value < 0.05:
    print('유의수준 5%에서 귀무가설 기각 → 정규성을 만족하지 않음')
else:
    print('유의수준 5%에서 귀무가설 채택 → 정규성 만족')

[output]


데이터 수: 1000
ShapiroResult(statistic=0.9981444478034973, pvalue=0.34849318861961365) 
유의수준 5%에서 귀무가설 채택 → 정규성 만족

 

02. 다음 데이터의 정규성을 검증하라.

df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/normal3.csv')
plt.hist(df)
plt.show()

print('데이터 수: ', len(df))

from scipy.stats import shapiro
statistic, p_value = shapiro(df)
print(shapiro(df))
if p_value < 0.05:
    print('유의수준 5%에서 귀무가설 기각 → 정규성을 만족하지 않음')
else:
    print('유의수준 5%에서 귀무가설 채택 → 정규성 만족')
[output]

데이터 수: 1000
ShapiroResult(statistic=0.9578885436058044, pvalue=2.309641794969743e-16)
유의수준 5%에서 귀무가설 기각 → 정규성을 만족하지 않음

 

3. 위의 데이터를 로그변환 한 후에 정규성을 검증하라.

import numpy as np
log_df = np.log1p(df)
plt.hist(log_df)
plt.show()

statistic, p_value = shapiro(log_df)
print(shapiro(df))
if p_value < 0.05:
    print('유의수준 5%에서 귀무가설 기각 → 정규성 만족')
else:
    print('유의수준 5%에서 귀무가설 채택 → 정규성을 만족하지 않음.')
[output]
ShapiroResult(statistic=0.9578885436058044, pvalue=2.309641794969743e-16)
유의수준 5%에서 귀무가설 채택 → 정규성을 만족하지 않음.

 

04. 다음 데이터의 정규성을 검증하라.

df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/normal6.csv')
plt.hist(df)
plt.show()

print('데이터 수: ', len(df))
# 데이터의 수가 5000개 이상이므로 shapiro 검정은 부적절

from scipy.stats import anderson
print(anderson(df['data'].values))
statistic, critical_values, significance_level = anderson(df['data'].values)
if statistic > critical_values[2]:
    print('유의수준 5%에서 귀무가설 기각 → 정규성을 만족하지 않음')
else:
    print('유의수준 5%에서 귀무가설 채택 → 정규성 만족')
[output]

데이터 수: 6000

AndersonResult(statistic=0.8266993530414766, critical_values=array([0.576, 0.656, 0.786, 0.917, 1.091]), significance_level=array([15. , 10. ,  5. ,  2.5,  1. ]), fit_result=  params: FitParams(loc=299.95980319533163, scale=5.031806887885131)
 success: True
 message: '`anderson` successfully fit the distribution to the data.')

유의수준 5%에서 귀무가설 기각 → 정규성을 만족하지 않음


단일 표본 t검정(One-Sample t-test)

05. 100명의 키 정보가 들어 있는 데이터가 있다.데이터가 정규성을 만족하는지 확인하라.
그리고 평균키는 165라 판단할수 있는지 귀무가설과 대립가설을 설정한 후 유의수준 5%로 검정하라.

# 데이터 로드
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/height1.csv')
print('데이터 수: ', len(df))

# 정규성 검정
from scipy.stats import shapiro
statistic, p_value = shapiro(df)
print(shapiro(df))
if p_value < 0.05:
    print('유의수준 5%에서 귀무가설 기각 → 정규성을 만족하지 않음')
else:
    print('유의수준 5%에서 귀무가설 채택 → 정규성 만족')

# 가설 검정 → 정규성을 만족하므로 단일 표본 t-test로 검정
# H0 : 평균키는 165이다. vs H1 : 평균키는 165가 아니다.
from scipy.stats import ttest_1samp
statistic, p_value = ttest_1samp(df['height'].values, 165)
print(ttest_1samp(df['height'].values, 165))
if p_value < 0.05:
    print('유의수준 5%에서 귀무가설 기각 → 평균키는 165라고 할 수 없음')
else:
    print('유의수준 5%에서 귀무가설 채택 → 평균키는 165라고 할 수 있음')
[output]
데이터 수: 100
ShapiroResult(statistic=0.9872668981552124, pvalue=0.4558176100254059)
유의수준 5%에서 귀무가설 채택 → 정규성 만족
TtestResult(statistic=3.2017884987150644, pvalue=0.0018367171548080209, df=99)
유의수준 5%에서 귀무가설 기각 → 평균키는 165라고 할 수 없음

 

06. 100명의 키 정보가 들어 있는 데이터가 있다.데이터가 정규성을 만족하는지 확인하라.
그리고 평균키는 165라 판단할수 있는지 귀무가설과 대립가설을 설정한 후 유의수준 5%로 검정하라.

# 데이터 로드
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/height2.csv')

# 정규성 검정
print('데이터 수: ', len(df))

from scipy.stats import shapiro
statistic, p_value = shapiro(df)
print(shapiro(df))
if p_value < 0.05:
    print('유의수준 5%에서 귀무가설 기각 → 정규성을 만족하지 않음')
else:
    print('유의수준 5%에서 귀무가설 채택 → 정규성 만족')
    
# 가설 검정 → 정규성을 만족하지 않으므로 비모수 검정 중 윌콕슨 순위 부호 검정
# H0 : 평균키는 165이다. vs H1 : 평균키는 165가 아니다.
from scipy.stats import wilcoxon
statistic, p_value = wilcoxon(df['height']-165)
print(wilcoxon(df['height']-165))
if p_value < 0.05:
    print('유의수준 5%에서 귀무가설 기각 → 평균키는 165라고 할 수 없음')
else:
    print('유의수준 5%에서 귀무가설 채택 → 평균키는 165라고 할 수 있음')
[output]
데이터 수: 100
ShapiroResult(statistic=0.9672006368637085, pvalue=0.013552471995353699)
유의수준 5%에서 귀무가설 기각 → 정규성을 만족하지 않음
WilcoxonResult(statistic=1952.0, pvalue=0.04880534424649582)
유의수준 5%에서 귀무가설 기각 → 평균키는 165라고 할 수 없음

 

등분산 검정

7. 두개 학급의 시험성적에 대한 데이터이다. 그룹간 등분산 검정을 시행하라.

# 데이터 로드
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/scipy2.csv')
display(df.head())

score_a = df[df['class'] == 'A']['score']
score_b = df[df['class'] == 'B']['score']

# 등분산 검정
from scipy.stats import bartlett
from scipy.stats import fligner
from scipy.stats import levene

# bartlett 검정
s1, p1 = bartlett(score_a, score_b)
# fligner 검정(default는 median 기준)
s2, p2 = fligner(score_a, score_b)
# fligner 검정(mean 기준)
s3, p3 = fligner(score_a, score_b, center = 'mean')
# levene 검정(default는 median 기준)
s4, p4 = levene(score_a, score_b)
# levene 검정(mean 기준)
s5, p5 = levene(score_a, score_b, center = 'mean')

result = pd.DataFrame({'bartlett': [s1, p1], 'fligner_median': [s2, p2], 'fligner_mean': [s3, p3], 'levene_median': [s4, p4], 'levene_mean': [s5, p5]})
display(result.T.rename({0:'statistic', 1:'p_value'}, axis = 1))
for col in result.columns:
    if result[col][1] < 0.05:
        print(f'{col}: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음')
    else:
        print(f'{col}: 유의수준 5%에서 귀무가설 채택 → 두 그룹의 분산이 같다고 할 수 있음')
[output]
bartlett: 유의수준 5%에서 귀무가설 채택 → 두 그룹의 분산이 같다고 할 수 있음
fligner_median: 유의수준 5%에서 귀무가설 채택 → 두 그룹의 분산이 같다고 할 수 있음
fligner_mean: 유의수준 5%에서 귀무가설 채택 → 두 그룹의 분산이 같다고 할 수 있음
levene_median: 유의수준 5%에서 귀무가설 채택 → 두 그룹의 분산이 같다고 할 수 있음
levene_mean: 유의수준 5%에서 귀무가설 채택 → 두 그룹의 분산이 같다고 할 수 있음

 

8. 두개 학급의 시험성적에 대한 데이터이다. 그룹간 등분산 검정을 시행하라.

# 데이터 로드
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/scipy3.csv')
display(df.head())

score_a = df[df['class'] == 'A']['score']
score_b = df[df['class'] == 'B']['score']

# 등분산 검정
from scipy.stats import bartlett
from scipy.stats import fligner
from scipy.stats import levene

# bartlett 검정
s1, p1 = bartlett(score_a, score_b)
# fligner 검정(default는 median 기준)
s2, p2 = fligner(score_a, score_b)
# fligner 검정(mean 기준)
s3, p3 = fligner(score_a, score_b, center = 'mean')
# levene 검정(default는 median 기준)
s4, p4 = levene(score_a, score_b)
# levene 검정(mean 기준)
s5, p5 = levene(score_a, score_b, center = 'mean')

result = pd.DataFrame({'bartlett': [s1, p1], 'fligner_median': [s2, p2], 'fligner_mean': [s3, p3], 'levene_median': [s4, p4], 'levene_mean': [s5, p5]})
display(result.T.rename({0:'statistic', 1:'p_value'}, axis = 1))
for col in result.columns:
    if result[col][1] < 0.05:
        print(f'{col}: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음')
    else:
        print(f'{col}: 유의수준 5%에서 귀무가설 채택 → 두 그룹의 분산이 같다고 할 수 있음')
[output]

bartlett: 유의수준 5%에서 귀무가설 채택 → 두 그룹의 분산이 같다고 할 수 있음
fligner_median: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음
fligner_mean: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음
levene_median: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음
levene_mean: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음

 

9. 두개 학급의 시험성적에 대한 데이터이다. 그룹간 등분산 검정을 시행하라.

# 데이터 로드
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/scipy6.csv')
display(df.head())

# 등분산 검정
from scipy.stats import bartlett
from scipy.stats import fligner
from scipy.stats import levene

# bartlett 검정
s1, p1 = bartlett(df.A, df.B)
# fligner 검정(default는 median 기준)
s2, p2 = fligner(df.A, df.B)
# fligner 검정(mean 기준)
s3, p3 = fligner(df.A, df.B, center = 'mean')
# levene 검정(default는 median 기준)
s4, p4 = levene(df.A, df.B)
# levene 검정(mean 기준)
s5, p5 = levene(df.A, df.B, center = 'mean')

result = pd.DataFrame({'bartlett': [s1, p1], 'fligner_median': [s2, p2], 'fligner_mean': [s3, p3], 'levene_median': [s4, p4], 'levene_mean': [s5, p5]})
display(result.T.rename({0:'statistic', 1:'p_value'}, axis = 1))
for col in result.columns:
    if result[col][1] < 0.05:
        print(f'{col}: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음')
    else:
        print(f'{col}: 유의수준 5%에서 귀무가설 채택 → 두 그룹의 분산이 같다고 할 수 있음')
[output]

bartlett: 유의수준 5%에서 귀무가설 채택 → 두 그룹의 분산이 같다고 할 수 있음
fligner_median: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음
fligner_mean: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음
levene_median: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음
levene_mean: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음

 

10. 두개 학급의 시험성적에 대한 데이터이다. 그룹간 등분산 검정을 시행하라.

# 데이터 로드
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/scipy5.csv')
display(df.head())

# 등분산 검정
from scipy.stats import bartlett
from scipy.stats import fligner
from scipy.stats import levene

# bartlett, fligner 두 검정은 nan값을 지우고 사용해야 함.
# LeveneResult의 경우 nan값이 포함된다면 연산이 제대로 수행되지 않음.

# bartlett 검정
s1, p1 = bartlett(df.A, df.B.dropna())
# fligner 검정(default는 median 기준)
s2, p2 = fligner(df.A, df.B.dropna())
# fligner 검정(mean 기준)
s3, p3 = fligner(df.A, df.B.dropna(), center = 'mean')
# levene 검정(default는 median 기준)
s4, p4 = levene(df.A, df.B.dropna())
# levene 검정(mean 기준)
s5, p5 = levene(df.A, df.B.dropna(), center = 'mean')

result = pd.DataFrame({'bartlett': [s1, p1], 'fligner_median': [s2, p2], 'fligner_mean': [s3, p3], 'levene_median': [s4, p4], 'levene_mean': [s5, p5]})
display(result.T.rename({0:'statistic', 1:'p_value'}, axis = 1))
for col in result.columns:
    if result[col][1] < 0.05:
        print(f'{col}: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음')
    else:
        print(f'{col}: 유의수준 5%에서 귀무가설 채택 → 두 그룹의 분산이 같다고 할 수 있음')
[output]

bartlett: 유의수준 5%에서 귀무가설 채택 → 두 그룹의 분산이 같다고 할 수 있음
fligner_median: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음
fligner_mean: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음
levene_median: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음
levene_mean: 유의수준 5%에서 귀무가설 기각 → 두 그룹의 분산이 같다고 할 수 없음

 


출처 : https://www.datamanim.com/dataset/97_scipy/scipy.html