카테고리 없음

이상탐지

yumin630 2024. 10. 23. 00:40

머신러닝에서 이상탐지란?

데이터에서 비정상적인 패턴이나 이상치를 찾아내는 기술을 말한다

 

학습방법은 비지도학습에 가까우나, 평가할때 정상과 비정상을 알아야함으로 label 필요

 

이상탐지는 보통 성능이 좋지 않다...

 

 

이상탐지 알고리즘중 Isolation Forest 를 소개해 보자면 ..!!

1. Train Set으로 부터, 데이터를 샘플링한다.

2. Isolation Tree를 만든다

▪ 랜덤하게 feature를 선정하고, 랜덤하게 split 기준을 삼아 Tree를 생성.

▪ 정상 데이터일 수록 Isolation 시키려면 많은 Split이 필요 ➔ Depth가 길어짐.

▪ 비정상 데이터일 수록(정상으로 부터 떨어져 있을 수록) ➔ Depth가 짧아짐.

 

 

더 쉽게 설명하자면,

 

  • 선택한 샘플 데이터에서 무작위로 **특성(feature)**과 분할 값을 선택
  • 이 과정은 **이진 트리(Binary Tree)**를 만들어, 데이터를 계속 나누어 고립될 때까지 분할

이렇게 설명할 수 있다

 

냅다 코드 ...

 

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.model_selection import train_test_split
from sklearn.ensemble import IsolationForest # Isolation Forest!
from sklearn.metrics import *

from tqdm import tqdm
import warnings
warnings.simplefilter(action='ignore')

# Single Blob
X1 = pd.read_csv('Anomaly_X.csv')

# Double Blob
X2 = pd.read_csv('Anomaly_X2.csv')

 

def model_visualize(model, v1, v2, title = "") :
    # 메쉬그리드값 저장하기
    xx, yy = np.meshgrid(np.linspace(-5, 5, 50), np.linspace(-5, 5, 50)) # mesh grid

    # 메쉬 그리드값에 대해 모델 부터 Anomaly Score 만들기.
    Z = model.decision_function(np.c_[xx.ravel(), yy.ravel()]) # Anomaly Score
    Z = Z.reshape(xx.shape)
    # 시각화
    plt.figure(figsize = (8,8))
    plt.title(title)

    # 메쉬그리드 값의 Anomaly Score에 대한 등고선
    plt.contourf(xx, yy, Z, cmap=plt.cm.Blues_r)

    # 데이터 산점도 그리기.(예측 결과 Abnormal은 오렌지색, Normal은 흰색)
    sns.scatterplot(x=v1, y=v2, sizes = 30, edgecolor='k', hue = pred, palette=['white', 'orange'])

    plt.axis("tight")
    plt.xlim(-5, 5)
    plt.ylim(-5, 5)
    plt.show()
    
    # sample data
plt.figure(figsize = (8,8))

plt.scatter(X1['v1'], X1['v2'], c="white", s=30, edgecolor="k")

plt.xlim(-5, 5)
plt.ylim(-5, 5)
plt.grid()
plt.show()

# 모델링
model = IsolationForest(contamination = 0.1, n_estimators = 50 )
model.fit(X1)
pred = model.predict(X1)
pred

pred = np.where(pred == 1, 0, 1)

 

#시각화
model_visualize(model, X1['v1'], X1['v2'], 'Isolation Forest')