## 들어가기전
Anomaly Detection은 지도학습인 Classification과 같은 문제유형으로,
모델을 만들고, 정상(normal)과 비정상(abnormal)을 평가한다.
하지만 대체로 비지도학습에 가까운데,
그 이유는 비정상 (Abnormal) 데이터가 너무 부족하기 때문이다.
또한 그나마 있는 데이터도 Class를 대표하기 어렵다.
=> 따라서, 정상(Normal) 데이터를 가지고 어디까지가 정상인지 추정한다.
1. 이상탐지의 몇 가지 Challenge
(1) Label을 어떻게 확보할 것인가?
- 보통, Normal Data는 자동으로 수집하고, Abnoraml Data는 수동관리하는 경우가 많음
- 비지도 학습이지만, 모델을 평가하려면 Label이 필요함.
(2) 낮은 성능 문제
- 정상모델과 비정상모델의 비율차이로, 정확도(Accuracy)는 높지만 재현율(recall)이 낮음.
- 어떤 지표를 사용해야하는지, 어떤 기준으로 잘라서 나눠야(0,1) 하는지 적절한 지표와 기준을 사용해야 함.
2. 평가지표 : f1-Score (정밀도와 재현율의 조화 평균)
=> Recall과 Precision을 균형 있게 볼 수 있는 F1-Score가 좀 더 나은 지표
=> 비즈니스 관점으로 평가하는 것이 중요함.
3. Anomaly Detection 해결 방법들
- Abnormal이 매우 부족한 경우 : Anomaly Detection => Isolation Forest / One Class SVM
- Abnormal이 적당히(?) 부족한 경우 : Classification => Class Imbalance 문제 해결
4. Isolation Forest 이해
(1) 절차
1 | Train Set로 부터, "일부" 데이터 샘플링 | - 256개 정도면 충분하다고 알려져 있음 | ![]() |
2 | Isolation Tree 만들기 | - 랜덤하게 feature 선정하고 랜덤하게 split 기준을 삼아 Tree 생성 (data가 leaf node에 혼자 남을 때까지) - 정상 데이터일수록 Isolation 시키려면 많은 Split 필요 => Depth 길어짐 - 비정상 데이터일수록 => Depth 짧아짐 - 랜덤 Tree를 늘려가면서 고립시키기 위한 Depth 측정 |
|
3 | Scoring으로 정상/비정상 구분 - 1에 가까울수록 Abnormal |
- xi depth가 전체 평균과 비슷하면 0.5 - xi depth가 전체 평균보다 작으면 1 - xi depth가 전체 평균보다 크면 0 |
|
=> 랜덤 트리 여러개... |
(2) hyper parameter
① n_estimators
- 하나의 데이터를 고립시키기 위해 생성하는 tree의 개수
- Default : 100
② max_samples
- Default : 256
③ contamination
- Score 계산 후, 이상치로 간주할 비율 (0.5보다 작아야 함)
(3) 모델링 절차
① 방법1
- Contamination 조정 : 학습데이터에서 Abnormal 비율로 부터 시작해서 조정하며 성능 최적화
- Validation : 예측 및 성능 평가
② 방법2
- Score 계산 및 최적의 cut-off 찾기
: x_val로 모델 생성 후 스코어 산출, cut-off 조금씩 조절하면서 F1 최대화 하는 cut-off 찾기
③ 튜닝
- Hypter-parameter 튜닝
: n_estimator, max_depth 조절하면서 튜닝 (for loop 사용)
# 가장 적합한 contamination 찾기
result = []
conts = np.linspace(0.01, 0.5, 100)
for c in conts:
model = IsolationForest(contamination = c, random_state = 20)
model.fit(x_train)
pred = model.predict(x_val)
pred = np.where(pred == 1, 0, 1)
result.append(f1_score(y_val, pred))
# 가장 큰값의 결과
print(round(max(result),3), round(conts[np.argmax(result)], 3) )
# 해당 contamination 값 입력 후 학습
model = IsolationForest(contamination=0.03, random_state = 20)
model.fit(x_train)
# 예측
pred = model.predict(x_val)
# 결과를 1,0으로 변환(np.where)
pred = np.where(pred == 1, 0, 1)
# 분류 결과를 평가
print(confusion_matrix(y_val, pred))
print(classification_report(y_val, pred))
'머신러닝 > 비지도학습' 카테고리의 다른 글
[머신러닝(비지도)] #2 - Clustering_241021 (1) | 2024.10.21 |
---|---|
[머신러닝(비지도)] #1 - 차원축소_241021 (6) | 2024.10.21 |