KT AIVLE/데이터 분석, ML, DL

[KT AIVLE DX 트랙 7기] 가설검증 & 이변량 분석과 시각화

Dori1998 2025. 4. 6. 15:04

KT 에이블스쿨 7기 DX 트랙에 기자단으로 신청하기도 하였고, 복습을 통한 역량을 강화, 습득을 목적으로 작성되었음을 알려드립니다.

 

그럼, 복습 Let's go

 


 

가설검정

가설검정은 표본데이터를 이용해 모집단에 대한 주장의 진위 여부를 통계적으로 판단하는 절차로서, 우리가 세운 주장이 데이터에 의해 통계적으로 타당한지 판단하는 방법이다.

 

가설검정 절차?

가설검정 비교 또는 검증할 주장 설정, 귀무가설과 대립가설 정의
유의수준 결정 기각 기준이 되는 오류 허용 수준 설정 (보통 0.05)
검정방법 결정 데이터 특성과 조건에 따라 적절한 검정법 선택
검정통계량 계산 표본 통계량을 이용해 검정통계량 계산
채택/기각 여부 판단 계산된 p-value와 유의수준을 비교하여 귀무가설 기각 여부 판단

 

가설 설정 : 귀무가설 vs 대립가설

가설검정을 시작하기 위해서는 귀무가설과 대립가설을 설정하는 것이 첫번째 단계이다. 귀무가설은 '차이가 없다' 주장이고, 대립가설은 '차이가 있다'는 주장이다.

 

- 귀무가설

: 모집단이 어떠한 특징을 지닐 것으로 여겨지는 가설로서 일반적으로 차이가 없다, 같다 기호를 사용해서 나타낼 수 있는 가설로 H0로 나타낸다.

 

- 대립가설

: 대립가설이란 실험이나 연구를 통해 증명하고 싶은 가설로서, 귀무가설이 틀렸다고 판단될 경우 채택되는 가설로 H1으로 나타낸다.

가설 종류 설명 예시
귀무가설(H0) 변화 없음, 차이 없음(기본 가정) "신제품 효과는 기존 제품과 동일하다."
대립가설(H1) 변화 있음, 차이있음 (우리의 주장) "신제품 효과는 기존 제품과 달리 효과가 있다."

 

유의수준이란?

- 유의수준은 귀무가설이 참일 때, 그것을 잘못 기각할 최대 허용확률을 의미한다.

- 즉, 1종 오류를 감수하는 기준이 된다.

- 일반적 (관례)으로 a = 0.05 사용하며, 이는 5% 확률로 잘못 판단할 수 있다를 의미한다.

 


이변량 분석

이변량 분석은 두 개의 변수 간 관계를 파악하기 위한 탐색적 데이터 분석 방법입니다. 두 변수의 상관성, 영향 관계, 차이 등을 시각화 및 통계 기법을 통해 분석합니다.

숫자형 vs 숫자형 산점도, 상관계수 (피어슨, 스피어만), 회귀선
범주형 vs 숫자형 그룹별 평균 비교 (박스플롯), t-test, ANOVA
범주형 vs 범주형 교차표, 모자이크 플롯, 카이제곱 검정

 

가설검정 용어 (피어슨, 티테스트, chi2)

숫자 - 숫자 (pearsonr) pearsonr()
범주 - 숫자 (ttest) ttest_ind()
범주 - 범주 (chi2) chi2_contingency()

 

이변량 분석 : 숫자형 - 숫자형 변수 분석하기

먼저 데이터를 설정합니다.

import pandas as pd

data = {
    'study_hours': [1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10],
    'exam_score': [52, 55, 60, 62, 64, 68, 72, 75, 78, 82, 85, 88, 90, 94]
}
df = pd.DataFrame(data)
df.head()

 

그리고 저희는 "학생의 공부 시간과 시험 점수 간의 관계를 분석하여, 양의 상관관계가 있는지를 검정해 보도록 합니다."

※ 산점도, 피어슨 상관계수 활용

- 귀무가설 : 공부 시간과 시험 점수 사이에는 상관관계가 없다.

- 대립가설 : 공부 시간이 증가할수록 시험 점수도 증가하는 경향이 있다.

 

산점도(Scatter Plot)

- 산점도는 숫자형 변수 두 개의 관계를 볼 때 가장 많이 쓰이는 그래프입니다.

- 각 점은 한 명의 학생을 나타낼 거고, x축은 공부시간, y축은 시험 점수로 표현된다면 공부 시간이 늘어날수록 점수가 올라가는지 확인할 수 있을 것입니다.

 

피어슨 상관계수

- 두 숫자형 변수 사이에 선형 관계를 수치로 표현한 값입니다.

- 값의 범위는 -1에서 1사이이며,

  +1에 가까울수록 : 강한 양의 상관관계가 있다고 하며(공부 시간 많이 -> 점수 높음)

  - 1에 가까울수록 : 강한 음의 상관관계가 있다고 한다.(공부 시간이 낮다면 -> 점수가 낮다.)

 

P-value

- 상관계수가 우연히 나온 값인지, 아니면 통계적으로 유의미한 관계인지를 검정하는 값입니다.

- 보통 p-value가 0.05보다 작으면, "이건 우연이 아니라, 실제 관계가 있다"고 해석한다.

 

■ 피어슨 상관계수 : 관계의 방향과 세기

■ p-value : 그 관계가 통계적으로 의미 있는지 여부

 

import pandas as pd

data = {
    'study_hours': [1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10],
    'exam_score': [52, 55, 60, 62, 64, 68, 72, 75, 78, 82, 85, 88, 90, 94]
}
df = pd.DataFrame(data)



import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import pearsonr

# 1. 산점도 그리기
sns.scatterplot(x='study_hours', y='exam_score', data=df)
plt.title('Study Hours vs Exam Score')
plt.xlabel('Study Hours')
plt.ylabel('Exam Score')
plt.grid(True)
plt.show()

 

※ matplotlib.pyplot.scatter

matplotlib.pyplot.scatter(x, y, s=None, c=None, *, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, edgecolors=None, colorizer=None, plotnonfinite=False, data=None, **kwargs)

matplotlib.pyplot.scatter — Matplotlib 3.10.1 documentation

 

matplotlib.pyplot.scatter — Matplotlib 3.10.1 documentation

{'/', '\', '|', '-', '+', 'x', 'o', 'O', '.', '*'}

matplotlib.org

 

그럼 여기에서 scipy.stats.pearsonr 함수를 이용해서 피어슨 상관계수와 p-value를 구해볼까요?

from scipy.stats import pearsonr
corr, p_value = pearsonr(df['study_hours'], df['exam_score'])
print(f"📌 피어슨 상관계수: {corr:.2f}")
print(f"📌 p-value: {p_value:.4f}")

📌 피어슨 상관계수: 0.99 📌 p-value: 0.0000

 

pearsonr

pearsonr(x, y, *, alternative='two-sided', method=None, axis=0)

 

이변량 분석 2 : 범주형 - 숫자형 변수 분석하기

먼저 데이터를 설정해 봅시다.

import pandas as pd

data = {
    'gender': ['Male', 'Female', 'Male', 'Female', 'Male', 'Female', 'Male', 'Female', 'Male', 'Female'],
    'math_score': [75, 82, 70, 85, 68, 88, 72, 90, 74, 87]
}

df = pd.DataFrame(data)
df.head()

 

그럼 왜 범주형 - 숫자형은 박스플롯(Boxplot)을 사용할까요?- 성별은 범주형 변수이고, 수학 점수는 숫자형 변수입니다.- 이런 경우, 각 범주 (예 : 남성, 여성) 그룹의 점수 분포를 비교할 때 박스 플롯이 가장 많이 쓰입니다.

 

독립 표본 t-검정이란?- 두 개의 집단 평균이 통계적으로 유의미하게 다른지 검정하는 방법입니다. - 여기서는 "남학생과 여학생의 수학 점수 평균이 같은가?"를 검정합니다.- 귀무가설(H0) : 남녀 간 수학 점수 차이가 없다.- 대립가설(H1) : 남겨 간 수학 점수 차이가 있다.

만약, T-test에서 P-value의 값이 0.05보다 작으면, "두 집단의 평균은 유의마하게 다르다."고 해석할 수 있습니다.

 

 

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import ttest_ind

# df[df["gender"] == "Male"]['math_score'] 남성인 성을 뽑아서 매스 스코어를 다 더한 것
# df[df["gender"] == "Female"]['math_score'] 여성인 성을 뽑아서 매스 스코어를 다 더한 것

plt.boxplot([     df[df["gender"] == "Male"]['math_score'], df[df["gender"] == "Female"]['math_score']    ], labels = ["Male", "Female"])
plt.show()
# 모범 답안

import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import ttest_ind

# 1. 박스플롯 시각화
sns.boxplot(x='gender', y='math_score', data=df)
plt.title('Math Score by Gender')
plt.xlabel('Gender')
plt.ylabel('Math Score')
plt.grid(True)
plt.show()

# sns.boxplot(x = df[df["gender"] == "Male"]['math_score'],y = df[df["gender"] == "Female"], data=df)
# plt.show()

 

※ plt.boxplot이랑 sns.boxplot의 차이

matplotlib.pyplot.boxplot

matplotlib.pyplot.boxplot(x, *, notch=None, sym=None, vert=None, orientation='vertical', whis=None, positions=None, widths=None, patch_artist=None, bootstrap=None, usermedians=None, conf_intervals=None, meanline=None, showmeans=None, showcaps=None, showbox=None, showfliers=None, boxprops=None, tick_labels=None, flierprops=None, medianprops=None, meanprops=None, capprops=None, whiskerprops=None, manage_ticks=True, autorange=False, zorder=None, capwidths=None, label=None, data=None)

seaborn.boxplot — seaborn 0.13.2 documentation

 

seaborn.boxplot — seaborn 0.13.2 documentation

seaborn.boxplot seaborn.boxplot(data=None, *, x=None, y=None, hue=None, order=None, hue_order=None, orient=None, color=None, palette=None, saturation=0.75, fill=True, dodge='auto', width=0.8, gap=0, whis=1.5, linecolor='auto', linewidth=None, fliersize=Non

seaborn.pydata.org

seaborn.boxplot

seaborn.boxplot(data=None, *, x=None, y=None, hue=None, order=None, hue_order=None, orient=None, color=None, palette=None, saturation=0.75, fill=True, dodge='auto', width=0.8, gap=0, whis=1.5, linecolor='auto', linewidth=None, fliersize=None, hue_norm=None, native_scale=False, log_scale=None, formatter=None, legend='auto', ax=None, **kwargs)

seaborn.boxplot — seaborn 0.13.2 documentation

 

seaborn.boxplot — seaborn 0.13.2 documentation

seaborn.boxplot seaborn.boxplot(data=None, *, x=None, y=None, hue=None, order=None, hue_order=None, orient=None, color=None, palette=None, saturation=0.75, fill=True, dodge='auto', width=0.8, gap=0, whis=1.5, linecolor='auto', linewidth=None, fliersize=Non

seaborn.pydata.org

 

spicy.stats.ttest_ind를 통해 독립 표본 t-검정을 추출할 겁니다.

이때, 독립 표본 t-검정은 두 집단의 평균이 통계적으로 유의미하게 다른지를 검정하는 방법이다. p-value를 통해서는 성별에 따른 수학 점수 차이의 유의성을 판단할 수 있습니다.

 

ttest_ind

ttest_ind(a, b, *, axis=0, equal_var=True, nan_policy='propagate', permutations=None, random_state=None, alternative='two-sided', trim=0, method=None, keepdims=False)

# 남성의 수학점수 df[df['gender'] == 'Male']['math_score']
# 여성의 수학점수 df[df['gender'] == 'Female']['math_score']

male_scores = df[df['gender'] == 'Male']['math_score']
female_scores = df[df['gender'] == 'Female']['math_score']

t_stat, p_value = ttest_ind(male_scores, female_scores)
print(f"📌 t-statistic: {t_stat:.2f}")
print(f"📌 p-value: {p_value:.4f}")

 

이변량 분석 3 : 범주형 - 범주형 변수 분석하기

교차표를 사용하는 이유는?

- 성별과 구매 여부는 모두 범주형 변수입니다.

- 이 경우 각 범주의 빈도수 분포를 확인하는 것이 우선입니다.

- 교차표(crosstab 또는 contingency table)는 두 범주형 변수의 조합별로 몇 명이 해당하는지를 표로 보여주는 것입니다.

 

카이제곱 검정이란?

- 두 범주형 변수 간에 통계적으로 연관성이 있는지 확인하는 방법입니다.

- "성별과 구매 여부는 독립적이다."라는 가정 (귀무가설)을 세우고, 실제 데이터가 가정과 얼마나 다른지를 검정합니다.

- 귀무가설(H0) : 성별과 구매 여부는 관련이 없다.

- 대립가설(H1) : 성별과 구매 여부는 관련이 있다.

 

import pandas as pd

data = {
    'gender': ['Male', 'Female', 'Male', 'Female', 'Male', 'Female', 'Male', 'Female', 'Male', 'Female'],
    'purchased': ['Yes', 'Yes', 'No', 'Yes', 'No', 'Yes', 'No', 'Yes', 'No', 'No']
}

df = pd.DataFrame(data)

import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import chi2_contingency

# 1. 교차표 생성 및 시각화
# gender purchased
# 교차표 : pd.crosstab()

cross_tab = pd.crosstab(df['gender'], df['purchased'])

sns.heatmap(cross_tab, annot=True, fmt='d', cmap='Blues')
plt.title('Gender vs Purchased (Counts)')
plt.show()

 

scipy.stats.chi2_contingency를 이용해 카이제곱 독립성 검정을 수행하시오.

카이제곱 독립성 검정은 두 범주형 변수 간에 연관성이 있는지를 판단하는 통계 기법입니다.

 

chi2_contingency

chi2_contingency(observed, correction=True, lambda_=None, *, method=None)

# 2. 카이제곱 검정
chi2, p, dof, expected = chi2_contingency(cross_tab)
print(f"📌 Chi-square statistic: {chi2:.2f}")
print(f"📌 p-value: {p:.4f}")