본문 바로가기
분석/파이썬 Python

Python : 순열검정 (비모수)

by 여우요원 2024. 1. 27.

 

두 집단의 평균을 비교하는 방법에는 크게는 모수적 방법과 비모수적 방법이 있다.

여기서 모수적 방법이란 모집단이 정규분포를 한다는 가정하에, 평균과 분산같은 통계량을 이용하여 계산되는 방식이며

비모수적 방법이란 모집단의 분포와 관계없이 계산하는 방식을 말한다.

 

아래에 python sample code 를 소개하고자 한다.

 

Colab에서 실행된 결과는 아래의 링크에서도 확인할 수 있다.

https://colab.research.google.com/drive/1GOBBNP13if2PotGpUXgwiqcVQR8JjbmZ#scrollTo=uhPCOt8ii7YJ


# -*- coding: utf-8 -*-
"""Permutation Test.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1GOBBNP13if2PotGpUXgwiqcVQR8JjbmZ

# 평균비교 순열검정과 T-test
"""

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

"""## 데이터 읽기"""

## 웹페이지의 로딩 시간

file_url = 'https://raw.githubusercontent.com/gedeck/practical-statistics-for-data-scientists/master/data/web_page_data.csv'
data = pd.read_csv(file_url)
data

"""### 각 Page의 분포 시각화"""

## 박스플롯

ax = sns.boxplot(data=data, x='Page', y='Time')
ax.set_title('Box Plot')
plt.show()

"""### 데이터의 평균 비교"""

mean_a = data['Time'][data['Page'] == 'Page A'].mean()
mean_b = data['Time'][data['Page'] == 'Page B'].mean()

print('A 평균 = {0:.3f}, B 평균 = {1:.3f}'.format(mean_a, mean_b))
print('B - A 평균차이 : {:.3f}'.format(mean_b - mean_a))

"""## 순열검정을 사용한 비교"""

import random
def perm_fun(x, nA, nB):
    n = nA + nB
    idx_B = set(random.sample(range(n), nB))
    idx_A = set(range(n)) - idx_B
    return x.loc[list(idx_B)].mean() - x.loc[list(idx_A)].mean()

nA = data[data['Page'] == 'Page A'].shape[0]
nB = data[data['Page'] == 'Page B'].shape[0]
print(nA, nB)

perm_fun(data['Time'], nA, nB)

## 1000 번의 차이값을 반복게산

diff_perm = [perm_fun(data['Time'], nA, nB) for _ in range(1000)]

fig, ax = plt.subplots(figsize=(5,5))
ax.hist(diff_perm, bins=11, rwidth=0.9)
ax.axvline(x=mean_b - mean_a, color='black', lw=2)
ax.text(50, 190, "observed\ndifference", bbox={"facecolor":"white"})
ax.set_xlabel("Session time differences (in second)")
ax.set_ylabel("Freequency")
plt.show()

## 실험에서의 차이가 반복된 분포에서의 확률

np.mean(diff_perm > mean_b - mean_a)

"""## T-Test 와 비교 (단측검정)"""

from scipy import stats

result = stats.ttest_ind(
    data[data.Page == "Page A"].Time,
    data[data.Page == "Page B"].Time,
    equal_var=False,
)
print(f"p-value for single sided test: {result.pvalue / 2:.4f}")