Python

데이터 전처리: 이상치 탐지 및 처리

수현조 2024. 12. 3. 11:09

1. 이상치(Outlier)란?

  • 이상치는 데이터의 일반적인 패턴에서 벗어난 값을 의미합니다.
  • 문제점:
    • 분석 결과에 부정적인 영향을 미침.
    • 모델 학습 과정에서 왜곡 발생 가능.
  • 해결 필요성:
    • 탐지 후 적절히 제거하거나 처리해야 합니다.

2. 이상치 탐지 방법

1) 기술 통계 기반 탐지

  • describe() 함수: 데이터의 기본 통계량 확인.
  • 이상치 의심 기준:
    • 평균(mean)과 최대값(max)이 지나치게 차이 나는 경우.
    • 표준편차(std)가 지나치게 큰 경우.
import pandas as pd

# 데이터 생성
data = {
    '이름': ['철수', '영희', '민수', '지수', '상수'],
    '나이': [25, 30, 22, 35, 120],  # 120은 이상치로 의심됨
    '점수': [90, 85, 95, 80, 88]
}
df = pd.DataFrame(data)

# 기술 통계량 확인
print(df['나이'].describe())

결과:

count      5.000000
mean      46.400000
std       41.892848
min       22.000000
25%       25.000000
50%       30.000000
75%       35.000000
max      120.000000

분석:

  • 평균(46.4)과 최대값(120)의 차이가 매우 큽니다.
  • 표준편차(std=41.89)가 크다는 점에서 이상치 가능성이 높습니다.

2) 시각화 기반 탐지

박스플롯(Box Plot):
데이터 분포와 이상치를 한눈에 파악할 수 있는 유용한 시각화 도구입니다.

import matplotlib.pyplot as plt

# 박스플롯으로 이상치 시각화
plt.boxplot(df['나이'])
plt.title('나이의 박스플롯')
plt.show()

분석:

  • 박스 위 또는 아래에 있는 점이 이상치로 간주됩니다.

3) IQR(사분위수 범위) 기반 탐지

IQR(Interquartile Range):

  • Q1(25%)와 Q3(75%)의 차이를 사용해 이상치를 정의.
  • 공식: 이상치 = 값이 Q1 - 1.5 * IQR보다 작거나, Q3 + 1.5 * IQR보다 큰 값.
# IQR 계산
Q1 = df['나이'].quantile(0.25)
Q3 = df['나이'].quantile(0.75)
IQR = Q3 - Q1

# 이상치 조건
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

# 이상치 탐지
outliers = df[(df['나이'] < lower_bound) | (df['나이'] > upper_bound)]
print(outliers)

결과:

    이름   나이  점수
4  상수  120   88

분석:

  • 나이 120은 이상치로 확인되었습니다.

IQR이 뭘까? 🔽

 

IQR

1. IQR(Interquartile Range)이란?데이터를 작은 값부터 큰 값까지 정렬했을 때, 전체 데이터를 4등분한 값 중 일부를 이용하는 방법입니다.Q1 (1사분위수): 데이터의 하위 25% 지점 (데이터를 4등분했을 때

josuhyeon.tistory.com

 


3. 이상치 처리 방법

1) 제거

  • 이상치를 제거해 데이터의 왜곡을 방지.
# 이상치 제거
df_cleaned = df[(df['나이'] >= lower_bound) & (df['나이'] <= upper_bound)]
print(df_cleaned)

결과:

    이름  나이  점수
0  철수  25   90
1  영희  30   85
2  민수  22   95
3  지수  35   80

2) 대체

  • 이상치를 평균, 중앙값 또는 다른 값을 사용해 대체.
# 중앙값으로 이상치 대체
median_value = df['나이'].median()
df['나이'] = df['나이'].apply(lambda x: median_value if x > upper_bound or x < lower_bound else x)
print(df)

결과:

    이름    나이  점수
0  철수   25.0  90
1  영희   30.0  85
2  민수   22.0  95
3  지수   35.0  80
4  상수   30.0  88

3) 변환

  • 이상치를 로그 변환(Log Transformation)이나 스케일링 기법으로 처리.
# 로그 변환
import numpy as np

df['로그_나이'] = np.log1p(df['나이'])
print(df)

 

4) 이상치를 그대로 유지

이상치를 탐지했지만, 경우에 따라서는 이를 처리하지 않고 유지하는 것이 더 적합할 때가 있습니다.


언제 이상치를 유지해야 하나요?

  1. 분석 목적에 따라
    • 이상치 자체가 분석의 중요한 포인트일 수 있습니다.
    • 예: 시장의 극단적인 고객 행동, 비정상적으로 높은 매출 등.
  2. 실제 데이터의 특성을 반영
    • 이상치가 데이터의 자연스러운 일부일 가능성.
    • 예: 과학 실험에서 특정 환경적 요인으로 값이 매우 높은 경우.
  3. 데이터 손실 방지
    • 이상치를 제거하거나 대체하면 중요한 데이터가 손실될 가능성이 있음.

예제: 이상치를 유지

import pandas as pd

# 데이터 준비
data = {
    '이름': ['철수', '영희', '민수', '지수', '상수'],
    '나이': [25, 30, 22, 35, 120],  # 120은 이상치로 의심됨
    '점수': [90, 85, 95, 80, 88]
}
df = pd.DataFrame(data)

# 이상치를 그대로 유지
print(df)

출력 결과:

    이름   나이  점수
0  철수   25   90
1  영희   30   85
2  민수   22   95
3  지수   35   80
4  상수  120   88

주의 사항

  • 모델 학습에 미치는 영향: 이상치를 유지하면 분석 모델이 왜곡될 수 있으므로 결과를 해석할 때 주의가 필요합니다.
  • 검증 과정 필요: 이상치를 유지한 상태에서 데이터가 올바르게 작동하는지, 모델의 성능에 문제가 없는지 추가 검증이 필요합니다.

 

5) 이상치 처리 전략

  1. 이상치가 분석에 어떤 영향을 미치는지 확인.
  2. 분석 목적에 따라 제거, 대체 또는 변환 기법 선택.
  3. 이상치 처리 후 데이터가 정상적으로 분포하는지 검토.