빅데이터 분석기사 실기 3유형

서준·2024년 6월 17일
0

독립성 검정

  • 변수가 두개 이상 범주로 분할되어 있고, 독립적인지 연관성이 있는지 검정
  • 귀무가설(H0) : 서로 독립
  • 대립가설(H1) : 연관성이 있다
  • p-value < 0.05 이면 대립가설 채택

검정방법 순서

  1. 패키지 추가 (from scipy.stats import chi2_contingency)
  2. 데이터 table 변환 (범주형 - pd.crosstab / 수치형 - np.array)
  3. chi2 검정 (chi2, p_val, dof(자유도), ex(기대치))

패키지

from scipy.stats import chi2_contingency
from statsmodels.formula.api import logit

독립성 검정

import pandas as pd

df = pd.read_csv("data/Titanic.csv")

#1번 문제
from scipy.stats import chi2_contingency

table = pd.crosstab(df.Gender, df.Survived)
chi2, p_val, dof, exp = chi2_contingency(table)

print(round(chi2, 3)) 	# 260.717
print(p_val) 			# 매우 작으므로 대립가설 채택

로지스틱 회귀

from statsmodels.formula.api import logit
result1 = logit('Survived ~ Gender+SibSp+Parch+Fare', data=df).fit().summary()
print(result1)

오즈비 구하기

import numpy as np
result2 = logit('Survived ~ Gender+SibSp+Parch+Fare', data=df).fit().params
print(np.exp(result2))

상관계수

df.corr()

Shapiro-Wilk (정규분포)

from scipy import stats
statistic, p_val = stats.shapiro(data)

출처 - datamanim.com

stats 주요 모듈

01 T-test

  • ttest_1samp (단일표본 t검정)
  • ttest_ind (독립표본 t검정)
  • ttest_rel (대응표본 t검정)

02 비모수 검정

  • manwhitneyu (맨-휘트니 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

예시

#1 정규성 검정

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

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

from scipy.stats import shapiro
print(shapiro(df))
  • 결과
    ShapiroResult(statistic=0.9981444478034973, pvalue=0.34849318861961365)
    -> 통계랑이 1에 가까우므로 정규분포에 가까움
    -> p-value가 0.05보다 크므로 귀무가설 기각X -> 정규 분포를 따름
    -> 통계량이 1에 가깝더라도, p-value가 0.05보다 작으면 정규성X

02 다음 데이터를 log변환 후 정규성을 확인하라

import pandas as pd
import numpy as np
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/normal3.csv')

log_df = np.log1p(df)

from scipy.stats import shapiro
print(shapiro(log_df))
  • 결과
    ShapiroResult(statistic=0.9976889491081238, pvalue=0.17540602385997772)
    -> 0.05보다 크므로 정규성 O
    -> log변환 시 너무 작은 값이거나, 0, 음수를 포함하는 값들이 있을때 사용

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

import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/normal6.csv')

from scipy.stats import shapiro
#shapiro(df)

from scipy.stats import anderson
anderson(df['data'].values)
  • 결과
    AndersonResult(statistic=0.8266993530405671, 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.')
    -> 5000개 이상일 경우 shapiro 말고 anderson 사용
    -> 5% : 0.786 < 통계량 : 0.827 < 2.5% : 0.917
    -> 따라서 유의수준 5% 이하이므로, 정규성 X

#2 단일 표본 t검정(one-sample)

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

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/height1.csv')

from scipy.stats import shapiro

shapiro(df)
# ShapiroResult(statistic=0.9872668981552124, pvalue=0.4558176100254059)
# 정규성 O -> 단일 표본 t 검정

from scipy.stats import ttest_1samp
ttest_1samp(df['height'], 165)
  • 결과
    TtestResult(statistic=3.2017884987150644, pvalue=0.0018367171548080209, df=99)
    -> p-value 0.05이하 이므로, 100명 키의 평균은 165가 아니다.

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

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/height2.csv')

from scipy.stats import shapiro

shapiro(df) 
# ShapiroResult(statistic=0.9672006368637085, pvalue=0.013552471995353699)
# 정규성 X -> 비모수 검정 (윌콕슨)

from scipy.stats import wilcoxon

wilcoxon(df)
  • 결과
    WilcoxonResult(statistic=array([0.]), pvalue=array([3.87726172e-18]))
    -> p-value가 0.05보다 작으므로, 대립가설 채택
    -> 100명 키의 평균은 165가 아니다.

#3 등분산 검정

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

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/scipy2.csv')

from scipy.stats import bartlett
from scipy.stats import fligner
from scipy.stats import levene

a = df[df['class'] == 'A'].score
b = df[df['class'] == 'B'].score

print(bartlett(a, b))
print(fligner(a, b, center = 'median'))
print(fligner(a, b, center = 'mean'))
print(levene(a, b, center = 'median'))
print(levene(a, b, center = 'mean'))
  • 결과
    BartlettResult(statistic=0.26035880448930865, pvalue=0.609873758447687)
    FlignerResult(statistic=0.7281251154135562, pvalue=0.39349158741002765)
    FlignerResult(statistic=0.8272211734319945, pvalue=0.36307728836821906)
    LeveneResult(statistic=0.3145466542912649, pvalue=0.5751662820554713)
    LeveneResult(statistic=0.5086970687685527, pvalue=0.4760514837800255)
    -> 0.05보다 크므로, 각 그룹은 등분산이다.

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

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/scipy3.csv')
from scipy.stats import bartlett
from scipy.stats import fligner
from scipy.stats import levene

a = df[df['class'] =='A'].score
b = df[df['class'] =='B'].score

print(bartlett(a,b))
print(fligner(a,b,center='median')) #default
print(fligner(a,b,center='mean')) 

print(levene(a,b, center='median')) #default
print(levene(a,b,center='mean'))
  • 결과
    BartlettResult(statistic=1.5116783794562305, pvalue=0.2188831590902503)
    FlignerResult(statistic=4.960366756026232, pvalue=0.025934706256615564)
    FlignerResult(statistic=4.94724457924667, pvalue=0.026132286002684912)
    LeveneResult(statistic=4.307122424591436, pvalue=0.03848734007752694)
    LeveneResult(statistic=4.342327020297874, pvalue=0.0377066528874248)
    -> fligner, levene 는 bartlett에 비해 robust하다
    -> 정규분포를 따르지 않는다면 bartlett은 신뢰하기 어렵다
    -> 따라서 등분산 X

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

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/scipy6.csv')

from scipy.stats import bartlett
from scipy.stats import fligner
from scipy.stats import levene

print(bartlett(df.A, df.B))
print(fligner(df.A, df.B))
print(levene(df.A, df.B))
  • 결과
    BartlettResult(statistic=2.3832178811043527, pvalue=0.12264468401745829)
    FlignerResult(statistic=5.124831619122788, pvalue=0.023585858890699054)
    LeveneResult(statistic=5.147914610463281, pvalue=0.023868975493455683)

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

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/scipy5.csv')

print(bartlett(df.A, df.B.dropna()))
print(fligner(df.A, df.B.dropna()))
print(levene(df.A, df.B.dropna()))
  • 결과
    BartlettResult(statistic=3.024072692680794, pvalue=0.08203720607748438)
    FlignerResult(statistic=7.710320541528441, pvalue=0.005490600130793619)
    LeveneResult(statistic=8.008595918808284, pvalue=0.004851565077063284)
    -> nan 값이 포함될 경우 없애고 등분산 검정을 시행해야 한다

#4 독립 표본 검정(Independent) - 정규성에 따라 다름

01 두 개 학급의 시험성적에 대한 데이터이다. 두 학급의 시험 평균(비모수검정의 경우 중위값)은 동일하다 말할 수 있는지 확인하라.

import pandas as pd 
df1 = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/ind1.csv')
df2 = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/ind2.csv')

from scipy.stats import shapiro

print(shapiro(df1)) # 정규성 O
print(shapiro(df2)) # 정규성 O

from scipy.stats import levene
print(levene(df1['data'], df2['data'])) # 등분산 O

from scipy.stats import ttest_ind
print(ttest_ind(df1, df2, equal_var = True))
  • 결과
    ShapiroResult(statistic=0.9860946536064148, pvalue=0.379673033952713)
    ShapiroResult(statistic=0.990182638168335, pvalue=0.6793646216392517)
    LeveneResult(statistic=2.5337683795339547, pvalue=0.11302904824469093)
    TtestResult(statistic=array([2.76719074]), pvalue=array([0.00619015]), df=array([198.]))
    -> 대립가설 채택
    -> 각 그룹 평균은 동일하지 않다

02 두 개 학급의 시험성적에 대한 데이터이다. 두 학급의 시험 평균(비모수검정의 경우 중위값)은 동일하다 말할 수 있는지 확인하라.

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/scipy5.csv')

from scipy.stats import shapiro
print(shapiro(df.A))          # 정규성 X
print(shapiro(df.B.dropna())) # 정규성 X

from scipy.stats import mannwhitneyu, ranksums
print(mannwhitneyu(df.A, df.B.dropna()))  # 귀무가설 채택
print(ranksums(df.A, df.B.dropna()))      # 귀무가설 채택
  • 결과
    ShapiroResult(statistic=0.93753981590271, pvalue=6.175894240456614e-10)
    ShapiroResult(statistic=0.9639433026313782, pvalue=0.00013568344002123922)
    MannwhitneyuResult(statistic=27036.0, pvalue=0.9807458376150018)
    RanksumsResult(statistic=0.02446942170858557, pvalue=0.9804781743503561)
    -> 귀무가설 채택
    -> 평균은 같다

03 두개 그룹에 대한 수치형 데이터이다. 두 그룹은 평균이 동일하다 말할 수 있는가

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/ind3.csv')

from scipy.stats import shapiro
a = df[df['group'] == 'a'].data
b = df[df['group'] == 'b'].data
print(shapiro(a)) # 정규성 O
print(shapiro(b)) # 정규성 O

from scipy.stats import levene
print(levene(a, b))   # 등분산 X

from scipy.stats import ttest_ind
print(ttest_ind(a, b, equal_var = False))
  • 결과
    ShapiroResult(statistic=0.9834123253822327, pvalue=0.1473984718322754)
    ShapiroResult(statistic=0.9831852316856384, pvalue=0.4701973497867584)
    LeveneResult(statistic=6.185601018015722, pvalue=0.013750484571911342)
    TtestResult(statistic=-2.1949470315829265, pvalue=0.029512802991767898, df=171.25282465005142)
    -> 귀무가설 기각
    -> 평균 동일 X

04 두개 그룹에 대한 수치형 데이터이다. 두 그룹은 평균이 동일하다 말할 수 있는가

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/ind6.csv')

from scipy.stats import shapiro
print(shapiro(df.a)) # 정규성 O
print(shapiro(df.b.dropna())) # 정규성 O

from scipy.stats import levene
print(levene(df.a, df.b.dropna()))  # 등분산 X

from scipy.stats import ttest_ind
print(ttest_ind(df.a, df.b.dropna(), equal_var = False))
  • 결과
    ShapiroResult(statistic=0.9865895509719849, pvalue=0.28390026092529297)
    ShapiroResult(statistic=0.9854326844215393, pvalue=0.5937624573707581)
    LeveneResult(statistic=3.9862856894158347, pvalue=0.04731495612868527)
    TtestResult(statistic=0.0015963310698567184, pvalue=0.9987289046092704, df=122.72255248639058)
    -> 귀무가설 기각X
    -> 평균값은 동일

#5 대응 표본 t 검정 (paired)

01 특정 질병 집단의 투약 전후의 혈류량 변화를 나타낸 데이터이다. 투약 전후의 변화가 있는지 검정하라

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/rel2.csv')

from scipy.stats import shapiro

print(shapiro(df.before)) # 정규성 O
print(shapiro(df.after))  # 정규성 O

from scipy.stats import levene
print(levene(df.before, df.after))  # 등분산 O

from scipy.stats import ttest_rel
print(ttest_rel(df.before, df.after))
  • 결과
    ShapiroResult(statistic=0.9907895922660828, pvalue=0.6065835952758789)
    ShapiroResult(statistic=0.9916961193084717, pvalue=0.6923638582229614)
    LeveneResult(statistic=0.06427968690211128, pvalue=0.8000741651677987)
    TtestResult(statistic=-2.5535473487670677, pvalue=0.011926744724546513, df=119)
    -> p-value 0.05이내
    -> 대립가설 채택
    -> 평균은 같지 않다

02 특정 질병 집단의 투약 전후의 혈류량 변화를 나타낸 데이터이다. 투약 전후의 변화가 있는지 검정하라

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/rel3.csv')

from scipy.stats import shapiro
print(shapiro(df.before)) # 정규성 O
print(shapiro(df.after))  # 정규성 O

from scipy.stats import levene
print(levene(df.before, df.after))  # 등분산 O

from scipy.stats import ttest_rel
print(ttest_rel(df.before, df.after))
  • 결과
    ShapiroResult(statistic=0.9920631051063538, pvalue=0.7270199656486511)
    ShapiroResult(statistic=0.992019534111023, pvalue=0.7229290008544922)
    LeveneResult(statistic=1.3463330638203617, pvalue=0.24708279045237214)
    TtestResult(statistic=0.188900575991026, pvalue=0.8504925317234707, df=119)
    -> 귀무가설 채택
    -> 평균은 같다

03 특정 집단의 학습 전후 시험 성적 변화를 나타낸 데이터이다. 시험 전과 후에 차이가 있는지 검정하라.

import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/rel1.csv')

from scipy.stats import shapiro

print(shapiro(df.before))   # 정규성 X
print(shapiro(df.after))    # 정규성 X

from scipy.stats import levene
print(levene(df.before, df.after))  # 등분산 O

from scipy.stats import wilcoxon
print(wilcoxon(df.before, df.after))
  • 결과
    ShapiroResult(statistic=0.9173730611801147, pvalue=0.0018974003614857793)
    ShapiroResult(statistic=0.9448966979980469, pvalue=0.021140215918421745)
    LeveneResult(statistic=0.14329522146179022, pvalue=0.7058456563194881)
    WilcoxonResult(statistic=437.0, pvalue=0.12098409484052809)
    -> p-value 0.05보다 높으므로, 귀무가설 채택
    -> 전 후 평균 일치

04 한 기계 부품의 rpm 수치를 두 가지 다른 상황에서 측정했다. (총 70세트) b상황이 a상황보다 rpm값이 높다고 말할 수 있는지 검정하라.

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/rel4.csv')

a = df[df['group'] == 'a'].rpm
b = df[df['group'] == 'b'].rpm

from scipy.stats import shapiro

print(shapiro(a))   # 정규성 O
print(shapiro(b))   # 정규성 O

from scipy.stats import levene
print(levene(a, b)) # 등분산 O

from scipy.stats import ttest_rel
print(ttest_rel(a, b, alternative = 'greater'))
  • 결과
    ShapiroResult(statistic=0.9907217025756836, pvalue=0.8884284496307373)
    ShapiroResult(statistic=0.984674870967865, pvalue=0.5505106449127197)
    LeveneResult(statistic=0.06716114122680159, pvalue=0.7959020864923277)
    TtestResult(statistic=-1.9018108294460812, pvalue=0.9693143365355352, df=69)
    -> a>b 가 대립가설, a<=b 가 귀무가설
    -> 0.05보다 크므로 귀무가설 채택

#6 카이제곱 검정 (교차분석)

01 144회 주사위를 던졌을 때, 각 눈금별로 나온 횟수를 나타낸다. 이 데이터는 주사위의 분포에서 나올 가능성이 있는지 검정하라

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/dice.csv')

from scipy.stats import chisquare

df['expected'] = (df['counts'].sum()/6).astype('int')
print(chisquare(df.counts, df.expected))
  • 결과
    Power_divergenceResult(statistic=2.333333333333333, pvalue=0.8013589222076911)
    -> 귀무가설 채택
    -> 각 주사위 눈금 발생 비율은 동일함

02 다음 데이터는 국민 기초체력을 조사한 데이터이다. 성별과 등급이 독립적인지 검정하라.

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/body/body.csv')

cdf = pd.crosstab(df['측정회원성별'], df['등급'])

from scipy.stats import chi2_contingency
chi2, p, dof, exp = chi2_contingency(cdf)
print(p)
  • 결과
    7.481892813401677e-26
    -> 귀무가설 기각
    -> 두 항목은 연관이 있다

03 성별에 따른 동아리 활동 참석 비율을 나타낸 데이터이다. 성별과 참석간에 관련이 있는지 검정하라.

import pandas as pd 
df = pd.read_csv('https://raw.githubusercontent.com/Datamanim/datarepo/main/scipy/fe2.csv',index_col=0)

cdf = df.iloc[:-1, :-1]

from scipy.stats import chi2_contingency
chi2, p, dof, exp = chi2_contingency(cdf)
print(p)  # 귀무가설 채택 -> 하지만 5보다 작은 셀이 20%가 넘어가므로 피셔의 정확검정을 사용해야함

from scipy.stats import fisher_exact
print(fisher_exact(cdf))
  • 결과
    0.07023259819117404
    SignificanceResult(statistic=18.0, pvalue=0.03571428571428571)
    -> 대립가설 채택
    -> 관련이 있다
profile
어린이입니다.

0개의 댓글