정지홍 2023. 1. 6. 19:35

데이터 분석시에 종속변수가 있으면 지도학습 혹은 예측 분석을 이용한다.

지도학습은 종속변수가 양적변수인 회귀와 질적변수인 분류로 나뉜다.

양적변수:회귀

질적변수:분류

 

회귀분석 방법

-범주형(설명변수가 질적변수):t-검정 or 분산분석(ANOVA)

-수치형:상관분석

-수치형/범주형(설명변수에 양적변수 포함시):선형회귀

 


t-검정

  • 단일표본 t-검정--->특정 집단의 평균을 어떤 숫자와 비교
  • 독립표본 t-검정--->서로 다른 두 그룹간의 평균 비교
  • 대응표본 t-검정--->한 집단의 처리 전후 평균 비교

단일표본 t-검정

-반응변수:연속형으로 평균 비교 대상이 되는 변수

-설명변수:범주형

 

import numpy as np
import pandas as pd
import scipy as sp
from scipy import stats 

from matplotlib import pyplot as plt
import seaborn as sns

%matplotlib inline
#경고 메세지 숨기기
import warnings
warnings.filterwarnings('ignore')

data1=np.array([89.03,95.07,88.26,90.07,90.6,87,87.67,88.8,90.67,81.33])

onesample=stats.ttest_1samp(data1,90)#한 점수 그룹의 평균에 대한 T-검정을 계산,90은 감자칩 무게에 대한 귀무가설
print("Statistic(t-value):%.3f p-value:%.4f"%onesample)
print("t-value가 기각역 |2.262|보다 작고 p-value도 유의수준 0.05보다 크니 기각 불가능 ")
#kde=커널 밀도 추적 , fit=stats.norm=정규분포로
ax=sns.distplot(data1, kde=False , fit=stats.norm , label="weight" , color="blue")
ax.set(xlabel="wieght of snack")
plt.legend()#우측상단에 범례표시
plt.show()

ax=sns.distplot(data1, kde=False , fit=stats.norm , label="weight" , color="green",rug=True)
ax.set(xlabel="wieght of snack")
plt.legend()#우측상단에 범례표시
plt.show()


Statistic(t-value):-1.048 p-value:0.3218
t-value가 기각역 |2.262|보다 작고 p-value도 유의수준 0.05보다 크니 기각 불가능 

독립표본 t-검정

-반응변수: 연속형

-설명변수: 범주형(2개 이상의 집단)

두 집단은 서로 독립임을 가정한다.

등분산:두 집단의 분산이 같은 경우

이분산:두 집단의 분산이 다른 경우

 

import numpy as np
import pandas as pd
import scipy as sp
from scipy import stats

from matplotlib import pyplot as plt
import seaborn as sns

print("프로모션 진행시와 아닐시에 판매량출력하는데 상위 5개만")
df_ttest=pd.read_csv('data/ttest/promotion.csv')
df_ttest.head()
프로모션 진행시와 아닐시에 판매량출력하는데 상위 5개만

프로모션 안한경우의 평균을 구한다
Out[3]:
profitcountmeanstdmin25%50%75%max
52.000000
1923.076923
347.887397
1400.000000
1675.000000
1900.000000
2125.000000
2800.000000

print("프로모션 안한경우의 평균을 구한다")
df_ttest[df_ttest['promotion']=='NO'][['profit']].describe()

프로모션 안한경우의 평균을 구한다
Out[6]:
profitcountmeanstdmin25%50%75%max
52.000000
1923.076923
347.887397
1400.000000
1675.000000
1900.000000
2125.000000
2800.000000

print("프로모션 한 경우 평균을 구한다")
df_ttest[df_ttest['promotion']=='YES'][['profit']].describe()

프로모션 한 경우 평균을 구한다
Out[7]:
profitcountmeanstdmin25%50%75%max
48.000000
2906.250000
331.602332
2200.000000
2600.000000
2900.000000
3125.000000
3600.000000

arrYes=df_ttest[df_ttest['promotion']=='YES']['profit']
arrNo=df_ttest[df_ttest['promotion']=='NO']['profit']

print("등분산 검정 레빈")
levene=stats.levene(arrYes,arrNo)
print('levene result: %.3f         p-value: %.3f'%(levene))

print("등분산 검정 플리그너")
f=stats.fligner(arrYes,arrNo)
print('fligner result: %.3f         p-value: %.3f'%(f))

print("등분산 검정 바틀렛")
b=stats.bartlett(arrYes,arrNo)
print('bartlett result: %.3f         p-value: %.3f'%(b))

print("위 결과를 통하여 p-value가 0.5보다 크니 등분산성 조건을 만족한다")
print("아래를 보면 p-value가 0.05보다 작으니 유의미하다고 본다")
rst=stats.ttest_ind(arrNo,arrYes,equal_var=True)
print('t-value:%.3f     p-value:%.28f'%rst)


등분산 검정 레빈
levene result: 0.258         p-value: 0.612
등분산 검정 플리그너
fligner result: 0.179         p-value: 0.672
등분산 검정 바틀렛
bartlett result: 0.111         p-value: 0.739
위 결과를 통하여 p-value가 0.5보다 크니 등분산성 조건을 만족한다
아래를 보면 p-value가 0.05보다 작으니 유의미하다고 본다
t-value:-14.439     p-value:0.0000000000000000000000000527

print("대응 표본 t검정이다.")
print("특정 객체에게 처리를 하기 전 후 를 비교한는것")
print("광고모델 a양 기용 전후에 매출에 의미가 있는지 확인한다.\n아래는 전후 매출을 보여준다. 5개만")
df_ad=pd.read_csv('data/ttest/tvads.csv')
df_ad.head()

대응 표본 t검정이다.
특정 객체에게 처리를 하기 전 후 를 비교한는것
광고모델 a양 기용 전후에 매출에 의미가 있는지 확인한다.
아래는 전후 매출을 보여준다. 5개만
Out[19]:
storebeforeafter01234
1 290 326
2 304 306
3 282 328
4 293 322
5 288 314

대응 표본 t검정이다.
특정 객체에게 처리를 하기 전 후 를 비교한는것
광고모델 a양 기용 전후에 매출에 의미가 있는지 확인한다.
아래는 전후 매출을 보여준다. 5개만
Out[19]:
storebeforeafter01234
1 290 326
2 304 306
3 282 328
4 293 322
5 288 314

plt.figure(figsize=(16,12)) #그래프의 사이즈설정 가로,세로

ax1=plt.subplot(221)
ax1=sns.distplot(before,kde=False,fit=stats.gamma,label='before',color='blue')
ax1.set(xlabel="number of customers",title='before')
plt.legend()

ax2=plt.subplot(222)
ax2=sns.distplot(after,kde=False,fit=stats.gamma,label='before',color='red')
ax2.set(xlabel="number of customers",title='after')
plt.legend()


ax3=plt.subplots()
ax3=sns.distplot(before , kde=False , fit=stats.gamma , label='before' , color='blue')
ax3=sns.distplot(after , kde=False , fit=stats.gamma , label='after' , color='red')
ax3.set(xlabel='number of customers',title='before and after')
plt.legend()
plt.show()


분산분석은 독립변수가 범주형, 종속변수가 수치형인 경우 사용

 

 

일원 분산 분석(one way ANOVA)

-연속형 반응변수 1개

-범주형 변수 1개(주로 설명변수 수준 수가 3개 이상인 경우 사용 , 2개 이하면 t-검정)

-자료는 정규분포이며 등분산 가정을을 한다. 아닌 경우 비모수 검정을 사용

import numpy as np
import pandas as pd
from scipy import stats
import statsmodels.api as sm
from statsmodels.formula.api import ols

from matplotlib import pyplot as plt
import seaborn as sns

%matplotlib inline
import warnings
warnings.filterwarnings('ignore')

dataF=pd.read_csv('data/anova/factory.csv')
dataF
 

machinetypedefRate01234...295296297298299

1 3 0.001999
2 1 0.005974
3 4 0.007828
4 1 0.006121
5 1 0.005887
... ... ...
296 2 0.002640
297 4 0.007573
298 2 0.003870
299 1 0.005815
300 1 0.006372

 


dataF.info()
print("\n결측치가 존재하는지 확인")
dataF.isnull().sum()
print('\n업체별 데이터 개수 확인')
dataF['type'].value_counts()
 
<class 'pandas.core.frame.DataFrame'> RangeIndex: 300 entries, 0 to 299 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 machine 300 non-null int64 1 type 300 non-null int64 2 defRate 300 non-null float64 dtypes: float64(1), int64(2) memory usage: 7.2 KB 결측치가 존재하는지 확인 업체별 데이터 개수 확인
3 78 2 77 1 75 4 70 Name: type, dtype: int64

dataF.describe()

machinetypedefRatecountmeanstdmin25%50%75%max

300.000000 300.000000 300.000000
150.500000 2.476667 0.004636
86.746758 1.104622 0.002418
1.000000 1.000000 0.000704
75.750000 1.750000 0.002357
150.500000 2.000000 0.003865
225.250000 3.000000 0.006799
300.000000 4.000000 0.008727

def skew(x):
    return stats.skew(x)

def kurtosis(x):
    return stats.kurtosis(x)

df_desc_stat=dataF.groupby("type")['defRate'].describe()

skew_rst=[]
kurtosis_rst=[]
null_rst=[]

for i in range(1,5):
    skew_rst.append(skew(dataF[dataF['type']==i]['defRate']))
    kurtosis_rst.append(kurtosis(dataF[dataF['type']==i]['defRate']))
    null_rst.append((dataF[dataF['type']==i]['defRate'].isnull().sum()))

df_desc_stat['median']=dataF.groupby("type")['defRate'].median()
df_desc_stat['skew']=skew_rst
df_desc_stat['kurtosis']=kurtosis_rst
df_desc_stat['miss']=null_rst
df_desc_stat.head()

countmeanstdmin25%50%75%maxmedianskewkurtosismisstype1234

75.0 0.006029 0.000460 0.005062 0.005724 0.005986 0.006344 0.007295 0.005986 0.284333 -0.245943 0
77.0 0.002996 0.000522 0.002097 0.002640 0.002976 0.003368 0.004074 0.002976 0.203093 -0.770529 0
78.0 0.001946 0.000454 0.000704 0.001689 0.001986 0.002248 0.002917 0.001986 -0.369573 0.398895 0
70.0 0.007946 0.000420 0.006821 0.007650 0.007940 0.008278 0.008727 0.007940 -0.389347 -0.232689 0

sns.boxplot(x="type",y="defRate",data=dataF)
plt.show()


sns.violinplot(x='type',y='defRate',data=dataF)
plt.show()


type1 = np.array(dataF[dataF['type'] == 1]['defRate'])
type2 = np.array(dataF[dataF['type'] == 2]['defRate'])
type3 = np.array(dataF[dataF['type'] == 3]['defRate'])
type4 = np.array(dataF[dataF['type'] == 4]['defRate'])

figure, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2)
figure.set_size_inches(16,12)

sns.distplot(type1, norm_hist=False, kde=False, label="type1", rug=True, color = 'blue', ax=ax1)
sns.distplot(type2, norm_hist=False, kde=False, label="type2", rug=True, color = 'red', ax=ax2)
sns.distplot(type3, norm_hist=False, kde=False, label="type3", rug=True, color = 'green', ax=ax3)
sns.distplot(type4, norm_hist=False, kde=False, label="type4", rug=True, color = 'orange', ax=ax4)

ax1.set(ylabel='defRate', title = "type1")
ax2.set(ylabel='defRate', title = "type2")
ax3.set(ylabel='defRate', title = "type3")
ax4.set(ylabel='defRate', title = "type4")

 


plt.figure(figsize=(16,6))

ax5 = sns.distplot(type1, hist=True, norm_hist=False, kde=False, label="type1", color = 'blue')
ax5 = sns.distplot(type2, hist=True, norm_hist=False, kde=False, label="type2", color = 'red')
ax5 = sns.distplot(type3, hist=True, norm_hist=False, kde=False, label="type3", color = 'green')
ax5 = sns.distplot(type4, hist=True, norm_hist=False, kde=False, label="type4", color = 'orange')
ax5.set(xlabel="defRate")

plt.legend()
plt.show()


<div><br class="Apple-interchange-newline">("위의 결과로 업체3이 불량률이 제일 낮았다.") data_one_anova=dataF.drop('machine',axis=1) data_one_anova.head()</div>
 
 
print("위의 결과로 업체3이 불량률이 제일 낮았다.")
data_one_anova=dataF.drop('machine',axis=1)
data_one_anova.head()
위의 결과로 업체3이 불량률이 제일 낮았다.
Out[30]:
typedefRate01234
3 0.001999
1 0.005974
4 0.007828
1 0.006121
1 0.005887

t1=data_one_anova[data_one_anova['type']==1]['defRate']
t2=data_one_anova[data_one_anova['type']==2]['defRate']
t3=data_one_anova[data_one_anova['type']==3]['defRate']
t4=data_one_anova[data_one_anova['type']==4]['defRate']

rst=stats.f_oneway(t1,t2,t3,t4)
rst
print(f'F-Value : {rst[0]:.4f} P-value : {rst[1]:.3f}')
print("p-value가 0.05보다 작으니 귀무가설(업체의 기계에 따른 불량률의 차이는 없다)을 기각한다")
print("아래의 R-squared가 1에 가까우니 설명력이 높다고 본다.")

F-Value : 2583.2183 P-value : 0.000
p-value가 0.05보다 작으니 귀무가설(업체의 기계에 따른 불량률의 차이는 없다)을 기각한다

df_model = pd.DataFrame(dataF, columns=['defRate', 'type'])

results = ols('defRate ~ C(type)', data = df_model).fit()
results.summary()


levene = stats.levene(type1, type2, type3, type4)
print('levene result(F) : %.3f \np-value : %.3f' % (levene))

levene = stats.levene(type1, type2, type3, type4, center = 'mean')
print('levene result(F) : %.3f \np-value : %.3f' % (levene))


fligner = stats.fligner(type1, type2, type3, type4)
print('fligner Result(F) : %.3f \np-value : %.3f' % (fligner))


bartlett = stats.bartlett(type1, type2, type3, type4)
print('bartlett Result(F) : %.3f \np-value : %.3f' % (bartlett))

levene result(F) : 1.731 
p-value : 0.161
levene result(F) : 1.749 
p-value : 0.157
fligner Result(F) : 5.074 
p-value : 0.166
bartlett Result(F) : 3.608 
p-value : 0.307

# reject: True인 경우, type1과 type2의 불량률의 차이가 없다는 귀무가설을 기각
from statsmodels.stats.multicomp import pairwise_tukeyhsd

posthoc = pairwise_tukeyhsd(dataF['defRate'], dataF['type'], alpha=0.05)
posthoc.summary()


df_desc_stat[['mean']]