Skip to main content

Matplotlib 분포 시각화

데이터의 분포를 파악하는 것은 EDA의 첫 단계입니다. 히스토그램으로 전체적인 분포 형태를 확인하고, 박스플롯으로 이상치와 사분위수를 파악합니다.

학습 목표

  • 히스토그램으로 수치형 데이터의 분포를 시각화할 수 있다
  • 박스플롯으로 사분위수, 이상치를 확인할 수 있다
  • 바이올린 플롯으로 분포의 밀도를 시각화할 수 있다
  • bin 크기가 시각화 해석에 미치는 영향을 이해한다

왜 중요한가

피처의 분포 형태(정규분포, 편향, 다봉 등)는 전처리 전략에 직접적인 영향을 미칩니다. 정규분포에 가까운 피처는 StandardScaler, 편향된 피처는 로그 변환이나 RobustScaler가 적합합니다.

히스토그램

import matplotlib.pyplot as plt
import numpy as np

np.random.seed(42)
data = np.random.normal(170, 10, 1000)  # 키 데이터

fig, axes = plt.subplots(1, 3, figsize=(15, 4))

# bin 수에 따른 차이
for ax, bins in zip(axes, [10, 30, 100]):
    ax.hist(data, bins=bins, color='#4a9eca', edgecolor='white', alpha=0.8)
    ax.set_title(f'bins={bins}')
    ax.set_xlabel('키 (cm)')
    ax.set_ylabel('빈도')

plt.suptitle('히스토그램 — bin 크기의 영향', fontsize=14)
plt.tight_layout()
plt.show()
# 밀도 히스토그램 + KDE 곡선
fig, ax = plt.subplots(figsize=(8, 5))
ax.hist(data, bins=30, density=True, color='#4a9eca', edgecolor='white', alpha=0.7, label='히스토그램')

# KDE 곡선 추가
from scipy import stats
x_range = np.linspace(data.min(), data.max(), 100)
kde = stats.gaussian_kde(data)
ax.plot(x_range, kde(x_range), color='#e6a23c', linewidth=2, label='KDE')

ax.set_title('키 분포 (밀도)')
ax.legend()
plt.tight_layout()
plt.show()

박스플롯

np.random.seed(42)
groups = {
    '개발': np.random.normal(5000, 800, 50),
    '영업': np.random.normal(4500, 600, 50),
    '마케팅': np.random.normal(4200, 500, 50),
}

fig, ax = plt.subplots(figsize=(8, 5))
bp = ax.boxplot(groups.values(), labels=groups.keys(),
                patch_artist=True, showmeans=True,
                meanprops={'marker': 'D', 'markerfacecolor': '#e6a23c'})

# 색상 설정
colors = ['#4a9eca', '#4a9e4a', '#e6a23c']
for patch, color in zip(bp['boxes'], colors):
    patch.set_facecolor(color)
    patch.set_alpha(0.6)

ax.set_title('부서별 연봉 분포')
ax.set_ylabel('연봉 (만원)')
ax.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.show()
박스플롯에서 상자는 Q1~Q3(IQR), 중앙선은 중앙값, 다이아몬드는 평균, 수염은 1.5 * IQR 범위, 점은 이상치를 나타냅니다.

바이올린 플롯

fig, ax = plt.subplots(figsize=(8, 5))

data_list = [groups['개발'], groups['영업'], groups['마케팅']]
vp = ax.violinplot(data_list, showmeans=True, showmedians=True)

# 색상 설정
for i, body in enumerate(vp['bodies']):
    body.set_facecolor(colors[i])
    body.set_alpha(0.6)

ax.set_xticks([1, 2, 3])
ax.set_xticklabels(['개발', '영업', '마케팅'])
ax.set_title('부서별 연봉 분포 (바이올린)')
ax.set_ylabel('연봉 (만원)')
plt.tight_layout()
plt.show()

AI/ML에서의 활용

  • 피처 분포 확인: 히스토그램으로 각 피처의 분포 형태를 파악합니다
  • 이상치 시각화: 박스플롯으로 이상치의 존재와 크기를 확인합니다
  • 그룹 비교: 바이올린 플롯으로 클래스별 피처 분포를 비교합니다
  • 스케일링 전후: 전처리 전후의 분포 변화를 시각적으로 확인합니다
Sturges’ Rule(bins = 1 + log2(n)), Scott’s Rule, Freedman-Diaconis Rule 등이 있습니다. Matplotlib에서 bins='auto'를 사용하면 자동으로 적절한 값을 선택합니다. 일반적으로 20~50 사이가 적절합니다.

체크리스트

  • 히스토그램의 bins 파라미터를 조절하여 적절한 분포를 시각화할 수 있다
  • density=True로 밀도 히스토그램을 그릴 수 있다
  • 박스플롯의 각 구성 요소(상자, 수염, 이상치)를 해석할 수 있다
  • 바이올린 플롯으로 분포의 형태를 파악할 수 있다

다음 문서