에이블스쿨 6기 DX 트랙/일일 복습

데이터 분석 - 이변량: 범주 vs 숫자

d061120 2024. 10. 4. 01:39

1. 환경준비

(1) 라이브러리 불러오기

import pandas as pd
import numpy as np

import matplotlib.pyplot as plt
import seaborn as sns

import scipy.stats as spst

 

(2) 데이터 불러오기

※ 예제 데이터: 타이타닉 생존자

# 타이타닉 데이터
titanic = pd.read_csv('https://raw.githubusercontent.com/DA4BAM/dataset/master/titanic.0.csv')

# 데이터 확인
titanic.head()

 

※ 범주 vs 숫자 비교하는 방법

  • 범주가 2개: 두 평균의 차이 비교
  • 범주가 3개 이상: 전체 평균과 각 범주의 평균 비교

 

2. 시각화

(1) 평균 비교: barplot

sns.barplot(x='Survived', y='Age', hue='Survived', data=titanic)
plt.grid()
plt.show()

※ 시각화: 두 집단(범주) → 숫자

  • 대립가설: 생존여부에 따라 나이의 차이가 있다.
  • sns.barplot
    • 평균을 비교할 땐 barplot을 사용한다.
    • 신뢰구간(오차범위)
      • 평균값은 신뢰구간이 좁을수록 믿을만하다.
      • 데이터가 많을수록, 편차가 적을 수록 신뢰구간은 좁아진다.
    • 두 평균의 차이가 크고, 신뢰구간이 겹치지 않을 때, 대립가설이 맞다고 볼 수 있다.
sns.barplot(x='Pclass', y='Age', hue='Pclass', data=titanic)
plt.grid()
plt.show()

※ 시각화 : 세 집단(범주) → 숫자

  • 대립가설: 객실등급에 따라 나이의 차이가 있다.
  • 동일한 함수를 사용하고, 해석 방법도 동일하다.

 

3. 수치화: t-test, anova(분산분석)

  • 범주가 두 개일 때와 세 개 이상일 때 평균을 비교하는 방법

(1) t-test: 두 집단의 평균 비교

  • 주의사항
    • 데이터에 NaN(결측치)이 있으면 계산이 안된다.
    • .notnull(), .notna() 등으로 NaN을 제외한 데이터를 사용해야 한다.
  • t 통계량
    • 두 평균의 차이를 표준오차로 나눈 값.
    • 기본적으로는 두 평균의 차이로 이해해도 된다.
    • 보통 t 값이 -2보다 작거나, 2보다 크면 차이가 있다고 본다.

1) 데이터 준비

# 먼저 NaN이 있는지 확인한다.
titanic.isna().sum()

# NaN 행 제외
temp = titanic.loc[titanic['Age'].notnull()]

# 두 그룹으로 데이터 저장
died = temp.loc[temp['Survived'] == 0, 'Age']
survived = temp.loc[temp['Survived'] == 1, 'Age']

 

2) t-test

spst.ttest_ind(died, survived)

# 출력
# TtestResult(statistic=2.06668694625381, pvalue=0.03912465401348249, df=712.0)

→ t 값이 약 2.067로, 2 이상이므로 생존여부 별로 나이에 차이가 있다는 가설이 맞기는 하나 그 영향이 크지는 않다.

 

(2) anova: 셋 이상 집단(범주)의 숫자 비교

  • 분산 분석 ANalysis Of VAriance
  • 여기서 기준은 전체 평균 입니다.
  • 𝐹 통계량 =
    • (집단 간 분산)/(집단 내 분산) = (전체 평균 − 각 집단 평균)/(각 집단의 평균 − 개별 값)
    • 값이 대략 2~3 이상이면 차이가 있다고 판단한다.
# Pclass(3개 범주) --> Age
sns.barplot(x="Pclass", y="Age", hue='Pclass', data=titanic)
plt.grid()
plt.show()

 

1) 데이터 준비

# 1) 분산 분석을 위한 데이터 만들기

# NaN 행 제외
temp = titanic.loc[titanic['Age'].notna()]

# 그룹별 저장
P_1 = temp.loc[temp.Pclass == 1, 'Age']
P_2 = temp.loc[temp.Pclass == 2, 'Age']
P_3 = temp.loc[temp.Pclass == 3, 'Age']

 

2) anova

spst.f_oneway(P_1, P_2, P_3)

# 출력
# F_onewayResult(statistic=57.443484340676214, pvalue=7.487984171959904e-24)

→ F 통계량이 약 57.4로, 객실등급에 따라 나이 분포가 다르다는 가설이 맞는 것을 알 수 있다.

 

※ 주의!

  • 분산분석은 전체 평균대비 각 그룹간 차이가 있는지만 알려준다.
  • 어느 그룹 간에 차이가 있는지는 알 수 없다.
    • 그래서 보통 사후분석을 진행한다.