기술통계로 데이터 분포를 읽는 방법
평균·중앙값·최빈값과 분산·표준편차, 왜도·첨도로 데이터 분포를 요약하고 이상 변화를 진단하는 기술통계 분석 체계
2026-08-14 · 최초 발행 2025-10-14
분포를 요약할 때 함께 봐야 할 지표
기술통계는 원천 데이터를 의사결정에 연결할 수 있는 분포 정보로 압축한다. 평균·중앙값·최빈값은 중심을, 분산·표준편차는 변동성을, 왜도·첨도는 분포의 모양을 보여 준다. 탐색적 데이터 분석(EDA), 모니터링, 모델링 전처리에서는 이 지표를 같은 절차로 산출하고 해석할 기준이 필요하다.
평균(mean)은 가법적 특성을 가진 중심값이다. 중앙값(median)은 순서에 기반하며 이상치에 강건하고, 최빈값(mode)은 범주형·이산형 데이터에 적합하다.
산포는 평균 주변의 변동을 설명한다. 분산(variance)은 제곱 단위를 사용하고 표준편차(standard deviation)는 원 단위로 해석한다. 사분위수 범위(IQR)는 이상치에 강건한 산포 지표다.
왜도(skewness)는 분포의 비대칭성을, 첨도(kurtosis)는 꼬리의 두터움과 피크 정도를 나타낸다. 통상 Fisher 정의를 사용하며, 초과첨도(excess kurtosis)는 정규분포를 기준으로 0이다. 두 지표는 무차원이며 스케일 변화에 불변이다.
표본분산에는 불편추정량인 ddof=1의 Bessel 보정을 권장한다. 왜도와 첨도는 표본 크기에 민감하므로 n<200 구간에서는 불확실성이 커진다.
지표 선택은 데이터 상태에서 시작한다
결측치는 제외·대체·모형화 중 어떤 전략으로 다룰지 정해야 한다. 이상치 역시 IQR, MAD, 도메인 규칙 등 탐지 기준을 먼저 정한다. 그다음 연속형·이산형·범주형을 구분하고 단위와 스케일을 맞춰야 지표 간 비교가 가능하다.
중심경향은 평균과 중앙값을 함께 보고, 산포는 표준편차와 IQR로 보완하는 방식이 유용하다. 평균과 분산은 이상치에 민감한 반면, 중앙값·IQR·MAD는 강건 지표다. 어느 한쪽만 선택하기보다 이 차이를 보고에 드러내야 한다.
운영 환경에서는 롤링 윈도우로 지표를 계산하고 임계값 및 변동성과 비교해 변화 신호를 찾는다. 리포트에는 지표, 단위, 표본 크기, CI를 같은 형식으로 남겨 품질 관리 대상으로 삼는다.
지표별 해석과 사용 맥락
| 지표 | 해석 | 이상치 민감도 | 권장 상황 |
|---|---|---|---|
| 평균 | 가중 중심값 | 높음 | 대수적 결합, 정규분포 근사, 샘플 충분 |
| 중앙값 | 50% 위치 | 낮음 | 꼬리 두터움, 이상치 다수, 순위 중요 |
| 최빈값 | 최빈 범주 | 중간 | 범주형·이산형, 다봉 분포 탐지 |
| 분산 | 평균 제곱변동 | 매우 높음 | 분산분해, ANOVA, 모형 가정 검토 |
| 표준편차 | 평균 기준 변동폭 | 높음 | 스케일 해석, 공정 변동 관리 |
| 왜도 | 비대칭성 | 중간 | 편향 방향·정도 파악, 변환 필요성 판단 |
| 첨도 | 꼬리 두터움 | 중간 | 극단값 리스크, 이상치 발생성 평가 |
데이터에서 모니터링까지 이어지는 흐름
지표가 쓰이는 운영 장면
API 지연시간 모니터링에서는 중앙값·P95·왜도를 함께 추적해 꼬리 지연을 관리한다. 스케일이 바뀌는 상황에서는 표준편차보다 IQR이 안정적인 지표가 될 수 있다.
제조 공정에서는 X-bar/R 관점에서 평균과 표준편차를 추적하고, 첨도로 두터운 꼬리 신호를 포착한다. IQR·MAD 기반 이상치 규칙은 샘플링과 교정 의사결정을 지원한다.
금융 리스크 요약에서는 수익률의 분산·표준편차와 초과첨도로 테일 리스크를 진단한다. 왜도 변화는 비대칭 리스크의 사전 탐지 신호가 된다.
강건 지표와 이상치 민감 지표를 병행하면 알람 오검출률을 20~40% 감소시킬 수 있다. 롤링 통계 기반 조기경보는 이상 이벤트 탐지 지연을 30% 이상 단축할 수 있다. 해석 기준을 표준화하면 팀 간 판단의 일관성이 높아지고, 왜도·첨도 가시화는 데이터 품질 회복력을 강화한다.
Python으로 계산하는 기술통계
전제조건: Python 3.10+, numpy>=1.23, pandas>=1.5, scipy>=1.10
import numpy as np
import pandas as pd
from scipy import stats
# 예시 데이터
np.random.seed(42)
x = np.r_[np.random.normal(100, 15, 500), [250, 300]] # 이상치 2개
s = pd.Series(x)
# 중심경향
mean = s.mean()
median = s.median()
mode = s.mode().iloc[0] if not s.mode().empty else np.nan
# 산포
var = s.var(ddof=1) # 표본분산(Bessel 보정)
std = s.std(ddof=1)
iqr = stats.iqr(s, rng=(25, 75))
mad = stats.median_abs_deviation(s, scale='normal') # 정규화(MAD*1.4826)
# 형태
skew = stats.skew(s, bias=False) # 표본 보정
kurt_excess = stats.kurtosis(s, fisher=True, bias=False)
# 강건 대안
trimmed_mean = stats.trim_mean(s, 0.1) # 10% 절사평균
# 부트스트랩 CI (예: 평균 95% CI)
rng = np.random.default_rng(123)
def bootstrap_ci(a, stat_fn=np.mean, B=5000, alpha=0.05):
n = len(a)
idx = rng.integers(0, n, size=(B, n))
sims = stat_fn(a[idx], axis=1)
lo, hi = np.quantile(sims, [alpha/2, 1-alpha/2])
return lo, hi
mean_lo, mean_hi = bootstrap_ci(s.values)
print({
"mean": mean, "median": median, "mode": mode,
"var": var, "std": std, "IQR": iqr, "MAD": mad,
"skew": skew, "kurt_excess": kurt_excess,
"trimmed_mean": trimmed_mean,
"mean_CI": (mean_lo, mean_hi),
})
리포트에는 n, 결측 수, 평균·중앙값, 표준편차·IQR, 왜도·첨도, 95% CI, 강건 지표를 함께 기록한다. 경계값은 과거 4~8주 기준선에서 z-스코어 또는 IQR 규칙(1.5·IQR)으로 설계하고, 비정상 신호가 나타나면 구간·세그먼트·피처 단위로 근본원인을 분해한다.