인공지능/머신러닝
# [EDA] 데이터 불균형 해결을 위한 SMOTE oversampling
ForrestPark
2024. 12. 17. 16:12
📌 본 포스팅은 오버샘플링을 통한 데이터 불균형 해결 내용을 다룹니다.
📌 [참고] 데이콘
1. 데이터 불균형
1.1 데이터 불균형 모델 학습의 균형
- 한 클랫의 데이터가 다른 클래스에 비해 훨씬 많을 때 발생함. ex) 은행 사기 탐지 시스템에서 정상거래는 많지만 사기거래는 적은 경우 모델이 사기 거래를 제대로 인식하지 못할 수있음. 모델 성능 저하, 일반화 능력 감소, 부정적 결과 초래
- 데이터가 불균형하면 다양한 상황을 제대로 학습 불가. 특정 유형 데이터만 많이 보면 다른 중요한 유형 간과 혹은 잘못 이해
- 소수 클래스 과소평가 사기거래를 찾는게 아니라 그냥 모든 거래를 정상으로 분류 할수 있음. 이럴경우 99 퍼 예측률 나옴.
- 불균형으로 인한 과적합이 나올수 잇음. 정상거래에 완전히 과적합 되어서 사기 거래는 모두 틀리게 될 수있음.
- 일반화 능력 저하( 현실 적응 불가 ) 학습한 내용을 새로운 보지 못한 데이터에도 잘 적용하는 능력
2. over sampling -> 소수 클래스 증가
- 가상의 금융 거래 데이터셋 , 사기거래 탐지 모델, 오버샘플링을 사용하는 데이터 불균형 문제 해결
- 오버샘플링 개념, 단순무작위 복제와 SMOTE(Synthetic Minority Over-sampling Technique)
- undersampling : 다수 클래스의 샘플을 줄이는 방식. , oversampling: 소수 클래스 샘플을 인위적으로 늘림. 상황에따라 둘을 섞어서 적용함.
2.1 오버 샘플링 종류
- 단순 무작위 복제 : 가장 기본적 방식. from imblearn.overs_sampling import RandomOverSampler
- 간단하고 쉬움, 빠름, 데이터 분포를 유지하면서 샘플 수만 증가. 클래스 특성을 변형하지 않고 보존.
- 과적합의 위험: 동일한 데이터륿 반복하기떄문에 훈련데이터에 과도하게 최적화 되는 과적함.
- 새롭고 다양한 정보를 추가하지 않고 복제 -> 다양성이 증가하지 않음.
- 실제 상황에서 소수 클래스가 다양한 형태로 나타날 경우. 복잡한 패턴 모델링 하는데 한계가 잇ㅇ므.
- SMOTE : 새로운 손님을 만들어 내는것 처럼 기존 데이터를 바탕으로 새로운 데이터 포인트를 합성함.
- 합성 소수 오버샘플링 , 소수 클래스의 오버샘플링을 통해 균형 잡힌 데이터 를 만듬.
- 기존 소수 클래스 인스턴스간의 특성을 보간함. => 새로운 합성 샘플을 생성
방법:- 이웃 선택 : 소수 클래스의 인스턴스를 선택, 이 인스턴스와 가장 가까이 있는 소수 클래스 인스턴스들 중에서 하나 이상을 이웃으로 선택함. 이웃-> 선택한 원본 인스턴스와 비슷한 특성을 가진 데이터포인트임
- 임의의 이웃을 선택: 이중에 하나의 이웃을 무작위 선택, 다양성을 보장하기 위해 무작위성을 도입.
- 특성 차이 계산: 선택된 이웃과 원본 인스턴스 간 각 특성값 의 차이를 계산(ex: 데이터 포인트의 각 변수 값) => 새로운 데이터 포인트를 생성시 사용되는 간격, 벡터가 됨.
- 새 인스턴스 생성 : 계산된 특성 차이에 0과 1 사이에 무작위수(랜덤 스칼라값) 을 곱함. , 새로운 합성 인스턴스가 원본 인스턴스와 선택된 이웃 사이의 중간 점에 위치하도록 함. -> 무작위 수를 곱함으로 써 생성된 새 인스턴스는 원본 인스턴스와 정확히 동일하지 않고 약간의 변화를 가지게 됨.
- 합성 인스턴스 추가 : 원본 인스턴스의 특성값에 추가되어 최종 인스턴스 생성.
- 데이터 다양성 증가, 일반화된 학습 수행 가능, 과적합 위험을 줄여줌.
- 기존 데이터패턴이 이상할떄 잘못된 샘플 생성 위험, 계산 복잡성으로 인한 리소스 와 시간필요, 변수가 많은 데이터나 복잡한 데이터는 smote 적용 어려움.
3. Oversampling 함수 제작 및 사용
## 4-1 : ROS 와 SMOTE 를 활용한 오버샘플링 -> 데이터 균일화
def step_4_1_Oversampling(train_x,train_y, ros =False, smote =False,feature_select=[]):
"""
#1.
## train_x_ros, train_y_ros= step_4_1_Oversampling(train_x,train_y, ros=True)
## step_4_MLOutput_target_ratio(pd.concat([train_x_ros, train_y_ros],axis=1), target_col=target,graph_show=False)
#2.
## train_x_smote, train_y_smote = step_4_1_Oversampling(train_x,train_y, smote=True,feature_select=[])
## step_4_MLOutput_target_ratio(pd.concat([train_x_smote, train_y_smote],axis=1), target_col=target,graph_show=False)
"""
print(r_cy("\n======================= step_4_1_Oversampling ======================="))
import pandas as pd
if ros:
from imblearn.over_sampling import RandomOverSampler
ros = RandomOverSampler(random_state= 42)
X_resampled, y_resampled = ros.fit_resample(train_x,train_y)
#결과
print(red(" - Random Over Sampling 을 적용하여 불균일을 처리합니다"))
train_resampled = pd.concat([X_resampled,y_resampled],axis =1)
return X_resampled, y_resampled
if smote:
from imblearn.over_sampling import SMOTE
smote = SMOTE(random_state =42)
X_smote, y_smote =smote.fit_resample(train_x,train_y)
# SMOTE 결과
print(red(" - Synthetic Minority OverSampling Technique(smote )을 적용하여 불균일을 처리합니다"))
train_smote = pd.concat([X_smote, y_smote ],axis =1)
import matplotlib.pyplot as plt, seaborn as sns
import warnings ; warnings.filterwarnings('ignore')
plotSetting()
## 피처 선택
if len(feature_select) !=0:
feature1= feature_select[0]
feature2=feature_select[1]
else:
feature1 = train_x.columns[0] #'이전 거래와의 시간 간격'
feature2 = train_x.columns[1] #'거래 금액'
# 원본 데이터 분포 시각화
plt.figure(figsize= (16,5))
plt.subplot(1,2,1)
sns.scatterplot(x = train_x.loc[:,feature1], y = train_x.loc[:,feature2], hue =train_y)
plt.title("Original Data")
# SMMOTE 방법으로 오버샘플링 데이터 시각화
plt.subplot(1,2,2)
sns.scatterplot(x = X_smote.loc[:,feature1], y = X_smote.loc[:,feature2], hue= y_smote)
plt.title("SMOTE oversampled DATA")
plt.show()
return X_smote, y_smote