일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 크롤링
- fashion mnist
- AWS 입문자를 위한 강의
- MaxPooling2D
- 데이터
- Pooling Layer
- NewsWhale
- kt에이블스쿨
- 딥러닝
- bias
- learning_rate
- CNN 실습
- pandas
- Neural Network
- 모델평가
- Convolution Neural Network
- 데이터크롤링
- CNN
- explained AI
- 뉴스웨일
- 데이터처리
- 데이터분석
- AI
- 머신러닝
- 키워드 기반 뉴스 조회
- CIFAR-10
- 인공지능
- CRISP-DM
- OneHotEncoding
- plot_model
- Today
- Total
jjinyeok 성장일지
데이터 분석 및 의미 찾기 #3 - 이변량 데이터 분석하기 2022/08/10~2022/08/12 본문
데이터 분석 및 의미 찾기 #3 - 이변량 데이터 분석하기 2022/08/10~2022/08/12
jjinyeok 2022. 8. 20. 22:341. 이변량 분석
CRISP-DM의 비즈니스 이해 과정에서 우리는 (초기)가설을 수립했다. 가설은 어떠한 feature X가 target y에 영향을 줄 것이라는 것이다. 우리는 데이터를 분석하고 이해하는 과정에서 시각화와 수치화라는 두가지 도구를 통해 가설의 두 변수 X와 y의 관계를 살펴볼 수 있다. 이때 데이터의 형태에 따라 사용하는 도구가 달라진다.

2. X(수치형 데이터) -> y(수치형 데이터) 시각화를 통해 분석하기
수치형 데이터와 수치형 데이터의 관계를 분석하기 위해서 중요한 관점은 직선(Linearity)이다. matplotlib pyplot의 scatter() 함수와 seaborn의 scatterplot() 함수를 통해 산점도를 그릴 수 있고, 산점도를 통해 우리는 두 수치형 데이터의 관계를 시각화 할 수 있다. 이때 산점도에서 뚜렷한 패턴이 보인다면 두 데이터는 강한 관계로 볼 수 있다. 추가적으로 seaborn의 pairplot() 함수를 통해 Dataframe의 숫자형 변수들에 대한 산점도 전체를 그릴 수 있고 seaborn의 jointplot() 함수를 통해 산점도와 히스토그램을 함께 시각화하는 것 또한 가능하다. 과정은 다음과 같다.
"X(수치형 데이터) -> y(수치형 데이터) 시각화 분석"
# matplotlib pyplot scatter() 함수
plt.scatter('Temp', 'Ozone', data = air)
plt.title('Temp & Ozone')
plt.xlabel('Temp')
plt.ylabel('Ozone')
plt.grid()
plt.show()
# seaborn scatterplot() 함수
sns.scatterplot(x='Temp', y='Ozone', data = air)
plt.title('Temp & Ozone')
plt.xlabel('Temp')
plt.ylabel('Ozone')
plt.grid()
plt.show()

# seaborn pairplot() 함수
sns.pairplot(air)
plt.show()

# seaborn jointplot() 함수
sns.jointplot(x='Temp', y='Ozone', data = air)
plt.show()

3. X(수치형 데이터) -> y(수치형 데이터) 수치화를 통해 분석하기
산점도에서 직선의 패턴이 보인다면 강한 상관관계로 볼 수 있다. 이때 데이터가 얼마나 직선으로 모여 있는지를 수치화한 것이 상관계수이다. 상관계수는 -1에서 1 사이의 값이고 -1, 1에 가까울수록 강한 상관관계를 나타낸다. 현업에 계신 강사님의 경험에 의하면 보통 상관계수 r에 대해 0. 5 < | r | <= 1 일때 강한 상관관계를 0. 2 < | r | <= 0.5 일때 중간의 상관관계를 0. 1 < | r | <= 0.2 일때 약한 상관관계를 가지고 | r | <= 0.1 일때 관계가 없다고 판단한다고 하셨다.
상관계수를 구하기 위해 데이터프레임의 모든 숫자형 데이터 상호간에 상관계수를 계산하는 데이터프레임의 corr() 메서드를 사용할 수 있고 두 수치형 데이터로부터 상관계수를 구하기 위해 scipy 패키지의 pearsonr() 함수를 사용할 수 있다. 두 과정은 다음과 같다.
"X(수치형 데이터) -> y(수치형 데이터) 수치화 분석"
import scipy.stats as spst
# scipy stats의 pearson() 함수
spst.pearsonr(air['Temp'], air['Ozone'])
# 상관계수와 p-value
# (0.6833717861490115, 2.197769800200214e-22)
# 데이터프레임 corr() 메서드
print(air.corr())
# Ozone Solar.R Wind Temp Month Weekday
# Ozone 1.000000 0.280068 -0.605478 0.683372 0.174197 -0.012900
# Solar.R 0.280068 1.000000 -0.056792 0.275840 -0.075301 0.071189
# Wind -0.605478 -0.056792 1.000000 -0.457988 -0.178293 0.037313
# Temp 0.683372 0.275840 -0.457988 1.000000 0.420947 -0.032574
# Month 0.174197 -0.075301 -0.178293 0.420947 1.000000 0.030261
# Weekday -0.012900 0.071189 0.037313 -0.032574 0.030261 1.000000
이때 추가적으로 데이터프레임의 corr() 메서드를 통한 상관계수를 heatmap으로 시각화 할 수 있다. 이것은 seaborn의 heatmap() 함수를 통해 가능한데 과정은 다음과 같다. 추가적으로 color를 수정한다면 https://matplotlib.org/stable/tutorials/colors/colormaps.html 사이트를 참고하자.
#seaborn의 heatmap() 함수
sns.heatmap(air.corr(), annot = True, fmt = '.3f', cmap = 'RdYlBu_r', vmin = -1, vmax = 1)
plt.show()

그러나 상관계수에는 한계가 존재한다. 첫번째로 상관계수는 얼마나 직선인가를 측정하는 지표이다. 직선의 기울기를 계산할 수 없다는 문제가 있다. 두번째로 데이터가 연관되어 있어도 직선의 관계가 아니라면 상관계수가 낮을 수 있다.
4. p-value와 가설검정
우리의 목적은 일부 데이터인 표본을 통해 구하고 싶은 대상의 전체 데이터인 모집단을 추정하는 것이다. 따라서 먼저 모집단에 대한 가설을 수립하고 표본을 가지고 가설이 진짜인지 검증하는 과정을 거치게 된다. 이것은 CRISP-DM의 비즈니스 이해 과정에서 우리는 (초기)가설을 수립하는 것과 같다. 이때 기존의 입장을 귀무가설, 우리가 현재 세운 가설을 대립가설이라 한다. 우리는 표본으로부터 대립가설을 확인하고 모집단에서도 맞을 것이라 주장한다. 이때 대립가설의 값이 얼마나 큰지 작은지 흔한 일인지 드문 일인지 알기 위해 값의 분포를 알아야한다. 이때 계산된 통계량은 각자의 분포를 가진다. 당연히 분포를 통해서 값이 큰지 작은지 판단이 가능한데 이를 손쉽게 판단할 수 있도록 계산해 준 것이 p-value이다. 즉 p-value는 분포에서 드문 영역의 면적이다.
p-value를 통해 가설을 검증한다는 것은 어떠한 가설에 대해 p-value를 구했을 때, p-value는 그 결정이 틀릴 확률을 나타낸다. 피셔의 밀크티로부터 유래한 5%를 기준으로 대립가설인지 귀무가설인지 찾을 때 p-value가 0.05보다 작다면 대립가설이, 크다면 귀무가설이 참이 되는 것이다. 이러한 절차를 가설 검정이라고 한다.
5. X(범주형 데이터) -> y(수치형 데이터) 시각화를 통해 분석하기
범주형 데이터와 수치형 데이터의 관계를 분석하기 위해서 중요한 관점은 평균비교이다. 평균을 비교할 때는 두 가지를 고려해야 한다. 평균값이 그 집단을 대표할 수 있는지 판단해야 하고 평균값이 믿을만한지 판단해야 한다. 보통 분포가 히스토그램의 분포가 정규분포가 유사할 때 평균값은 그 집단을 대표할 수 있다고 할 수 있다. seaborn의 barplot() 함수를 통해 평균비교를 시각화할 수 있다. 그 과정은 다음과 같다.
"X(범주형 데이터) -> y(수치형 데이터) 시각화 분석하기"
# seaborn의 barplot() 함수
sns.barplot(x="Survived", y="Age", data=titanic)
plt.show()

이때 막대그래프 위의 선은 신뢰구간을 의미한다. 신뢰 구간을 포함하여 둘의 차이가 크다면 두 집단의 평균은 차이가 있다고 볼 수 있고 따라서 대립가설이 참일 가능성이 높다.
6. X(범주형 데이터) -> y(수치형 데이터) 수치화를 통해 분석하기
범주의 개수에 따라 우리는 사용하는 도구가 다르다. 범주가 2개일 때는 t-Test 검증을 범주가 3개 이상일 때는 ANOVA 검증을 사용한다. t-Test는 귀무가설이 맞다면, 두 집단의 평균은 일치하거나 거의 같을 것이라는 두 집단의 평균 비교를 가정하여 사용한다. t-Test를 통해 우리는 t 통계량과 p-value를 알 수 있다. t 통계량은 두 평균의 차이를 표준오차로 나눈 값으로 기본적으로는 두 평균의 차이이다. t 통계량이 크다는 것은 차이가 있다는 것을 의미한다. 따라서 t 통계량이 크다면 대립가설이 참일 가능성이 높다. 보통 t 통계량이 -2보다 작거나, 2보다 크다면 차이가 있다고 본다. scipy의 ttest_ind() 함수를 통해 구현이 가능하다. 그 과정은 다음과 같다.
"두 집단의 평균 비교: t Test"
# 데이터
temp = titanic.loc[titanic['Age'].notnull()]
died = temp.loc[temp['Survived']==0, 'Age']
survived = temp.loc[temp['Survived']==1, 'Age']
# t Test
print(spst.ttest_ind(died, survived))
# Ttest_indResult(statistic=2.06668694625381, pvalue=0.03912465401348249)
여러 집단 간에 차이는 전체 평균을 통해 비교한다. 이때 ANOVA라고 불리는 분산 분석 (ANalysis Of VAriance) 을 사용한다. 전체 그룹간의 차이를 알려주는 역할로 f 통계량을 반환한다. 보통 f 통계량은 보통 2~3 이상이면 차이가 있다 판단한다. scipy의 f_oneway() 함수를 사용해서 구현이 가능하다. 그 과정은 다음과 같다.
"여러 집단의 평균 비교: ANOVA"
# 데이터
temp = titanic.loc[titanic['Age'].notnull()]
P_1 = temp.loc[temp.Pclass == 1, 'Age']
P_2 = temp.loc[temp.Pclass == 2, 'Age']
P_3 = temp.loc[temp.Pclass == 3, 'Age']
# ANOVA
print(spst.f_oneway(P_1, P_2, P_3))
# F_onewayResult(statistic=57.443484340676214, pvalue=7.487984171959904e-24)
이때 분산분석 (ANOVA)는 전체 평균대비 각 그룹간 차이가 있는지를 알려준다. 따라서 어느 그룹 간에 차이가 있는지는 알 수 없다는 문제가 있음에 유의하자.
7. X(범주형 데이터) -> y(범주형 데이터) 시각화를 통해 분석하기
범주형 데이터와 범주형 데이터의 관계를 분석하기 위해 먼저 교차표를 만들어야한다. 교차표를 통해 집계한 정보를 기반으로 시각화와 수치화 모두 가능하기 때문이다. pandas의 crosstab() 메서드를 이용하여 교차표를 만들 수 있다. 이때, normalize parameter를 활용할 수 있다. normalize='columns'는 열 기준을 100%로 두고, normalize='index'는 행 기준을 100%로 normalize='all'은 전체 기준을 100%로 교차표를 만들어 준다. crosstab의 plt.bar() 메서드를 사용할 때는 normalize를 'index'로 지정해야 한다. 과정은 다음과 같다.
"X(범주형 데이터) -> y(범주형 데이터) 시각화 분석"
# crosstab 만들기
temp = pd.crosstab(titanic['Pclass'], titanic['Survived'], normalize = 'index')
print(temp)
# Survived 0 1
# Pclass
# 1 0.370370 0.629630
# 2 0.527174 0.472826
# 3 0.757637 0.242363
# crosstab의 plot.bar() 메서드
temp.plot.bar(stacked=True)
plt.show()

이때 crosstab의 plt.bar() 메서드는 범주의 비율에 대한 시각화를 제공한다. 따라서 양에 대한 비교를 할 수 없다. 이러한 단점을 해결하기 위해 mosaic plot을 사용한다. mosaic plot은 statsmodles.graphic.mosaicplot에서 제공되는 mosaic() 함수를 통해 사용가능하다. 과정은 다음과 같다.
"X(범주형 데이터) -> y(범주형 데이터) 시각화 분석 : mosaic"
from statsmodels.graphics.mosaicplot import mosaic
mosaic(titanic, [ 'Pclass','Survived'])
plt.show()

귀무가설이 참일때는 막대를 나누는 기준이 동일하다. 따라서 기준의 차이가 크면 클수록 대립가설이 참일 가능성이 높다.
7. X(범주형 데이터) -> y(범주형 데이터) 수치화를 통해 분석하기
범주형 데이터와 범주형 데이터의 관계를 수치화하기 위해 카이 제곱 검정 방법을 사용한다. 카이 제곱 검증은 관측된 값과 확률적으로 독립일 때 기대되는 값을 비교하여 p-value를 도출하는 방법이다. 따라서 카이 제곱 통계량이 클수록 기대빈도로부터 실제 값에 차이가 있다는 의미를 지니고 보통 자유도의 2~3배보다 크면 차이가 있다고 본다. 자유도는 범주의 수 - 1을 의미한다. 카이 제곱 검증 또한 pandas의 crosstab() 메서드를 통한 집계 이후 scipy의 chi2_contingency() 함수를 이용해 구현한다. 과정은 다음과 같다.
"X(범주형 데이터) -> y(범주형 데이터) 수치화 분석"
# 먼저 집계
table = pd.crosstab(titanic['Survived'], titanic['Pclass'])
print(table)
# Pclass 1 2 3
# Survived
# 0 80 97 372
# 1 136 87 119
# 카이제곱검정
result = spst.chi2_contingency(table)
print('카이제곱통계량', result[0])
print('p-value', result[1])
print('기대빈도\n',result[3])
# 카이제곱통계량 102.88898875696056
# p-value 4.549251711298793e-23
# 기대빈도
# [[133.09090909 113.37373737 302.53535354]
# [ 82.90909091 70.62626263 188.46464646]]
'[KT AIVLE School]' 카테고리의 다른 글
머신 러닝 #2 - KNN & Logistic Regression 2022/08/22~2022/08/29 (0) | 2022.08.29 |
---|---|
머신러닝 #1 - 모델링 개요 & Linear Regression 2022/08/22~2022/08/29 (0) | 2022.08.22 |
데이터 분석 및 의미 찾기 #2 - 개별 변수 분석하기 2022/08/10~2022/08/12 (0) | 2022.08.20 |
데이터 분석 및 의미 찾기 #1 - 2022/08/10~2022/08/12 (0) | 2022.08.15 |
데이터 처리 #2 - 2022/08/08~2022/08/09 (0) | 2022.08.15 |