이변량 분석은 타겟(y)과 변수(x)와의 관계
를 살펴보는 작업이다.
이 작업에서 우리가 세운 가설이 타당한 지를 확인한다.
귀무가설
: X와 Y가 관계가 없다.
대립가설
: 우리가 세운 가설로, X에 따라 Y가 차이가 있다.
X와 Y가 숫자냐, 범주냐에 따라서 사용하는 도구들이 달라진다.
아래 표를 참고하자(절대적인 기준은 아님).
이미지 출처: https://github.com/DA4BAM/image
상관관계를 분석하는 것으로, 숫자형(연속형)에 대해서 사용가능
하다.
결측치가 존재할 경우 계산되지 않는다.
얼마나 직선으로 값들이 모여 있는지
에 대한 수치화이다.
상관분석의 한계
는 관계가 있지만 직선이 아닌 경우
엔 해당 도구로 관계가 없다고 판단될 수 밖에 없다.상관계수는 r로 표현
된다.
r은 -1 ~ 1 사이 값
이다.
, 즉 -1 또는 1에 가까울수록 강한 상관관계
를 나타낸다.
cf) 절대적인 기준이 아니며, 강사님 경험에 의한 대략적인 기준이다.
범주형 X와 숫자형(연속형) Y일 때
사용가능하다.범주형 X의 범주가 2개일 때 사용가능
하다.결측치가 있으면 계산되지 않는다.
t통계량
은 두 평균의 차이를 표준오차로 나눈 값
이다.-2보다 작거나 2보다 크면
차이가 있다고 본다(대립가설 채택)
. 범주형 X와 숫자형(연속형) Y일 때
사용가능하다.범주가 3개 이상
일 때 사용가능하다.F통계량
은 분산비
이다.2~3 이상이면
차이가 있다고 본다(대립가설 채택)
.결측치가 존재하면 계산되지 않는다.
숫자형(연속형) X와 범주형 Y일 때
사용할 가설검정 도구가 없다.p-value
를 구하여 검정한다.5%(0.05)미만
이면 차이가 있다고 본다(대립가설 채택)
.미봉책
으로 너무 믿지는 말자.결측치가 존재하면 계산되지 않는다.
범주형 X와 범주형 Y일 때
사용가능하다.
카이는 그리스문자 를 뜻한다.
카이제곱검정
은 카이제곱 분포에 기초한 통계적 방법
으로 범주형 변수들 사이에 어떤 관계가 있는 지
를 수치화해준다.
관찰된 빈도가 기대되는 빈도와 유의하게 다른지를 검정한다.
기대빈도
: 귀무가설이 참이면 나올 수 있는 값들카이제곱검정을 통해 얻는 카이제곱통계량
은 클수록 기대빈도와 값 차이가 크다
는 의미이다.
하지만 수식을 보면 범주 수가 많을수록 카이제곱통계량은 커지게 되어있음을 알 수 있다.
따라서 보통 자유도의 2~3배보다 크면 차이가 있다
고 본다.
범주형 변수의 자유도: 범주 수 - 1
카이제곱검정에서 자유도: x변수의 자유도 * y변수의 자유도
(5 - 1) * (2 - 1) = 4
이다.이제곱통계량이 자유도 4의 2~3배인 8~12보다 크면 차이가 있다
고 볼 수 있다.import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
titanic = pd.read_csv('https://raw.githubusercontent.com/DA4BAM/dataset/master/titanic.0.csv') # 타이타닉 데이터
air = pd.read_csv('https://raw.githubusercontent.com/DA4BAM/dataset/master/air2.csv') # 뉴욕시 공기 오염도 데이터
데이터 출처: https://github.com/DA4BAM/dataset
x와 y분할과 train, val, test 셋분할은 여기서 생략하여 진행한다.
plt.scatter(air['Temp'], air['Ozone'])
plt.show()
또는
plt.scatter(x='Temp', y='Ozone', data=air)
plt.show()
sns.lmplot(x='Temp', y='Ozone', data=air)
plt.show()
sns.pairplot(air)
plt.show()
import scipy.stats as spst
튜플로 결과값을 출력한다.
첫 번째 값은 상관계수
, 두 번째 값은 p-value
이다.
결측치가 존재하면 계산되지 않는다.
-1 또는 1에 가까울수록 강한 상관관계
p-value
는 5%(0.05)미만
일 경우 x에 따라 y에 차이가 있다고 본다.spst.pearsonr(air['Temp'], air['Ozone'])
air.corr()
sns.heatmap(air.corr(), annot=True, annot_kws={'size': 10}, fmt='.2f', cmap='Blues', cbar=False)
plt.show()
범주(x)와 숫자(y) 관계를 살펴볼 때 중요한 관점은 평균비교
이다.
이때 두 가지를 고려
해야한다.
1. 평균이 그 집단을 대표할 수 있는가?
2. 평균이 믿을 만 한가?
이와 관련된 내용은 다음에 다룬다.
막대 그래프 가운데에 있는 직선은 error bar
로 신뢰구간을 의미
한다.
막대그래프의 높이는 평균
을 의미한다.
error bar의 길이에 평균이 위치할 수 있다는 것으로, 길수록 신뢰도가 떨어진다.
대립가설을 기각하고 귀무가설 채택
sns.barplot(x="Survived", y="Age", data=titanic)
plt.show()
sns.barplot(x="Pclass", y="Age", data=titanic) # X와 Y 순서를 바꾸면 옆으로 눕힌 barplot이 됨
plt.axhline(titanic['Age'].mean(), color='r') # 전체평균(기준)
plt.show()
t통계량은 두 평균의 차이를 표준오차로 나눈 값
이다.
보통 t값이 -2보다 작거나, 2보다 크면
차이가 있다고 본다.
import scipy.stats as spst
결측치가 존재하면 계산되지 않는다.
temp = titanic.loc[titanic['Age'].notnull()] # 결측치 제외
died = temp.loc[temp['Survived']==0, 'Age']
survived = temp.loc[temp['Survived']==1, 'Age']
# t-test # 인자1(평균) - 인자2(평균) = t통계량
spst.ttest_ind(died, survived)
statistic은 t통계량
을 의미한다.
F통계량은 보통 2~3이상이면 차이가 있다
고 본다.
# Na값이 있으면 F통계량, pvalue가 NaN
temp = titanic.loc[titanic['Age'].notnull()]
P_1 = temp.loc[titanic.Pclass == 1, 'Age']
P_2 = temp.loc[titanic.Pclass == 2, 'Age']
P_3 = temp.loc[titanic.Pclass == 3, 'Age']
# ANOVA
spst.f_oneway(P_1, P_2, P_3)
statistic은 F통계량(분산비)
을 의미한다.
sns.histplot(x='Age', data=titanic, hue='Survived', bins=16)
plt.show()
common_norm=False
를 할 경우, 그래프 각각의 면적 합이 1
인 그래프로 그려진다.
True로 하는 것보다 False로 하는 게 분석에 더 적합
하다.
cf) `common_norm=True가 디폴트로, 이 경우 모든 그래프 아래 면적 합이 1이다.
sns.kdeplot(x='Age', data=titanic, hue='Survived', common_norm=False)
plt.show()
x에 따라 y 클래스별 비율
을 비교해볼 수 있다.
나이에 따라 생존여부 비율을 비교
해볼 수 있다.sns.histplot(x='Age', data=titanic, bins=16, hue='Survived', multiple='fill')
plt.axhline(titanic['Survived'].mean(), color='r')
plt.show()
x에 따라 y 클래스별 비율
을 비교해볼 수 있다.
나이에 따라 생존여부 비율을 비교
해볼 수 있다.sns.kdeplot(x='Age', data = titanic, hue ='Survived', multiple = 'fill')
plt.axhline(titanic['Survived'].mean(), color = 'r')
plt.show()
숫자형 변수와 범주형 타켓에 맞는 가설검정 도구가 마땅히 없다.
로지스틱 회귀 모델은 미봉책
이다.
따라서 너무 믿지는 말자.
결측치가 있으면 계산되지 않는다.
p-value가 5%(0.05)미만
이면 차이가 있다고 본다.
import statsmodels.api as sm
model = sm.Logit(titanic['Survived'], titanic['Age'])
result = model.fit()
print(result.pvalues)
범주형 x와 범주형 y를 비교분석하기 위해선 먼저 pd.crosstab()
을 이용해 교차표
를 만들어야한다.
시각화 결과가 아래와 같다면, 대립가설을 기각하고 귀무가설을 채택
한다.
즉, x에 따라 y에 차이가 없다는 것을 의미
한다.
이미지 출처: https://github.com/DA4BAM/image
# 먼저 집계
temp = pd.crosstab(titanic['Sex'], titanic['Survived'], normalize='index')
print(temp)
# temp = temp.reindex(['male', 'female']) # 원하는 순서대로 정렬
# 집계 후 차트 그리기
temp.plot.bar(stacked=True)
plt.axhline(1 - titanic['Survived'].mean(), color = 'r') # 전체 사망률
print('전체 생존율: ', titanic['Survived'].mean())
plt.show()
from statsmodels.graphics.mosaicplot import mosaic
x축은 각 x의 범주별 전체 데이터에 대한 비율
을 나타낸다.
y축은 x의 각 범주별 y의 각 클래스 비율
을 나타낸다.
mosaic(titanic, ['Sex', 'Survived'])
plt.axhline(1 - titanic['Survived'].mean(), color = 'r') # 전체 사망률
plt.show()
mosaic(titanic, ['Sex', 'Pclass', 'Survived'])
plt.axhline(1 - titanic['Survived'].mean(), color = 'r')
plt.show()
import scipy.stats as spst
# 먼저 집계
table = pd.crosstab(titanic['Survived'], titanic['Sex'])
print('교차표\n', table)
print('-' * 35)
# 카이제곱검정
result = spst.chi2_contingency(table)
print('카이제곱통계량', result[0]) # 자유도의 2~3배보다 크면 차이가 있다는 것
print('p-value', result[1])
print('자유도', result[2])
print('기대빈도\n',result[3]) # 귀무가설이 참이면 나올 수 있는 값들
카이제곱통계량은 자유도의 2~3배
보다 크면 차이가 있다.
p-value는 5%(0.05)미만
이어야 차이가 있다고 본다.