표준화 전후로 이상치(Outlier)를 제거하는 Python 예제 코드입니다.
2022. 4. 5 최초작성
이상치는 대부분의 값과 다르게 아주 작거나 아주 큰 값을 의미합니다.
평균 ± 표준편차 × 3 을 벗어나는 것을 이상치로 취급하여 제거해본 예제 코드입니다. 표준화를 적용 전후에 각각 이상치를 제거해봤습니다.
전체 코드입니다.
import pandas as pd import numpy as np import matplotlib.pyplot as plt from collections import Counter # 5개의 특징으로 구성된 샘플 40개 생성 a = np.random.randint(1, 13, size=200).reshape(40, 5) df_raw = pd.DataFrame(a) # 0번째 특징에 이상치 추가 df_raw.iloc[0, 0] = -30 df_raw.iloc[1, 0] = 30 df_raw.iloc[2, 0] = 60 df_raw.iloc[3, 0] = -27 df_raw.iloc[4, 0] = 27 df_raw.iloc[5, 0] = -60 # 평균과 표준편차 df_raw_mean = df_raw.mean(axis=0) df_raw_std = df_raw.std(axis=0) # df_raw에 포함된 숫자(key_raw) 별로 몇개가 존재하는지 계산(value_raw) key_raw = Counter(df_raw.values.flatten()).keys() value_raw = Counter(df_raw.values.flatten()).values() # mean - 3*std ~ mean + 3*std 범위 벗너나면 이상치로 제거 df_raw_result = df_raw.copy() df_raw_result[df_raw_result > df_raw_mean + df_raw_std * 3] = 0 df_raw_result[df_raw_result < df_raw_mean - df_raw_std * 3] = 0 # df_raw_result에 포함된 숫자(key_raw_result) 별로 몇개가 존재하는지 계산(value_raw_result) key_raw_result = Counter(df_raw_result.values.flatten()).keys() value_raw_result = Counter(df_raw_result.values.flatten()).values() # 표준화 적용 df_standardization = (df_raw - df_raw_mean) / df_raw_std # df_standardization에 포함된 숫자(key_standardization) 별로 몇개가 존재하는지 계산(value_standardization) key_standardization = Counter(df_standardization.values.flatten()).keys() value_standardization = Counter(df_standardization.values.flatten()).values() # -3 ~ 3 범위 벗어나면 이상치로 제거 df_standardization_result = df_standardization.copy() df_standardization_result[df_standardization_result > 3] = 0 df_standardization_result[df_standardization_result < -3] = 0 # df_standardization_result에 포함된 숫자(key_standardization_result) 별로 몇개가 존재하는지 계산(value_standardization_result) key_standardization_result = Counter(df_standardization_result.values.flatten()).keys() value_standardization_result = Counter(df_standardization_result.values.flatten()).values() # 이상치가 존재했던 셀만 값을 출력하여 변화 확인 print('df_raw') for i in range(6): print(df_raw.iloc[i, 0], end=" ") print('\n') print('df_raw_result') for i in range(6): print(df_raw_result.iloc[i, 0], end= " ") print('\n') print('df_standardization') for i in range(6): print(df_standardization.iloc[i, 0], end=" ") print('\n') print('df_standardization_result') for i in range(6): print(df_standardization_result.iloc[i, 0], end=" ") print('\n') # 이상치 제거되는 것을 그래프로 확인 k = 0 # 각 값들의 분포 모양 비교 f,ax = plt.subplots(1,4,figsize=(12, 5)) ax[0].bar(key_raw, value_raw, color='red') ax[0].set_xlim([-65, 65]) ax[0].set_ylim([0, 45]) ax[0].set_title('rawdata before') ax[0].axvline(df_raw_mean[k], color='b', linestyle='dashed', linewidth=1) ax[0].axvline(df_raw_mean[k] - df_raw_std[k]*3 , color='k', linestyle='dashed', linewidth=1) ax[0].axvline(df_raw_mean[k] + df_raw_std[k]*3 , color='k', linestyle='dashed', linewidth=1) ax[1].bar(key_raw_result, value_raw_result, color='red') ax[1].set_xlim([-65, 65]) ax[1].set_ylim([0, 45]) ax[1].set_title('rawdata after') ax[1].axvline(df_raw_mean[k], color='b', linestyle='dashed', linewidth=1) ax[1].axvline(df_raw_mean[k] - df_raw_std[k]*3, color='k', linestyle='dashed', linewidth=1) ax[1].axvline(df_raw_mean[k] + df_raw_std[k]*3 , color='k', linestyle='dashed', linewidth=1) ax[2].bar(key_standardization, value_standardization, color='red') ax[2].set_xlim([-7, 7]) ax[2].set_ylim([0, 45]) ax[2].set_title('Standardization data before') ax[2].axvline(-3, color='k', linestyle='dashed', linewidth=1) ax[2].axvline(3 , color='k', linestyle='dashed', linewidth=1) ax[3].bar(key_standardization_result, value_standardization_result, color='red') ax[3].set_xlim([-7, 7]) ax[3].set_ylim([0, 45]) ax[3].set_title('Standardization data after') ax[3].axvline(-3, color='k', linestyle='dashed', linewidth=1) ax[3].axvline(3 , color='k', linestyle='dashed', linewidth=1) plt.show() |
이상치 제거를 보여주는 그래프입니다.
왼쪽 2개는 표준화 전에 이상치를 제거한 전후이고 오른쪽 2개는 표준화 후에 이상치를 제거한 전후입니다.
이상치에 해당되는 값만 출력한 결과입니다.
df_raw
-30 30 60 -27 27 -60
df_raw_result
-30 30 0 -27 27 0
df_standardization
-2.124591463996994 1.4536678437874169 3.2427974976796223 -1.9456784986077733 1.2747548783981963 -3.913721117889199
df_standardization_result
-2.124591463996994 1.4536678437874169 0.0 -1.9456784986077733 1.2747548783981963 0.0
참고
https://machinelearningmastery.com/how-to-use-statistics-to-identify-outliers-in-data/
https://analyticsindiamag.com/outlier-detection-using-z-score-a-complete-guide-with-python-codes/
'Deep Learning & Machine Learning > 강좌&예제 코드' 카테고리의 다른 글
캐글 딥러닝 강좌 정리 2 - 확률적 경사 하강법(Stochastic Gradient Descent), 손실함수, 옵티마이저 (0) | 2023.10.26 |
---|---|
캐글 딥러닝 강좌 정리 1 - 뉴런(Neuron)과 깊은 신경망(DNN) (0) | 2023.10.26 |
표준정규분포 표준화 (standardization) (0) | 2023.10.23 |
정규 분포(Normal Distribution)와 표준 정규 분포(Standard Normal Distribution)의 차이 (0) | 2023.10.23 |
상관 계수(Correlation coefficient) 개념 (0) | 2023.10.23 |
시간날때마다 틈틈이 이것저것 해보며 블로그에 글을 남깁니다.
블로그의 문서는 종종 최신 버전으로 업데이트됩니다.
여유 시간이 날때 진행하는 거라 언제 진행될지는 알 수 없습니다.
영화,책, 생각등을 올리는 블로그도 운영하고 있습니다.
https://freewriting2024.tistory.com
제가 쓴 책도 한번 검토해보세요 ^^
그렇게 천천히 걸으면서도 그렇게 빨리 앞으로 나갈 수 있다는 건.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!