파이썬에서 이상치 처리하기

학습 목표 매핑

SKALA 3기 Module 2 — 데이터 분석 개요 및 기초통계 (Learning Objective 2-2)

  • Objective: 데이터 품질 문제(결측치·중복·이상치) 3가지를 IQR 기법으로 탐지하고, 실무 데이터셋에서 90% 정확도로 식별 가능 (Bloom L3-L4)
  • Evaluation: 정확도 평가 (탐지 성공률)

이상치 탐지 방법

1. Z-score (표준정규분포)

개념: 데이터가 평균으로부터 얼마의 표준편차만큼 벗어나 있는지 측정

공식:

판정 기준:

  • |Z| < 1.96: 95% 신뢰수준 범위 내 (정상)
  • 1.96 ≤ |Z| < 2.58: 99% 신뢰수준 범위 내
  • |Z| ≥ 2.58: 99% 신뢰수준 초과 (이상치)

Python:

from scipy.stats import zscore
 
# Z-score 계산
df['Z_Score'] = zscore(df['Value'])
 
# 이상치 탐지 (3σ 기준)
df['Outlier'] = df['Z_Score'].abs() > 3

2. IQR (사분위수 범위)

개념: 데이터 분포의 중간 50% 범위를 이용한 탐지

공식:

  • Q1: 25 percentile
  • Q3: 75 percentile
  • IQR = Q3 - Q1
  • 하한 = Q1 - 1.5 × IQR
  • 상한 = Q3 + 1.5 × IQR

판정: 하한 미만 또는 상한 초과 → 이상치

Python:

# IQR 계산
Q1 = df['Value'].quantile(0.25)
Q3 = df['Value'].quantile(0.75)
IQR = Q3 - Q1
 
lower = Q1 - 1.5 * IQR
upper = Q3 + 1.5 * IQR
 
# 이상치 탐지
df['Outlier'] = (df['Value'] < lower) | (df['Value'] > upper)

이상치 처리 방법

방법 1: 삭제 (Removal)

이상치 행을 완전히 제거

Python:

# 이상치 제거
df_clean = df[~df['Outlier']]
 
# 또는 인덱스로 제거
outlier_idx = np.where((df['Value'] < lower) | (df['Value'] > upper))
df_clean = df.drop(outlier_idx)

장점:

  • ✅ 명확한 처리
  • ✅ 통계 왜곡 없음

단점:

  • ❌ 데이터 손실
  • ❌ 샘플 크기 감소

방법 2: 대체 (Capping / Imputation)

이상치 값을 상한/하한으로 대체

Python:

# 상한/하한으로 제한 (Capping)
df['Value_Capped'] = df['Value'].clip(lower=lower, upper=upper)
 
# 중앙값으로 대체
median = df[~df['Outlier']]['Value'].median()
df['Value_Imputed'] = df['Value'].where(~df['Outlier'], median)
 
# 최대/최소값으로 대체
max_val = df[~df['Outlier']]['Value'].max()
df['Value_MaxReplace'] = df['Value'].apply(
    lambda x: max_val if x > upper else (lower if x < lower else x)
)

장점:

  • ✅ 데이터 보존
  • ✅ 샘플 크기 유지
  • ✅ 머신러닝 모델 안정성

단점:

  • ❌ 원본 데이터 변형
  • ❌ 통계 왜곡 가능

박스플롯 시각화

import matplotlib.pyplot as plt
 
# 박스플롯으로 이상치 시각화
plt.figure(figsize=(10, 6))
plt.boxplot(df['Value'], vert=True)
plt.title('이상치 시각화 (박스플롯)')
plt.ylabel('Value')
plt.grid(axis='y', alpha=0.3)
plt.show()
 
# 파란색 상자: Q1 ~ Q3 (50% 데이터)
# 주황색 선: 중앙값 (Median)
# 수염(whisker): 하한 ~ 상한 (경계값)
# 검은 점: 이상치 (outliers)

처리 방법 선택 기준

상황추천 방법이유
샘플 충분삭제데이터 순수성 중시
샘플 부족대체데이터 손실 방지
금융/의료대체정보 손실 최소화
머신러닝대체모델 안정성
통계 분석삭제가정 충족
센서 데이터삭제오류 명백

실전 예시

# 시계열 데이터의 이상치 처리
data = {
    'Date': pd.date_range('2026-01-01', periods=100),
    'Sales': [100, 105, 98, 102, 95, 500, 103, ...  # 500은 이상치
}
df = pd.DataFrame(data)
 
# IQR 기반 이상치 탐지
Q1 = df['Sales'].quantile(0.25)
Q3 = df['Sales'].quantile(0.75)
IQR = Q3 - Q1
 
lower = Q1 - 1.5 * IQR
upper = Q3 + 1.5 * IQR
 
# 이상치 확인
print(f"이상치: {df[(df['Sales'] < lower) | (df['Sales'] > upper)]}")
 
# 상한/하한으로 제한 (추천)
df['Sales_Clean'] = df['Sales'].clip(lower=lower, upper=upper)
 
# 결과 비교
print(f"원본 mean: {df['Sales'].mean():.2f}")
print(f"정제 후 mean: {df['Sales_Clean'].mean():.2f}")

주의사항

⚠️ 이상치가 항상 오류는 아님:

  • 극단값도 유효할 수 있음 (예: 명절 판매량 급증)
  • 도메인 지식으로 판단 필수

⚠️ 자동 처리의 위험:

  • 단순한 규칙 적용은 위험
  • 항상 도메인 전문가 검토 필수

⚠️ 처리 방법 문서화:

  • 어떤 방법으로 처리했는지 기록
  • 재현성과 투명성 확보

학습 설계 포인트

Cognitive Level (Bloom)

  • L2 (Understand): Z-score/IQR 개념, 판정 기준
  • L3 (Apply): 실제 데이터에 적용
  • L4 (Analyze): 삭제 vs 대체 선택 판단

권장 실습

  1. 탐지: 샘플 데이터에서 이상치 식별
  2. 시각화: 박스플롯으로 확인
  3. 비교: 처리 전후 통계량 비교 (평균, 표준편차)
  4. 정확도: 탐지된 이상치 도메인 검증

참고 자료

타 소스와의 연계

outlier-detection-iqr-zscore-medium (이상치 탐지 수학/코드) eda-exploratory-data-analysis-geeksforgeeks (EDA 8단계 프로세스) eda-python-tds-prabhu (실제 데이터셋 정제 사례)