Statsmodels 튜토리얼#

Hits

import statsmodels

하위모듈확인

help로 확인한다

help(statsmodels)
Help on package statsmodels:

NAME
    statsmodels

PACKAGE CONTENTS
    _version
    api
    base (package)
    compat (package)
    conftest
    datasets (package)
    discrete (package)
    distributions (package)
    duration (package)
    emplike (package)
    formula (package)
    gam (package)
    genmod (package)
    graphics (package)
    imputation (package)
    interface (package)
    iolib (package)
    miscmodels (package)
    multivariate (package)
    nonparametric (package)
    othermod (package)
    regression (package)
    robust (package)
    sandbox (package)
    src (package)
    stats (package)
    tests (package)
    tools (package)
    tsa (package)

FUNCTIONS
    test(extra_args=None, exit=False)
        Run the test suite
        
        Parameters
        ----------
        extra_args : list[str]
            List of argument to pass to pytest when running the test suite. The
            default is ['--tb=short', '--disable-pytest-warnings'].
        exit : bool
            Flag indicating whether the test runner should exist when finished.
        
        Returns
        -------
        int
            The status code from the test run if exit is False.

DATA
    debug_warnings = False

VERSION
    0.13.2

FILE
    /Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/statsmodels/__init__.py

자주쓰는 모듈 구성#

statsmodels
│
├── 01 사후분석
│   │
│   └──stats
│       └── multicomp
│           ├── MultiComparison
│           │   └── allpairtest
│           └── pairwise_tukeyhsd
│
├── 02 시계열분석
│   │
│   ├── graphics.tsaplots
│   │   ├── plot_acf
│   │   └── plot_pacf
│   └── tsa
│       ├── arima_model
│       │   └── ARIMA
│       └── statesplace.sarimax
│           └── SARIMAX
│
├── 03 ANOVA (scipy모듈과 함께써야 모두 커버가능, 이분산 anova의 경우 pingouin모듈의 welch_anova를 사용)
│   │
│   ├── 다원분산분석 or 이원분산분석
│   └── 일원분산분석
│       └── stats.anova
│           └── anova_lm
│
└── 04 회귀분석
    │
    └── formula.api
        └── ols

세 집단 이상 검정 (independent)#

정규성(scipy.stats.shapiro), 등분산(scipy.stats.levene) 검정의 결과에 따라 시행하는 검정이 다르다
정규성 만족, 등분산 만족 : one-way anova
정규성 만족, 등분산 불만족 : welch’s anova
정규성 불만족 : kruskal-wallis H test

Question

x1,x2,x3의 변수들의 평균의 차이가 존재하는지 검정하라.
차이가 존재한다면 사후 분석까지 진행하라

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

data = df.x1
data2 = df.x2
data3 = df.x3

fig,ax = plt.subplots(1,2,figsize=(12,4))
ax[0].hist(data,alpha=0.3,bins=30,label='x1')
ax[0].hist(data2,alpha=0.3,bins=30,label='x2')
ax[0].hist(data3,alpha=0.3,bins=30,label='x3')
ax[0].legend()
labels = ['x1', 'x2', 'x3']
lst =[data,data2,data3]
ax[1].boxplot(lst, labels=labels) 
plt.show()
../../_images/6dadbcbd52ff1091352ad7f6c7b129777746ea0f8af9a09a09a654be9beda931.png
Hide code cell content
from scipy.stats import shapiro

# 정규성 검정 -> 모두 정규성을 가짐
print(shapiro(data))
print(shapiro(data2))
print(shapiro(data3))

from scipy.stats import levene

# 등분산 만족한다
print(levene(data,data2,data3))
print()

# anova 방법 1 
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm
dfm =df.melt()
dfm.head()
model = ols('value ~ C(variable)', dfm).fit()
print(anova_lm(model))
print()

# anova 방법 2 (scipy.stats.f_oneway)
from scipy.stats import f_oneway 
print(f_oneway(data, data2, data3))

# p-value 는 4.9e-86이므로 3그룹중 어느 두 그룹은 평균이 동일하다고 볼수 없다
ShapiroResult(statistic=0.9979788064956665, pvalue=0.27388232946395874)
ShapiroResult(statistic=0.9979414939880371, pvalue=0.25899720191955566)
ShapiroResult(statistic=0.9987626671791077, pvalue=0.7304413914680481)
LeveneResult(statistic=2.71270174202054, pvalue=0.06652021922816238)

                 df        sum_sq       mean_sq           F        PR(>F)
C(variable)     2.0  3.774347e+06  1.887173e+06  209.884999  4.919153e-86
Residual     2997.0  2.694742e+07  8.991464e+03         NaN           NaN

F_onewayResult(statistic=209.88499932318638, pvalue=4.919152988455592e-86)
Hide code cell content
#사후검정 방법 1 투키의 HSD
from statsmodels.stats.multicomp import pairwise_tukeyhsd

# 유의수준 5%기준으로 도표상의 reject을 보면 group간에 모든 귀무가설(두 그룹의 평균은 같다)을 기각 하는 것을 볼수 있다
posthoc = pairwise_tukeyhsd(dfm.value, dfm.variable, alpha=0.05)
print(posthoc)

# 시각화 y축은 각 label이다. 겹치는 구간이 없으므로 차이가 존재함을 알수 있음
fig = posthoc.plot_simultaneous()
plt.show()


# 사후 검정 방법 2 봉페로니 교정
from statsmodels.sandbox.stats.multicomp import MultiComparison
import scipy.stats

comp = MultiComparison(dfm.value, dfm.variable)
result = comp.allpairtest(scipy.stats.ttest_ind, method='bonf')
print(result[0])
 Multiple Comparison of Means - Tukey HSD, FWER=0.05 
=====================================================
group1 group2 meandiff p-adj  lower    upper   reject
-----------------------------------------------------
    x1     x2  86.8388  -0.0  76.8951  96.7825   True
    x1     x3  45.8253  -0.0  35.8816  55.7691   True
    x2     x3 -41.0135  -0.0 -50.9572 -31.0697   True
-----------------------------------------------------
../../_images/f7b9d260e4b1834626b41eb88c836451cb9b11002e6bf43c48a4838464e135f2.png
Test Multiple Comparison ttest_ind 
FWER=0.05 method=bonf
alphacSidak=0.02, alphacBonf=0.017
============================================
group1 group2   stat   pval pval_corr reject
--------------------------------------------
    x1     x2 -20.2943  0.0       0.0   True
    x1     x3 -10.6639  0.0       0.0   True
    x2     x3    9.897  0.0       0.0   True
--------------------------------------------

Question

x1,x2,x3의 변수들의 평균의 차이가 존재하는지 검정하라

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

data = df.x1
data2 = df.x2
data3 = df.x3

fig,ax = plt.subplots(1,2,figsize=(12,4))
ax[0].hist(data,alpha=0.3,bins=30,label='x1')
ax[0].hist(data2,alpha=0.3,bins=30,label='x2')
ax[0].hist(data3,alpha=0.3,bins=30,label='x3')
ax[0].legend()
labels = ['x1', 'x2', 'x3']
lst =[data,data2,data3]
ax[1].boxplot(lst, labels=labels) 
plt.show()
../../_images/68cc8b2329b355ac19b0d701b08da40341c6ed6ea0eb560c4be4506b6cd6662c.png
Hide code cell content
from scipy.stats import shapiro

# 정규성 검정 -> 모두 정규성을 가짐
print(shapiro(data))
print(shapiro(data2))
print(shapiro(data3))

from scipy.stats import levene

# 등분산 만족한다
print(levene(data,data2,data3))
print()

# anova 방법 1 
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm
dfm =df.melt()
dfm.head()
model = ols('value ~ C(variable)', dfm).fit()
print(anova_lm(model))
print()

# anova 방법 2 (scipy.stats.f_oneway)
from scipy.stats import f_oneway 
print(f_oneway(data, data2, data3))

# p-value 는 0.09이므로 귀무가설을 기각할 수 없다. 3그룹은 평균이 동일하다고 볼 수 있다.
ShapiroResult(statistic=0.9886646866798401, pvalue=0.5584300756454468)
ShapiroResult(statistic=0.992436408996582, pvalue=0.8518696427345276)
ShapiroResult(statistic=0.9848726987838745, pvalue=0.31093811988830566)
LeveneResult(statistic=1.845797549925243, pvalue=0.15970603203148068)

                df         sum_sq      mean_sq         F    PR(>F)
C(variable)    2.0    4856.241506  2428.120753  2.386153  0.093744
Residual     297.0  302223.696757  1017.588205       NaN       NaN

F_onewayResult(statistic=2.386152612702158, pvalue=0.09374426938585284)

Question

target 변수들에 의해 value값들의 평균의 차이가 존재하는지 검정하라

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

data = df[df.target=='a'].value
data2 = df[df.target=='b'].value
data3 = df[df.target=='c'].value

fig,ax = plt.subplots(1,2,figsize=(12,4))
ax[0].hist(data,alpha=0.3,bins=30,label='a')
ax[0].hist(data2,alpha=0.3,bins=30,label='b')
ax[0].hist(data3,alpha=0.3,bins=30,label='c')
ax[0].legend()
labels = ['a', 'b', 'c']
lst =[data,data2,data3]
ax[1].boxplot(lst, labels=labels) 
plt.show()
../../_images/dfe071bf2f50e043734442965d81d8b9787eafc5309d0b6e719e5fa38ce00c97.png
Hide code cell content
from scipy.stats import shapiro

# 정규성 검정 -> 하나의 변수가 정규성을 가지지 않는다. -> 비모수 검정인 kruskal 검정을 사용해야한다
print(shapiro(data))
print(shapiro(data2))
print(shapiro(data3))

from scipy.stats import levene

# 등분산 만족한다
print(levene(data,data2,data3))
print()

# anova
from scipy.stats import f_oneway  ,kruskal
print(f_oneway(data, data2, data3))
print(kruskal(data, data2, data3))

# 비교를 위해 f_oneway 와 kruskal 모두 시행했다.
# kruskal의 경우 평균의 차이가 존재, f_oneway의 경우 차이가 존재하지 않는다
ShapiroResult(statistic=0.9666388034820557, pvalue=0.01229821890592575)
ShapiroResult(statistic=0.9713969230651855, pvalue=0.1093384176492691)
ShapiroResult(statistic=0.9651245474815369, pvalue=0.4156579077243805)
LeveneResult(statistic=1.4817966330841852, pvalue=0.2297504921313145)

F_onewayResult(statistic=2.7145676300093733, pvalue=0.06871171968864054)
KruskalResult(statistic=6.9277037668798584, pvalue=0.03130893110123)

Question

target 변수들에 의해 value값들의 평균의 차이가 존재하는지 검정하라

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

data = df[df.target=='a'].value
data2 = df[df.target=='b'].value
data3 = df[df.target=='c'].value

fig,ax = plt.subplots(1,2,figsize=(12,4))
ax[0].hist(data,alpha=0.3,bins=30,label='a')
ax[0].hist(data2,alpha=0.3,bins=30,label='b')
ax[0].hist(data3,alpha=0.3,bins=30,label='c')
ax[0].legend()
labels = ['a', 'b', 'c']
lst =[data,data2,data3]
ax[1].boxplot(lst, labels=labels) 
plt.show()
../../_images/e5e88bf15291627df304f19682acd0374b7f069b3a98226a9fcc784988b4d2fd.png
Hide code cell content
from scipy.stats import shapiro

# 정규성 검정 -> 정규성 가짐
print(shapiro(data))
print(shapiro(data2))
print(shapiro(data3))

from scipy.stats import levene

# 등분산 만족하지 않음 -> welch test를 진행해야한다 (pingouin.welch_anova)
print(levene(data,data2,data3))
print()

# anova
from scipy.stats import f_oneway  ,kruskal
print(f_oneway(data, data2, data3))
print(kruskal(data, data2, data3))

import pingouin as pg
display(pg.welch_anova(dv='value', between='target', data=df))


# 비교를 위해 f_oneway 와 kruskal 모두 시행했다.
# kruskal의 경우 평균의 차이가 존재, f_oneway, welch(p-unc값)의 경우 차이가 존재하지 않는다
ShapiroResult(statistic=0.9835558533668518, pvalue=0.24877400696277618)
ShapiroResult(statistic=0.9923046231269836, pvalue=0.9479172825813293)
ShapiroResult(statistic=0.9523516893386841, pvalue=0.19537121057510376)
LeveneResult(statistic=4.530341210288782, pvalue=0.011923468290294031)

F_onewayResult(statistic=3.0058619004231084, pvalue=0.051771776524375666)
KruskalResult(statistic=7.273258848614091, pvalue=0.026340978769385875)
Source ddof1 ddof2 F p-unc np2
0 target 2 69.100989 2.244923 0.113608 0.029613