0Pricing
Pandas & NumPy Academy · 강의

기술 통계와 정규성 검정

scipy.stats로 왜도와 첨도를 계산하고, 정규성을 확인하는 샤피로-윌크 검정을 실행한 뒤 p값을 해석합니다.

기술 통계와 정규성 검정은(는) CoddyKit의 무료 Pandas & NumPy Academy 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Pandas & NumPy Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Pandas & NumPy Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

기술 통계와 추론 통계 비교

기술 통계는 데이터에 무엇이 들어 있는지 요약합니다. 평균, 중앙값, 표준 편차, 왜도 등이 이에 해당합니다. 추론 통계는 표본을 바탕으로 모집단에 대한 주장을 합니다. 가설 검정, 신뢰 구간, p값 등이 이에 해당합니다. SciPy의 scipy.stats 모듈은 이 두 영역을 연결하여 Pandas의 describe()를 넘어서는 기술 측정값과 고전적 가설 검정의 전체 모음을 모두 제공합니다. 데이터 조작에는 Pandas를 사용하고 통계 검정에는 SciPy를 사용하는 것이 표준 Python 데이터 과학 작업 흐름입니다.

확장된 기술 통계

Pandas의 describe()는 개수, 평균, std, 최솟값/최댓값, 사분위수를 제공합니다. scipy.stats는 분포의 왜도(분포의 비대칭성)와 첨도(꼬리의 두꺼운 정도)를 추가합니다. 왜도가 0이면 대칭이고, 양의 왜도는 오른쪽 꼬리가 더 긴 분포를 의미합니다(작은 값이 많고 매우 큰 값은 적음). 첨도가 3(초과 첨도 형식에서는 0)이면 정규 분포이며, 값이 클수록 정규 분포보다 극단적인 이상치가 많은 두꺼운 꼬리를 나타냅니다.

import pandas as pd
from scipy import stats
import numpy as np

np.random.seed(0)
data = np.concatenate([
    np.random.exponential(scale=2, size=500),  # right-skewed
    np.random.normal(loc=5, scale=1, size=500)
])

print('Mean:', round(data.mean(), 3))
print('Std:', round(data.std(), 3))
print('Skewness:', round(stats.skew(data), 3))
print('Kurtosis (excess):', round(stats.kurtosis(data), 3))

왜도 이해하기

왜도는 통계 검정과 변환을 선택할 때 중요합니다. 오른쪽으로 치우친(양의 왜도) 분포에서는 평균이 중앙값보다 큽니다. 소득 데이터, 반응 시간, 판매 금액에서 흔히 나타납니다. 왼쪽으로 치우친(음의 왜도) 분포에서는 평균이 중앙값보다 작습니다. 일반적인 기준은 다음과 같습니다. |왜도| < 0.5이면 대략 대칭이고, 0.5~1.0이면 중간 정도로 치우쳤으며, > 1.0이면 크게 치우친 상태입니다. 정규성을 가정하는 검정을 적용하기 전에 로그 또는 제곱근 변환을 적용하면 도움이 될 수 있습니다.

import numpy as np
from scipy import stats

# Right-skewed: income-like data
right_skewed = np.random.lognormal(mean=1, sigma=1, size=1000)
print('Right skew:', round(stats.skew(right_skewed), 3))

# After log transform
print('After log transform:', round(stats.skew(np.log(right_skewed)), 3))

# Symmetric normal
normal_data = np.random.normal(0, 1, 1000)
print('Normal skew:', round(stats.skew(normal_data), 3))

정규성 검정이 중요한 이유

많은 통계 검정(t-검정, ANOVA, Pearson 상관)은 데이터 또는 잔차가 정규(가우스) 분포를 따른다고 가정합니다. 작은 표본에서 이 가정을 위반하면 검정의 p값이 부정확할 수 있습니다. 정규성 검정은 이 가정이 성립하는지 확인합니다. 큰 표본(n > 100)에서는 정규성 검정이 매우 민감해져 사소한 편차에도 거의 항상 정규성을 기각합니다. 이 경우 원시 데이터를 검정하기보다 중심 극한 정리(표본 평균은 대략 정규 분포를 따름)에 의존하십시오.

Shapiro-Wilk 검정

Shapiro-Wilk 검정(scipy.stats.shapiro(data))은 약 5,000개까지의 표본 크기에서 가장 강력한 정규성 검정입니다. W 통계량과 p값을 반환합니다. p > 0.05이면 정규성을 기각하지 못한 것으로, 데이터가 정규 분포와 일치한다는 의미입니다. p ≤ 0.05이면 정규성을 기각합니다. 정규성을 기각하지 못했다고 해서 데이터가 정규 분포라는 것이 증명되는 것은 아닙니다. 단지 정규 분포가 아니라고 말할 충분한 증거가 없다는 뜻입니다.

import numpy as np
from scipy import stats

np.random.seed(42)

# Normal data
normal = np.random.normal(0, 1, 100)
stat, p = stats.shapiro(normal)
print(f'Normal data: W={stat:.4f}, p={p:.4f}')
print('Conclusion:', 'Looks normal' if p > 0.05 else 'Not normal')

# Skewed data
skewed = np.random.exponential(1, 100)
stat2, p2 = stats.shapiro(skewed)
print(f'Skewed data: W={stat2:.4f}, p={p2:.4f}')
print('Conclusion:', 'Looks normal' if p2 > 0.05 else 'Not normal')

Kolmogorov-Smirnov 검정

Kolmogorov-Smirnov(K-S) 검정(scipy.stats.kstest(data, 'norm', args))은 표본이 지정된 분포를 따르는지 검정합니다. Shapiro-Wilk와 달리 정규 분포뿐 아니라 모든 분포에 사용할 수 있으며, 큰 표본에도 적합합니다. 데이터의 경험적 CDF와 이론적 CDF 사이의 최대 차이를 계산합니다. 변형된 검정인 두 표본 K-S 검정(stats.ks_2samp(a, b))은 두 표본이 같은 분포에서 나온 것인지 검정하며, 전후 분포를 비교할 때 유용합니다.

import numpy as np
from scipy import stats

np.random.seed(0)
data = np.random.normal(loc=5, scale=2, size=200)

# One-sample K-S test against N(5, 2) distribution
stat, p = stats.kstest(data, 'norm', args=(5, 2))
print(f'K-S test: stat={stat:.4f}, p={p:.4f}')
print('Follows N(5,2)?', 'Yes' if p > 0.05 else 'No')

# Two-sample K-S test
data2 = np.random.normal(loc=5.5, scale=2, size=200)
stat2, p2 = stats.ks_2samp(data, data2)
print(f'Two-sample K-S: stat={stat2:.4f}, p={p2:.4f}')

시각적 정규성 확인: QQ 플롯

Q-Q(분위수-분위수) 플롯은 시각적으로 정규성을 확인하는 방법입니다. 데이터의 분위수를 정규 분포의 분위수에 대응하여 표시합니다. 데이터가 정규 분포라면 점들이 대각선 직선 위에 놓입니다. 직선에서 벗어나는 정도는 정규성에서 벗어났음을 나타냅니다. S자 곡선은 첨도를, 굽은 형태는 왜도를 나타냅니다. 통계 검정은 편차가 유의한지 알려 주고, Q-Q 플롯은 편차의 성격과 위치를 보여 줍니다. scipy.stats.probplot()을 사용하여 Q-Q 플롯 데이터를 생성하십시오.

import numpy as np
from scipy import stats
import matplotlib.pyplot as plt

np.random.seed(1)
data = np.random.exponential(2, 200)

# Q-Q plot
(osm, osr), (slope, intercept, r) = stats.probplot(data, dist='norm')
print(f'R-squared of Q-Q fit: {r**2:.4f}')  # Close to 1 = normal
# Visual inspection: if plotting, points on the line = normal
# plt.figure()
# stats.probplot(data, dist='norm', plot=plt)
# plt.show()

실전에서의 중심 극한 정리

중심 극한 정리(CLT)는 기저 분포와 관계없이 표본 크기가 커지면 표본 평균의 분포가 정규성에 가까워진다는 정리입니다. n ≥ 30이면 개별 관측값이 치우쳐 있더라도 표본 평균은 대략 정규 분포를 따릅니다. 이것이 큰 표본에서 t-검정이 강건한 이유입니다. 검정하는 것은 평균의 차이이고, 원시 데이터가 정규 분포가 아니더라도 평균은 대략 정규 분포를 따르기 때문입니다. 비정규 모집단에서 추출한 작은 표본에는 대신 비모수 검정을 사용하십시오.

import numpy as np
from scipy import stats

np.random.seed(0)
# Population: heavily right-skewed (exponential)
population = np.random.exponential(scale=1, size=10000)
print('Population skewness:', round(stats.skew(population), 3))

# Sample means are approximately normal (CLT)
sample_means = [np.random.choice(population, 50).mean()
                for _ in range(1000)]
print('Sample means skewness:', round(stats.skew(sample_means), 3))
_, p = stats.shapiro(sample_means)
print('Shapiro p-value for means:', round(p, 4))

그룹별 정규성

그룹 비교 검정(t-검정, ANOVA)에서는 전체 데이터가 아니라 각 그룹 내에서 정규성이 필요합니다. 지역별 판매량의 차이를 검정할 때는 각 지역의 판매량이 정규성을 따르는지 별도로 검정하십시오. 전체적으로 정규 분포가 아닌 데이터도 하위 그룹 내에서는 정규성을 만족할 수 있습니다. Pandas의 groupby()를 사용하여 각 그룹에 stats.shapiro()를 적용하고 그룹을 순회하면서 가정을 체계적으로 확인하십시오.

import pandas as pd
import numpy as np
from scipy import stats

np.random.seed(0)
df = pd.DataFrame({
    'region': ['N']*50 + ['S']*50 + ['E']*50,
    'sales': np.concatenate([
        np.random.normal(100, 20, 50),
        np.random.normal(110, 25, 50),
        np.random.normal(95, 15, 50)
    ])
})

for region, group in df.groupby('region'):
    stat, p = stats.shapiro(group['sales'])
    print(f'Region {region}: W={stat:.4f}, p={p:.4f} -> '
          f'{"Normal" if p>0.05 else "Not normal"}')

비모수 대안

정규성을 위반할 때는 비모수 검정을 사용하십시오. 비모수 검정은 분포에 대한 가정을 하지 않습니다. Mann-Whitney U 검정(stats.mannwhitneyu)은 독립 t-검정을 대체하고, Wilcoxon 부호 순위 검정(stats.wilcoxon)은 대응 t-검정을 대체하며, Kruskal-Wallis 검정(stats.kruskal)은 일원 ANOVA를 대체합니다. 이러한 검정은 원시 값 대신 순위를 사용하므로 이상치에 강건하지만, 실제로 정규성이 성립할 때는 모수 검정보다 통계적 검정력이 낮습니다.

import numpy as np
from scipy import stats

np.random.seed(0)
# Non-normal data
group_a = np.random.exponential(2, 40)
group_b = np.random.exponential(2.5, 40)

# Parametric would be wrong here; use non-parametric
stat, p = stats.mannwhitneyu(group_a, group_b, alternative='two-sided')
print(f'Mann-Whitney U test: U={stat:.1f}, p={p:.4f}')
print('Groups differ?' , 'Yes' if p < 0.05 else 'No')

여러 열의 통계 요약

EDA에서는 모든 수치 열의 정규성과 왜도를 한 번에 확인해야 하는 경우가 많습니다. Pandas의 select_dtypes를 열을 순회하는 반복문과 결합하고, 각 열에 stats.shapiro()와 stats.skew()를 호출하십시오. 왜도, 첨도, Shapiro p값을 열로 갖는 요약 DataFrame을 만들면 어떤 열이 비정규이고 모델링 전에 변환이 필요한지 한눈에 파악할 수 있습니다. 이는 체계적인 데이터 품질 점검 목록의 일부입니다.

import pandas as pd
import numpy as np
from scipy import stats

np.random.seed(0)
df = pd.DataFrame({
    'age': np.random.normal(35, 10, 200),
    'income': np.random.lognormal(10, 1, 200),
    'score': np.random.uniform(0, 100, 200)
})

rows = []
for col in df.select_dtypes(include='number').columns:
    s = stats.skew(df[col])
    _, p = stats.shapiro(df[col][:200])
    rows.append({'column': col, 'skewness': round(s, 3),
                 'shapiro_p': round(p, 4), 'normal': p > 0.05})

print(pd.DataFrame(rows).to_string(index=False))

빠른 확인

이 수업에서 배운 데이터 분석 개념을 제대로 이해했는지 확인해 보십시오.

수업 요약

이 수업에서는 다음을 배웠습니다. scipy.stats.skew()와 kurtosis()는 describe()가 제공하는 정보보다 더 자세하게 분포의 형태를 설명합니다. scipy.stats.shapiro()는 정규성을 검정하며 p > 0.05는 정규성에 반하는 증거가 없음을 의미합니다. 또한 중심 극한 정리는 비정규 데이터라도 큰 표본에서 t-검정을 강건하게 만듭니다. 다음으로 t-검정을 사용한 가설 검정을 적용하여 그룹 평균을 비교하겠습니다.

자주 묻는 질문

“기술 통계와 정규성 검정” 강의는 무료인가요?

네 — “기술 통계와 정규성 검정” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Pandas & NumPy Academy 강의 전체를 잠금 해제할 수 있습니다. Pandas & NumPy Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“기술 통계와 정규성 검정”에서 뭘 배우나요?

scipy.stats로 왜도와 첨도를 계산하고, 정규성을 확인하는 샤피로-윌크 검정을 실행한 뒤 p값을 해석합니다. 브라우저에서 직접 실행하는 실습 코드로 Pandas & NumPy Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Pandas & NumPy Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Pandas & NumPy Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.

“기술 통계와 정규성 검정” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Pandas & NumPy Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Pandas & NumPy Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 기술 통계와 정규성 검정
  2. 평균 비교를 위한 t 검정
  3. 독립성에 대한 카이제곱 검정
  4. ANOVA와 사후 검정
← Pandas & NumPy Academy(으)로 돌아가기