co-code 님의 블로그

이상치 판별 및 처리 본문

python

이상치 판별 및 처리

co-code 2026. 5. 8. 09:30
  • 이상치
    • 값이 이상한 데이터
      • 결측치
        • 결측치를 확인하는 방법
          • isna() 함수를 이용하여 결측치 유무 판단
          • sum() 함수를 이용하여 결측치 개수 확인
          • info() 함수를 이용하여 non-null count 확인
      • 범위를 벗어나는 데이터
        • 특정 범위를 벗어나는 데이터를 확인하는 방법
          • unique() 함수를 이용하여 특정 필드의 유일 데이터 확인
          • value_counts() 함수를 이용하여 특정 필드와 데이터들의 빈도수 확인
          • isin() 함수를 이용하여 특정 값들에 포함되어있는가를 확인하고 부정연산자(비트연산자(-))를 이용하여 데이터를 대입
      • 값이 크게 벗어나는 데이터(극단치)
        • 극단치 확인하는 방법
          • IQR방식
            • boxplot()의 수염의 경계
              • Q3(3사분위수)와 Q1(1사분위수)를 이용하여 극단치의 범위를 지정
              • IQR = Q3 - Q1
              • 극단치의 경계
                • 상단의 경계(상한) : Q3 + 1.5 * IQR
                • 하단의 경계(하한) : Q1 - 1.5 * IQR
              • 상한보다 크거나 하한보다 작은 경우 극단치로 판단
    • 분석 모형의 성능을 떨어뜨리거나 결과에 악영향을 미칠 수 있음
    • 이상치 데이터 발견 시 즉시 처리
      • 데이터 제거
        • 소량의 데이터에서 데이터를 제거하면 학습 데이터가 부족해지는 경우가 발생할 수 있음
        • 이상치 데이터가 너무 많은 경우 많은 양의 데이터가 제거될 수 있다.
        • 데이터 소실
      • 특정 값으로 대체
        • 데이터의 양은 보존됨
        • 일반적으로 평균값을 대체한다거나 최빈값으로 대체
        • 데이터의 신뢰도 하락 가능성 존재
        • 분석의 성능이 떨어질 수 있음
        • 데이터 분포도의 과밀화가 종종 발생

이제 wine 데이터셋을 이용해 이상치를 판별해 보자.

#사이킷런 라이브러리 설치
# !pip install scikit-learn

#필요 라이브러리 로드
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_wine

#사이킷런에서 제공하는 샘플 와인 데이터를 로드
wine_data=load_wine()

wine_data.keys()
dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names'])

#data, feature_names 데이터를 이용하여 데이터프레임 생성
wine = pd.DataFrame(
    data=wine_data['data'],
    columns=wine_data['feature_names']
)

wine

wine 데이터프레임


#결측치 확인
wine.info()


#극단치 데이터를 확인
#describe() 함수
wine.describe()


#boxplot()함수를 이용하여 극단치 경계에서 벗어나는 데이터기 존재하는가?
#특정 컬럼 (color_intensity)를 이용하여 확인
plt.boxplot(wine['color_intensity'])
plt.show()


#numpy 라이브러리를 이용해서 사분위수를 출력이 가능
#perentile() : 첫번째 인자는 데이터들 // 두번째 인자는 몇퍼샌트의 값들을 선택
q_1,q_3=np.percentile(wine['color_intensity'],[25,75])
print(q_1)
print(q_3)
3.2199999999999998
6.2

#IQP 계산
iqr=q_3 - q_1
#상단 경계 계산 : 3사분위수 + (1.5 * IQR)
upper_whis=q_3 + (1.5 * iqr)
#하단 경계 계산 : 1사분위수 - (1.5 * IQR)
lower_whis=q_1 - (1.5 * iqr)

print(upper_whis, lower_whis)
10.670000000000002 -1.2500000000000009

#극단치 : 상단의 경계보다 크거나 하단의 경계보다 작은 경우
upper_flag=wine['color_intensity'] > upper_whis
lower_flag=wine['color_intensity'] < lower_whis

wine.loc[upper_flag | lower_flag,]


#데이터프레임을 복사
df=wine.copy()

#case 1 : df 데이터프레임에서는 극단치를 제거
#drop()함수를 이용해서 해당 인덱스를 제거
#극단치의 경계식에 부정(비트연산자)하여 필터링
#극단치에 데이터를 결측치로 대체하고 결측치를 제거하는 함수
    #특정 컬럼의 데이터들을 결측치로 대체하고 결측치 제거함수(dropna())를 이용해서 삭제
whis_idx=df.loc[upper_flag | lower_flag,].index

df.drop(whis_idx,axis=0)


#case2 : 극단치 데이터들을 다른 값으로 대체
#극단치 상단의 경계에서 벗어난 데이터는 상단의 경계값으로 채워주소
#      하단의 경계에서 벗어나 데이터는 하단의 경계값을 채워준다.

#상단 경계에서 벗어난 데이터를 확인
df2=wine.copy()
df2.loc[upper_flag,]


#경계애서 벗어난 대이터는 상단의 경계값으로 대체
df2.loc[upper_flag,'color_intensity']=upper_whis
df2.loc[lower_flag,'color_intensity']=lower_whis

plt.boxplot(df2['color_intensity'])
plt.show()

위 박스 플롯(boxplot)을 통해 이상치(outlier)가 사라진 것을 확인할 수 있다.

 

 

'python' 카테고리의 다른 글

이진 분류  (0) 2026.05.13
데이터 불균형 문제 및 완화 방법  (0) 2026.05.08
matplotlib을 이용한 시각화  (0) 2026.04.29
웹 크롤링  (0) 2026.04.23
클래스(Class)란? 구성 및 상속  (0) 2026.04.15