파이썬 통계분석하기

Python
T-test
F-test
Statistics
Author

Taeyoon Kim

Published

September 17, 2023

Modified

June 30, 2025

1 왜 파이썬으로 통계분석을 하나요?

통계 계산을 위한 프로그래밍 언어에 R 프로그래밍 언어가 있는데 왜 파이썬을 써야 할까요? R은 문법 자체부터 통계에 특화되어 있고 여러가지 통계분석을 할 수 있습니다. 그럼에도 불구하고 제가 파이썬을 통계분석에 사용하는 이유는 간단합니다. 파이썬은 보다 범용적인 언어이고 라이브러리가 풍부해서 제가 원하는 기능은 거의 이미 다 있기 때문이죠.

1.1 예를 들어봅시다.

여기 brain_size 라는 데이터를 살펴 보겠습니다.

# 필요한 라이브러리를 불러옵니다.
%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd

1.2 CSV 파일 읽어오기

brain_size 데이터는 Willerman이 1991년에 사람의 뇌 크기와 무게, 그리고 IQ에 대하여 측정한 값입니다. 범주형의 데이터와 수치형 데이터로 구성 되어 있죠.

Pandas의 read_csv 기능을 이용해 데이터프레임을 만들어 보겠습니다.

df = pd.read_csv(
    "http://www.scipy-lectures.org/_downloads/brain_size.csv",
    sep=";",
    index_col=0,
    na_values=".",
)
df.head()  # 상단의 5개의 데이터 확인하기

간단히 살펴보면, 총 40명의 사람들의 성별, IQ, 몸무게, 키 그리고 MRI_count(total pixel Count from the 18 MRI scans) 값이 측정되어 있습니다. IQ의 경우 3종류로 세분화 되어있는데 각각을 알아 보면 아래와 같습니다.

  • Full Scale Intelligence Quotient (FSIQ) : VIQ와 PIQ의 종합적인 수치입니다
  • Verbal IQ (VIQ) : 언어적인 측면을 측정합니다.
  • Performance IQ (PIQ) : 논리, 계산적인 측면을 측정

1.3 Pandas 설명통계

pandas에서는 간단하게 평균값과 표준편차등을 계산해주는 기능이 있습니다.

describe() 함수를 사용하면 모든 열에 대한 설명통계값을 보여줍니다.

# padas 에서 제공하는 설명 통계
df.describe()

IQ의 평균값은 113이군요. 몸무게는 kg으로 변환하면 약 70kg쯤 됩니다.

1.4 산포 행렬을 그려보겠습니다.

전체적인 데이터의 양상을 보기에는 시각화가 중요합니다. 파이썬에서는 간단하게 산포 행렬(sactter matrix)를 그려 볼 수 있습니다.

먼저 키와 몸무게, MRI_count 간의 상관관계를 보겠습니다.

# Plotting data
from pandas.plotting import scatter_matrix

# 키와 몸무게, MRI_count
scatter_matrix(df[["Weight", "Height", "MRI_Count"]])

키와 몸무계는 서로 연관이 있는듯 하고 나머지는 그다지 서로 연관이 없어 보입니다.

그 다음으로는 여러 IQ 수치간에 상관관계를 알아 보죠.

scatter_matrix(df[["PIQ", "VIQ", "FSIQ"]])

당연하지만, FSIQ는 VIQ, PIQ 각각과 연관성이 있어 보입니다. VIQ와 PIQ간에는 애매하게 연관성이 없어 보이네요. FSIQ의 히스토그램에서는 100 - 125 사이에는 데이터가 없는 것을 확인 할 수 있습니다.

2 가설 검정: 두 그룹간의 비교

T-test 는 두 그룹간의 평균의 차이가 통계적으로 의미가 있는지를 알아볼때 사용됩니다.T-test에는 다음과 같이 세 종류가 있습니다.

  1. 1-sample T-test
  2. 2-sample T-test
  3. paired T-test

여기서는 간단한 가설 검정 방법으로 scipyscipy.stats 라이브러리를 사용해, 1-sample, 2-sample T-test를 해보겠습니다.

각각의 T-test는 사용되는 경우가 다르기에 주의 해야 합니다.

2.1 1-sample T-test

하나의 집단의 평균이 특정 기준보다 유의미하게 다른지 를 알아보는 분석 방법입니다. Student T-test이라고도 하는 1-sample T-test 를 사용하려면 scipy.stats.ttest_1samp() 함수를 사용하면 됩니다.

from scipy import stats
## Student’s t-test: the simplest statistical test
stats.ttest_1samp(df["VIQ"], 0)
# VIQ의 평균값이 0과 통계적으로 유의미하게 다른지 알아 보겠습니다.

간단하게 결론만 말하자면, p-value가 아주 낮음(10의 -28제곱) 으로 VIQ의 평균은 0이 아니라고 말할 수 있습니다.

2.2 2-sample t-test

서로 다른 두개의 그룹 간 평균의 차이가 유의미 한지 여부를 판단하기 위해 시행합니다. 2-sample t-test 는 scipy.stats.ttest_ind(): 함수를 사용합니다.

예를 들어 여자의 VIQ와 남자의 VIQ의 평균은 통계적으로 차이가 있는지 알아 보겠습니다.

# 여자의 VIQ
female_viq = df[df["Gender"] == "Female"]["VIQ"]
# 남자의 VIQ
male_viq = df[df["Gender"] == "Male"]["VIQ"]
# 두개의 리스트를 가지고 t-test실행
stats.ttest_ind(female_viq, male_viq)

p-value가 0.44로 아주 높게 나왔습니다. 따라서 기무가설이었던 남자와 여자의 VIQ 평균에는 차이가 있다. 는 기각되고 차이가 없다 라고 결론을 낼 수 있습니다.

2.3 Paired tests:

Paired t-test는 동일한 집단에서의 반복적인 측정에 의한 차이를 비교하기 위해 사용됩니다. 예를 들면 커피가 수면시간에 미치는 영향을 보기 위해 커피를 마시지 않고 측정하고 커피를 마시고 측정한 데이터를 수집하여 사용합니다. > 전제조건을 충족하기 위해서는 실험이 길어지는 단점이 있습니다

3 brain_size 데이터의 T-test

주어진 brain_size 데이터에서 3가지 IQ수치 PIQ, VIQ, FSIQ가 제공 되고 있는데, FSIQ 평균 값과 PIQ 평균이 통계적으로 차이가 있는지 알아 보도록 하겠습니다. 이를 위해서 2-sample T-test를 수행하겠습니다.

먼저, 전체적인 데이터의 모습을 알기 위한 boxplot을 그려보겠습니다.

# Box plots of different columns for each gender
groupby_gender = df.groupby("Gender")
groupby_gender.boxplot(column=["FSIQ", "VIQ", "PIQ"])
# 2-sample t-test
stats.ttest_ind(df["FSIQ"], df["PIQ"])

T-test 결과 p-value가 0.64로 매우 높기 때문에 기무가설을 기각하지 못합니다. 따라서, FSIQ와 PIQ값에 통계적으로 유의적인 차이는 없다고 볼 수 있습니다.

여기서 한가지 문제 점이 있는데, 각각의 FSIQ와 PIQ값은 같은 개인에서 측정되었기 때문에, paried T-test 으로 추가적인 확인이 필요합니다.

stats.ttest_rel(df["FSIQ"], df["PIQ"])
# This is equivalent to a 1-sample test on the difference:
# stats.ttest_1samp(df['FSIQ'] - df['PIQ'], 0)

Paired T-test결과에서도 p-value 값이 0.05 이상임으로 통계적으로 유의미한 차이가 없다고 볼 수 있습니다.

4 성별과 VIQ 수치의 관계

남성과 여성이 VIQ 차이가 있는지를 판단하기 위해서는 뇌의 크기, 키, 몸무게에 의한 영향을 배제해야 합니다. 이를 위해서는 statsmodels 라이브러리에서 제공하는 ols(ordinary least squares)모델을 사용하겠습니다. 그런 다음 F-test을 통해 통계적 유의성을 보겠습니다.

4.1 F-test

F-test는 두 표본의 분산에 대한 차이가 통계적으로 유의한가를 판별하는 검정기법입니다. 다른 이름으로 var-test로도 불립니다.

from statsmodels.formula.api import ols

model = ols("VIQ ~ Gender + MRI_Count + Height", df).fit()
print(model.summary())
print(model.f_test([0, 1, 0, 0]))

F test 결과, p-value 가 0.41로 아주 높게 나왔습니다. 따라서 기무가설을 기각하지 못합니다. 다시 말해 성별에 의한 VIQ 차이는 없다 라고 할 수 있습니다.

4.2 시각화

시각화를 하면 통계분석에 사용된 변수간의 상관관계를 손쉽게 확인할 수 있습니다. 아래 코드는 scatter_matrix를 그리는 방법입니다.

# This plotting is useful to get an intuitions on the relationships between
# our different variables

# Fill in the missing values for Height for plotting
df["Height"].fillna(method="pad", inplace=True)

# The parameter 'c' is passed to plt.scatter and will control the color
# The same holds for parameters 'marker', 'alpha' and 'cmap', that
# control respectively the type of marker used, their transparency and
# the colormap
scatter_matrix(
    df[["VIQ", "MRI_Count", "Height"]],
    c=(df["Gender"] == "Female"),
    marker="o",
    alpha=0.7,
)

fig = plt.gcf()
fig.suptitle("purple: male, yellow: female", size=13)

plt.show()

5 결론

시각화와 F-test 결과를 통해 성별은 VIQ값에 아무런 상관관계를 가지고 있지 않다는 것을 확인 할 수 있었습니다.