Sign In

[데이터 전처리] 데이터 불균형

Y
Yerim
  1. ML
  2. DataAnalysis

데이터 불균형

불균형 데이터 Imbalanced Data

•
분류 문제에서 가장 큰 문제는 불균형 데이터를 다루는 것이다.
•
데이터 불균형은 클래스 분포를 예측해야 하는 분류 문제에서 예측 라벨 값의 분포가 100:1, 200:1 등으로 불균형하게 나타나는 상태를 말한다.
•
불균형 데이터를 해결하지 않으면 과적합 문제가 발생할 수 있다.
•
이 문제를 효율적으로 다루기 위해서는 문제를 제대로 이해하고 전략을 잘 세워야 한다.

불균형 데이터의 원인

실제 세계에서의 분배
•
실제 세계에서 불균형하게 데이터가 구성
•
하나의 클래스가 다른 클래스에 비해서 덜 발생하는 경우
•
불법적인 신용 카드 거래는 정상적인 거래에 비해 훨씬 더 적게 일어난다.
Data Collection bias
•
데이터 수집 편향이 데이터 불균형의 원인
•
어떤 질병이 끼치는 영향 중 극히 일부에만 집중해서 질병 발생 설문조사를
하는 경우, 대부분은 질병을 경험하지 못했다고 함
Event rarity
•
산업 환경에서 장비 고장같은 이벤트의 희귀성은 데이터 불균형을 초래함

불균형 데이터의 영향

Training bias
•
불균형 데이터에 대해 훈련된 모델은 편향된 class를 선호
•
따라서 소수 class 데이터를 분류해야 할 경우 저조한 성적을 보임
잘못된 평가
•
정확도 같은 전통적인 측정 기준을 기만할 수 있음
•
높은 정확도를 보이지만 실질적으로 비효율
•
질병 발병과 그렇지 않은 경우의 데이터가 9999 : 1의 편향을 보일 경우,
◦
모델을 training할 때 거의 다 질병이 발생하지 않았다라고 판단
◦
→ 그렇게 되면 어짜피 정답률 높으니까. BUT 우리가 집중해야 할 것은 질병 걸린 환자
Failure to detect rare events
•
의료 진단이나 사기 탐지와 같은 영역에서 희귀하지만 중요한 사건을 놓치면 심각한 결과를 초래할 수 있음.

Resample

•
데이터 분포를 수정하는 기술
•
Oversampling과 Undersampling이 있음

Undersampling

•
Down Sampling라고도 부르며
•
데이터의 분포가 높은 값을 낮은 값으로 맞춰주는 작업
•
장점: 유의미한 데이터만 남길 수 있다.
•
단점: 정보가 유실되는 문제 발생
•
데이터셋의 크기를 크게 줄이지 않고 균형을 맞추기 위해 다른 기법과 함께 사용하는 경우가 많음
Random Under Sampling
•
무작위 샘플링
•
원하는 균형을 맞출 때까지 랜덤하게 다수 클래스의 인스턴스 제거
n0 = 200; n1 = 20
rv1 = sp.stats.multivariate_normal([-1, 0], [[1, 0], [0, 1]])
rv2 = sp.stats.multivariate_normal([+1, 0], [[1, 0], [0, 1]])
X0 = rv1.rvs(n0, random_state=0)
X1 = rv2.rvs(n1, random_state=0)
X_imb = np.vstack([X0, X1])
y_imb = np.hstack([np.zeros(n0), np.ones(n1)])

x1min = -4; x1max = 4
x2min = -2; x2max = 2
xx1 = np.linspace(x1min, x1max, 1000)
xx2 = np.linspace(x2min, x2max, 1000)
X1, X2 = np.meshgrid(xx1, xx2)

def classification_result2(X, y, title=""):
    plt.contour(X1, X2, rv1.pdf(np.dstack([X1, X2])), levels=[0.05], linestyles="dashed")
    plt.contour(X1, X2, rv2.pdf(np.dstack([X1, X2])), levels=[0.05], linestyles="dashed")
    model = SVC(kernel="linear", C=1e4, random_state=0).fit(X, y)
    Y = np.reshape(model.predict(np.array([X1.ravel(), X2.ravel()]).T), X1.shape)
    plt.scatter(X[y == 0, 0], X[y == 0, 1], marker='x', label="0 클래스")
    plt.scatter(X[y == 1, 0], X[y == 1, 1], marker='o', label="1 클래스")
    plt.contour(X1, X2, Y, colors='k', levels=[0.5])
    y_pred = model.predict(X)
    plt.xlim(-4, 4)
    plt.ylim(-3, 3)
    plt.xlabel("x1")
    plt.ylabel("x2")
    plt.title(title)
    return model
from imblearn.under_sampling import RandomUnderSampler
import matplotlib.pyplot as plt
from sklearn.svm import SVC

X_samp, y_samp = RandomUnderSampler(random_state=0).fit_resample(X_imb, y_imb)

plt.subplot(121)
classification_result2(X_imb, y_imb)
plt.subplot(122)
model_samp = classification_result2(X_samp, y_samp)
Tomek Links
•
서로 가장 가까운 이웃인 서로 다른 클래스의 인스턴스 쌍을 식별하고 제거
•
서로 다른 클래스가 있을 때 서로 다른 클래스끼리 가장 가까운 데이터들이 토멕링크로 묶여서 토멕링크 중 분포가 높은 데이터를 제거하는 방법론
•
클래스를 나누는 TreshHold를 분포가 높은 쪽으로 밀어 붙이는 효과가 있다
•
신용카드 사기 탐지 시스템을 구축하고 싶을 떄, 실제 데이터셋에는 1000개의 합법적인 데이터셋과 20개의 부정적인 트랜잭션이 존재. → 언더샘플링을 통해서 정상 1400 불법 20정도로 재조정
•
장점: 분포가 높은 클래스의 중심분포는 어느정도 유지하면서 경계선을 조정하기 때문에 무작위로 삭제하는 샘플링보다 정보의 유실을 크게 방지
•
단점: 토멕링크로 묶이는 값이 한정적이기 때문에 큰 언더 샘플링의 효과를 얻을 수 없다
from imblearn.under_sampling import TomekLinks
import matplotlib.pyplot as plt

tl = TomekLinks()
X_samp, y_samp = tl.fit_resample(X_imb, y_imb)

plt.subplot(121)
classification_result2(X_imb, y_imb)
plt.subplot(122)
model_samp = classification_result2(X_samp, y_samp)
CNN (Condensed Nearest Neighbour)
•
최근접인 클래스 분포 데이터를 삭제하면서 샘플링하는 방법론
•
과정
•
1. 분포가 작은 클래스르 S분포로 둡니다.
•
2. 분포가 큰 클래스를 랜덤으로 하나 선택한 뒤 그 데이터 위치에서 가장 가까운 데이터를 선택했을 때 S 분포에 포함 되어 있지 않은 데이터라면 제거합니다.
•
3. 가장 가까운 값이 S분포가 나올 때까지 2번을 반복합니다
from imblearn.under_sampling import CondensedNearestNeighbour
import matplotlib.pyplot as plt

cnn = CondensedNearestNeighbour(random_state=0)
X_samp, y_samp = cnn.fit_resample(X_imb, y_imb)

plt.subplot(121)
classification_result2(X_imb, y_imb)
plt.subplot(122)
model_samp = classification_result2(X_samp, y_samp)
One sided Selection
•
Tomek link + CNN
•
토멕링크로 먼저 데이터를 제거한 후 분포가 큰 클래스 내부에서 CNN방법으로 데이터를 데이터를 제거하는 과정을 거치는 방법
from imblearn.under_sampling import OneSidedSelection
import matplotlib.pyplot as plt

oss = OneSidedSelection(random_state=0)
X_samp, y_samp = oss.fit_resample(X_imb, y_imb)

plt.subplot(121)
classification_result2(X_imb, y_imb)
plt.subplot(122)
model_samp = classification_result2(X_samp, y_samp)
Edited Nearest Neighbours
•
KNN방식이랑 비슷하며 소수 클래스 주변의 다중 클래스 값을 제거하는 방법론
•
토멕링크 방법론 처럼 클래스를 구분하는 임계점을 다중 클래스 쪽으로 밀어낼 수 있지만 제거 효과가 크지 않다.
from imblearn.under_sampling import EditedNearestNeighbours
import matplotlib.pyplot as plt

enn = EditedNearestNeighbours(kind_sel="all", n_neighbors=5)

X_samp, y_samp = enn.fit_resample(X_imb, y_imb)

plt.subplot(121)
classification_result2(X_imb, y_imb)
plt.subplot(122)
model_samp = classification_result2(X_samp, y_samp)
Neighbourhood Cleansing Rule
•
CNN방법과 + ENN방법
•
장점: 좀 더 직관적으로 두 클래스를 나눌 수 있다
•
단점: 분포가 큰 데이터에 대한 제거 효과가 크지 않다
from imblearn.under_sampling import NeighbourhoodCleaningRule
import matplotlib.pyplot as plt

ncr = NeighbourhoodCleaningRule(kind_sel="all", n_neighbors=5)

X_samp, y_samp = ncr.fit_resample(X_imb, y_imb)

plt.subplot(121)
classification_result2(X_imb, y_imb)
plt.subplot(122)
model_samp = classification_result2(X_samp, y_samp)

Oversampling

•
Up Sampling이라고 부른다.
•
분포가 작은 클래스의 값을 분포가 큰 클래스로 맞춰주는 샘플링 방법
•
장점: 정보의 손실을 막을 수 있다.
•
단점: 여러 유형의 관측치를 다수 추가하기 때문에 오히려 오버피팅을 야기할 수 있습니다.
•
새로운 데이터, Test 데이터에서의 성능이 나빠지는 결과를 초래
Random Oversampling
•
소수 클래스의 인스턴스를 랜덤하게 복제해서 다수 클래스의 크기에 맞추는 것
•
소수의 클래스 데이터를 반복해서 넣는 것으로 가중치를 증가시키는 것과 비슷
from imblearn.over_sampling import RandomOverSampler
import matplotlib.pyplot as plt

X_samp, y_samp = RandomOverSampler(random_state=0).fit_resample(X_imb, y_imb)

plt.subplot(121)
classification_result2(X_imb, y_imb)
plt.subplot(122)
model_samp = classification_result2(X_samp, y_samp)
SMOTE (Synthetic Ministry Over-sampling Technique)
•
정형 데이터는 주로 SMOTE라는 기법을 통해 Data Augmentation과 같은 효과
•
데이터 증강을 통해 Overfitting을 방지한다.
•
SMOTE는 Imbalanced된 데이터에서 Minority한 데이터를 활용해 사이사이 데이터를 생성하는 방식이다. 기존 클래스 샘플을 보간해서 합성 데이터 포인트를 생성하고 기존 소수 클래스와 유사하지만 새로운 인스턴스를 생성한다.
•
신용카드 사기 탐지 시스템을 구축하고 싶을 떄,
실제 데이터셋에는 1000개의 합법적인 데이터셋과 20개의 부정적인 트랜잭션이 존재.
→ 오버샘플링을 통해서 정상 1000 불법 400정도로 재조정
•
데이터셋의 균형을 효과적으로 유지할 수 있지만, 신중하게 적용하지 않으면 과적합
으로 이어질 수 있음.
•
별도의 테스트 세트에서 모델의 성능을 평가하는 것이 필수
Data Argumentation
•
주로 이미지 분석에서 사용되는 방법론으로 불균형 데이터 상태에서 방법론으로 사용되는 오버샘플링과 데이터를 생성하거나 증가시키는 원리는 비슷하지만 다른 부분이 존재
•
딥러닝으로 이미지 데이터로 문제를 풀 때 많이 사용되는 기법
•
이미지 분석에서 Over fitting을 방지하고 예측에 대한 신뢰성을 높이기 위한 추가적인 데이터를(이미지) 생성하는 방법론
•
원본 이미지를 회전, 반전, 확대 및 축소 → 데이터 개수 늘림
•
GAN으로 데이터를 generate하는 방식과 거의 비슷
•
데이터를 의도적으로 증강시켜 모델에게 다양한 데이터로 학습할 수 있게 함
•
딥러닝에서 사용하는 것과 다르지만 정형 데이터에 활용 가능
from imblearn.over_sampling import ADASYN
import matplotlib.pyplot as plt

X_samp, y_samp = ADASYN(random_state=0).fit_resample(X_imb, y_imb)

plt.subplot(121)
classification_result2(X_imb, y_imb)
plt.subplot(122)
model_samp = classification_result2(X_samp, y_samp)
ADASYN (Adaptive Synthetic Sampling)
•
분포가 작은 클래스 데이터와 그 데이터와 가장 가까운 무작위의 K개의 데이터 사이에 가상의 직선을 그려서 직선상에 존재하는 가상의 분포가 작은 클래스 데이터를 생성
from imblearn.over_sampling import SMOTE
import matplotlib.pyplot as plt

X_samp, y_samp = SMOTE(random_state=0).fit_resample(X_imb, y_imb)

plt.subplot(121)
classification_result2(X_imb, y_imb)
plt.subplot(122)
model_samp = classification_result2(X_samp, y_samp)

Combine Sampling

•
오버샘플링과 언더샘플링을 결합한 샘플링 방법론
SMOTE + ENN
from imblearn.combine import SMOTEENN
import matplotlib.pyplot as plt

X_samp, y_samp = SMOTEENN(random_state=0).fit_resample(X_imb, y_imb)

plt.subplot(121)
classification_result2(X_imb, y_imb)
plt.subplot(122)
model_samp = classification_result2(X_samp, y_samp)
SMOTE + TOMEK
from imblearn.combine import SMOTETomek
import matplotlib.pyplot as plt

X_samp, y_samp = SMOTETomek(random_state=0).fit_resample(X_imb, y_imb)

plt.subplot(121)
classification_result2(X_imb, y_imb)
plt.subplot(122)
model_samp = classification_result2(X_samp, y_samp)

Cost-sensitive Learning

•
비용 민감 학습은 소수 클래스를 오분류할 경우 더 높은 비용을 지불하게 만들어 소수 클래스 인스턴스를 정확하게 예측하는 데 집중하게 만든다.
◦
다수 클래스: 대부분의 샘플이 속한 클래스
◦
소수 클래스: 대부분의 샘플이 속하지 않는 클래스
◦
위양성 비용 FP: 부정 클래스 샘플을 긍정 클래스 샘플로 분류해서 발생하는 비용
◦
위음성 비용 FN: 긍정 클래스 샘플을 부정 클래스 샘플로 분류해서 발생하는 비용
◦
절대 부족: 소수 클래스에 속한 샘플 개수가 절대적으로 부족한 상황
◦
보통 FN이 FP보다 비용이 훨씬 많이 든다.
◦
비용 민감 학습은 FN을 FP보다 크게 설정한다.
FN = w * FP (w>1)
•
여러 기계 학습 알고리즘은 클래스 가중치 또는 사용자 정의 손실 함수를 통해 비용에 민감한 학습을 지원
•
정밀도와 Recall(재현율) 사이에 원하는 균형을 달성하기 위해 비용 매개 변수 미세 조정 필요
•
희귀 질병을 탐지하기 위한 모델 구축 시나리오: 데이터 세트에는 1000건의 정상클래스
와 10건의 질병 사례(소수 클래스)만 있음. 질병 사례를 올바르게 식별하는 것의 중요성을 강조하기 위해 질병 사례를 잘못 분류하는 데 더 높은 비용을 할당하게 되면, 비용에 민감한 학습 프레임워크는 모델이 거짓 양성(비 질병 사례를 질병 사례로 잘못 분류)보다 거짓 음성(질병 사례를 감지하지 못함)에 대해 더 많은 불이익을 받도록 보장
확률모델
•
로지스틱 회귀, 나이브 베이즈 등의 확률 모델은 cut-off value, c를 조정하느 방식으로 비용 민감 모델 구현
•
정확한 확률 추정은 불가능하지만 그 개념을 도입할 수 있는 모델(k-최근접 이웃, 신경망, 의사결정나무, 앙상블 모델 등)에도 적용 가능
import numpy as np
import matplotlib.pyplot as plt
import scipy as sp
from sklearn.svm import SVC

n0 = 200; n1 = 20
rv1 = sp.stats.multivariate_normal([-1, 0], [[1, 0], [0, 1]])
rv2 = sp.stats.multivariate_normal([+1, 0], [[1, 0], [0, 1]])
X0 = rv1.rvs(n0, random_state=0)
X1 = rv2.rvs(n1, random_state=0)
X_imb = np.vstack([X0, X1])
y_imb = np.hstack([np.zeros(n0), np.ones(n1)])

x1min = -4; x1max = 4
x2min = -2; x2max = 2
xx1 = np.linspace(x1min, x1max, 1000)
xx2 = np.linspace(x2min, x2max, 1000)
X1, X2 = np.meshgrid(xx1, xx2)

def classification_result2(X, y, title=""):
    plt.contour(X1, X2, rv1.pdf(np.dstack([X1, X2])), levels=[0.05], linestyles="dashed")
    plt.contour(X1, X2, rv2.pdf(np.dstack([X1, X2])), levels=[0.05], linestyles="dashed")
    model = SVC(kernel="linear", C=1e4, random_state=0).fit(X, y)
    Y = np.reshape(model.predict(np.array([X1.ravel(), X2.ravel()]).T), X1.shape)
    plt.scatter(X[y == 0, 0], X[y == 0, 1], marker='x', label="0 클래스")
    plt.scatter(X[y == 1, 0], X[y == 1, 1], marker='o', label="1 클래스")
    plt.contour(X1, X2, Y, colors='k', levels=[0.5])
    y_pred = model.predict(X)
    plt.xlim(-4, 4)
    plt.ylim(-3, 3)
    plt.xlabel("x1")
    plt.ylabel("x2")
    plt.title(title)
    return model
# data/label, 학습/평가 데이터로 구분
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_imb, y_imb)

print("X_train.shape: {}".format(X_train.shape))
print("X_test.shape: {}".format(X_test.shape))
print("y_train.shape: {}".format(y_train.shape))
print("y_test.shape: {}".format(y_test.shape))

# 불균형 테스트
from sklearn.neighbors import KNeighborsClassifier as KNN
from sklearn.metrics import *

# Assuming you have X_train, y_train, X_test, and y_test defined
kNN_model = KNN(n_neighbors=11).fit(X_train, y_train)

pred_Y = kNN_model.predict(X_test)
print('recall_score: ', recall_score(y_test, pred_Y))
print('accuracy_score: ', accuracy_score(y_test, pred_Y))

# 비용 민감 모델 적용
from sklearn.linear_model import LogisticRegression

# 인스턴스화
model = LogisticRegression(max_iter=100000).fit(X_train, y_train)

y_pred = model.predict(X_test)
print('recall_score: ', recall_score(y_test, y_pred))
print('accuracy_score: ', accuracy_score(y_test, y_pred))

# cut off value 조정
probs = model.predict_proba(X_test)
probs = pd.DataFrame(probs, columns=model.classes_)

cut_off_value = 0.3

pred_y = 2 * (probs.iloc[:, -1] >= cut_off_value) - 1
print('recall_score: ', recall_score(y_test, y_pred))
print('accuracy_score: ', accuracy_score(y_test, y_pred))
def cost_sensitive_model(model, cut_off_value, X_test, y_test):
    probs = model.predict_proba(X_test)
    probs = pd.DataFrame(probs, columns=model.classes_)
    y_pred = 2 * (probs.iloc[:, -1] >= cut_off_value) - 1
    recall = recall_score(y_test, y_pred, average='weighted')
    accuracy = accuracy_score(y_test, y_pred)

    return recall, accuracy

from matplotlib import pyplot as plt
import numpy as np
%matplotlib inline

model = LogisticRegression(max_iter=100000).fit(X_train, y_train)

cut_off_value_list = np.linspace(0, 1, 101)
recall_list = []
accuracy_list = []

for c in cut_off_value_list:
    recall, accuracy = cost_sensitive_model(model, c, X_test, y_test)
    recall_list.append(recall)
    accuracy_list.append(accuracy)

plt.figure(figsize=(12, 8))
plt.plot(cut_off_value_list, recall_list, label = 'recall')
plt.plot(cut_off_value_list, accuracy_list, label='accuracy')
plt.legend()
plt.show()
비확률모델
•
가중치를 나누어 조절하는 형태로 구현(서포트 백터 머신, 의사결정나무)
import numpy as np
import matplotlib.pyplot as plt
import scipy as sp
from sklearn.svm import SVC

n0 = 200; n1 = 20
rv1 = sp.stats.multivariate_normal([-1, 0], [[1, 0], [0, 1]])
rv2 = sp.stats.multivariate_normal([+1, 0], [[1, 0], [0, 1]])
X0 = rv1.rvs(n0, random_state=0)
X1 = rv2.rvs(n1, random_state=0)
X_imb = np.vstack([X0, X1])
y_imb = np.hstack([np.zeros(n0), np.ones(n1)])

x1min = -4; x1max = 4
x2min = -2; x2max = 2
xx1 = np.linspace(x1min, x1max, 1000)
xx2 = np.linspace(x2min, x2max, 1000)
X1, X2 = np.meshgrid(xx1, xx2)

def classification_result2(X, y, title=""):
    plt.contour(X1, X2, rv1.pdf(np.dstack([X1, X2])), levels=[0.05], linestyles="dashed")
    plt.contour(X1, X2, rv2.pdf(np.dstack([X1, X2])), levels=[0.05], linestyles="dashed")
    model = SVC(kernel="linear", C=1e4, random_state=0).fit(X, y)
    Y = np.reshape(model.predict(np.array([X1.ravel(), X2.ravel()]).T), X1.shape)
    plt.scatter(X[y == 0, 0], X[y == 0, 1], marker='x', label="0 클래스")
    plt.scatter(X[y == 1, 0], X[y == 1, 1], marker='o', label="1 클래스")
    plt.contour(X1, X2, Y, colors='k', levels=[0.5])
    y_pred = model.predict(X)
    plt.xlim(-4, 4)
    plt.ylim(-3, 3)
    plt.xlabel("x1")
    plt.ylabel("x2")
    plt.title(title)
    return model
# data/label, 학습/평가 데이터로 구분
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_imb, y_imb)

# 불균형 테스트
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import *

KNN_model = KNeighborsClassifier(n_neighbors=11).fit(X_train, y_train)

y_pred = KNN_model.predict(X_test)
print('recall_score: ', recall_score(y_test, y_pred))
print('accuracy_score: ', accuracy_score(y_test, y_pred))

# 비용 민감 모델
from sklearn.svm import SVC
model = SVC().fit(X_train, y_train)

y_pred = model.predict(X_test)
print('recall_score: ', recall_score(y_test, y_pred))
print('accuracy_score: ', accuracy_score(y_test, y_pred))

# 조정
model = SVC(class_weight={1: 8, 0: 1}).fit(X_train, y_train)

y_pred = model.predict(X_test)
print('recall_score: ', recall_score(y_test, y_pred))
print('accuracy_score: ', accuracy_score(y_test, y_pred))

Collect More Data

•
근본적으로 문제를 해결하기 위해서는 소수 클래스에 해당하는 데이터를 더 많이 수집하면 된다.
•
가장 효과적인 방법이다.

Use Different Algorithms

•
불균형 데이터에 덜 민감한 기계 학습 알고리즘을 선택
•
다른 알고리즘에 비해 불균형 데이터를 더 잘처리한다.
•
특히 불균형 데이터를 처리하기 위한 알고리즘도 존재한다.
불균형 데이터에 덜 민감함 알고리즘
•
Decision Tree
: 각 분할에서 얻은 정보를 바탕으로 의사결정을 하기 때문에 클래스 불균형에 덜 민감
•
Naive Bayes
: 확률론적 원리를 기반으로 하며 클래스 멤버 자격의 조건부 확률을 계산하기 때문에 불균형 데이터로 합리적으로 잘 수행
특수 알고리즘
•
Balanced Random Forest
: 불균형 데이터에 대해 더 나은 성능을 제공하는 기존 랜덤 포레스트의 확장. 훈련 중에 각 의사결정 트리 내에서 클래스 분포의 균형을 유지
ensemble.BalancedRandomForestClassifier(n_estimators=100, *, criterion='gini', 
                max_depth=None, min_samples_split=2, min_samples_leaf=1, 
                min_weight_fraction_leaf=0.0, max_features='sqrt', 
                max_leaf_nodes=None, min_impurity_decrease=0.0, bootstrap='warn', 
                oob_score=False, sampling_strategy='warn', replacement='warn', 
                n_jobs=None, random_state=None, verbose=0, warm_start=False, 
                class_weight=None, ccp_alpha=0.0, max_samples=None, monotonic_cst=None)
from imblearn.ensemble import BalancedRandomForestClassifier
from sklearn.datasets import make_classification

X, y = make_classification(n_samples=1000, n_classes=3,
                           n_informative=4, weights=[0.2, 0.3, 0.5],
                           random_state=0)

clf = BalancedRandomForestClassifier(
    sampling_strategy='all', replacement=True, max_depth=2, random_state=0,
    bootstrap=False
)

# Fit the classifier on your data
clf.fit(X, y)

# Now you can access the feature importances
print(clf.feature_importances_)

# Make a prediction (Note: This is just to demonstrate; you may need actual test data)
print(clf.predict([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]))
•
Easy Essemble
: 데이터의 여러 균형 잡힌 하위 집합을 만들고 이 하위 집합에 기초 분류기를 훈련하는 앙상블 학습 방법
imblearn.ensemble.EasyEnsembleClassifier(n_estimators=10, estimator=None, *, 
            warm_start=False, sampling_strategy='auto', replacement=False, 
            n_jobs=None, random_state=None, verbose=0)
from collections import Counter
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from imblearn.ensemble import EasyEnsembleClassifier

X, y = make_classification(n_classes=2, class_sep=2,
                           n_features=20, n_clusters_per_class=1,
                           n_samples=1000, random_state=10)
print('Original dataset shape %s' %Counter(y))

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

# Instantiate the EasyEnsembleClassifier
eec = EasyEnsembleClassifier()

# Fit the classifier on your training data
eec.fit(X_train, y_train)

# Now you can use it for predictions
y_pred = eec.predict(X_test)
print(confusion_matrix(y_test, y_pred))

Anomaly Detection

•
특정 경우, 소수 클래스가 이상 현상이나 희귀 사건을 나타내는 경우도 있음
•
이 문제를 이상 탐지 문제로 취급
•
이상 탐지 알고리즘은 희귀한 사례와 특이한 사례를 식별하도록 특별히 설계
•
네트워크 침입은 정상 트래픽에 비해 상대적으로 드물다. 분류 접근 방식을 사용하는 대신 Isolation Forest 또는 One-Class SVM과 같은 이상 탐지 방법을 적용하여 네트워크 데이터의 비정상적인 패턴이나 이상치를 식별

Evaluation Metrics

•
불균형 데이터를 처리할 때는 클래스 불균형을 고려한 적절한 평가 지표를 선택하는 것이 중요
•
정밀도 : 정밀도란 모델이 True라고 분류한 것 중에서 실제 True인 것의 비율
•
재현율(recall): 재현율이란 실제 True인 것 중에서 모델이 True라고 예측한 것의 비율
•
둘은 trade off 관계
•
그 외: F1-score, AUC-ROC, AUC-PRC

Threshold Adjustment 임계값 조정

•
분류 작업에서 모델은 확률 점수를 생성하고 이 점수에 임계값을 적용하여 이진 예측을 수행
•
정밀도와 리콜 간의 트레이드오프를 제어
•
ex) 임계값이 0.5인 경우 recall이 낮다 → 임계값을 낮추고 recall 높임
Yerim-DevNote
Subscribe to 'Yerim-DevNote'
Subscribe to my site to be the first to receive notifications and emails about the latest updates, including new posts.
Join Slashpage and subscribe to 'Yerim-DevNote'!
Subscribe
👍