AI & 빅데이터/데이터 주물럭( + feature engineering)

[데이터전처리] Outlier(이상치/이상값/특이값/특이치 등) 탐지 방법(detection method) : 3. Isolation Forest 알고리즘 with 파이썬

Clary K 2020. 11. 20. 15:43
728x90

Isolation Forest는 앙상블 의사 결정 트리 기반 모델에 속하는 비지도 학습 알고리즘으로 의사 결정 트리를 기반으로 구축되었다. 이 방식은 먼저 올린 IQR이나 Z-score 방식 외 주요 인기있는 이상 감지 알고리즘과는 많이 다르다. 다른 다수의 방식들은 데이터의 정상 영역을 찾는 것을 시도한 다음 정상 영역이라고 정의한 영역 외부의 모든 항목이 이상치 또는 비정상인지를 식별한다.

 

 

Isolation Forest 알고리즘 개념 

그러나 Isolation Forest 방법은 다르게 작동한다. 데이터에 Isolation Forest 알고리즘을 적용하면 이상값들이 일반 지점에 비해 나머지 샘플에서 분리(격리)되는 경향이 있다. 그래서 각 데이터 포인트에 점수를 부여하여 정상적인 관측값과 영역을 프로파일링하고 구성하는 대신 이상값을 구분하여 격리시킬 수 있다. 이 알고리즘이 정의하는 이상값은 소수이고, 일반적인 관측값과 매우 다른 속성 값을 가지고 있다는 사실을 활용한다. 데이터 포인트를 분리하기 위해 알고리즘은 속성을 무작위로 선택한 다음 해당 속성에 허용되는 최소값과 최대값 사이에서 속성에 대한 분할 값을 무작위로 선택하여 샘플에 대한 파티션을 반복적으로 생성한다.

재귀적인 분할(recursive partitioning)은 트리 구조로 나타낼 수 있으며, 분리하는 지점을 격리하는 데 필요한 파티션의 수는 트리 내에서 시작 노드에 도달하기 위한 경로의 길이로 해석한다. 이러한 랜덤한 트리에서 평균을 낸 경로의 길이는 정규성과 그것을 결정하는데 작용하는 척도가 된다. 랜덤 파티셔닝(분할)이 어떤 포인트가 이상값이라고 탐지할 때에는 눈에 띄게 짧은 경로를 생성한다고 한다. 따라서 랜덤한 트리가 특정한 샘플에 대해 집합적으로 더 짧은 경로 길이를 생성 할 때 이상값일 가능성이 높다고 판단한다. 

이러한 특성 때문에 매우 높은 차원의 데이터셋에서도 잘 작동하며 이상을 탐지하는 매우 효과적인 방법임이 입증되었다. 지난번에 포스팅한 IQR과 Z-score는 고차원의 데이터셋에는 잘 사용하지 않는다고 하니 기억하면 좋음!!

(>> 여러 자료들을 보면서 몇번이나 읽어가면서 쉽게 이해할 수 있도록 진짜 많이 다듬었지만 그래도 쉽게 정리가 되지 않는다.. ㅠ_ㅠ)

 

정상 관측값과 비정상인 이상값을 식별하는 아이디어는 하단의 그림에서 확인할 수 있다.

(그림을 보면 드디어 이해가 쉬울 것이다!!)

정상 관측값(왼쪽)은 이상값(오른쪽)보다 더 많은 파티션을 식별해내야 한다.

 

원문 : https://towardsdatascience.com/outlier-detection-with-isolation-forest-3d190448d45e

 

공식은 다음과 같다고 한다.

 

여기서 h(x)는 관측치 x의 경로 길이이고, c(n)은 이진 검색 트리에서 실패한 검색의 평균 경로 길이이며, n은 외부 노드의 수를 말한다. 각 관찰 포인트에는 이상값에 대한 점수가 주어지며 그에 따라 다음과 같은 결정을 내릴 수 있다.[[1] Liu, F. T., Ting, K. M., & Zhou, Z. H. (2008, December). Isolation forest. In Data Mining, 2008. ICDM’08. Eighth IEEE International Conference on (pp. 413–422). IEEE. 참고]

 

 

Isolation Forest 공식 대입한 점수 판단

그리하여 공식을 사용한 점수는 다음과 같은 기준으로 판단하면 된다.

  • 1에 가까운 점수는 이상값을 나타낸다.
  • 0.5보다 훨씬 작은 점수는 정상적인 관측값을 나타낸다.
  • 모든 점수가 0.5에 가까우면 전체 샘플에서 명확하게 구별되는 이상이 없다고 판단한다.

 

 

파이썬에서 Isolation Forest 알고리즘으로 이상값 탐지하기

 

위의 과정을 파이썬으로 실행해보자.

일단 필요한 라이브러리들을 불러온다!

넘파이, 맷플롯립, 오늘의 주인공 Isolation Forest 알고리즘은 사이킷런으로부터 제공받을 수 있다 ^^

import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import IsolationForest

 

실험 할 데이터셋은 따로 없기 때문에 넘파이로 생성해줄 것이다.나중에 다시 똑같은 결과 구현을 위하여 랜덤 스테이트를 설정하여 학습 데이터를 생성하여 X_train으로 저장한다. 그리고 학습 데이터와 비슷한 수준의 데이터들을 추가해주어 X_test로 저장해주고, 이상값 구현을 위하여 인위적으로 정규 패턴에 어긋나는 데이터들을 추가하여 X_outliers로 저장해준다.

# 랜덤 스테이트 수치 설정하기
state_value = np.random.RandomState(20)

# 학습 데이터 생성하기
X = 0.3 * state_value.randn(100, 2)
X_train = np.r_[X + 2, X - 2]

# 정규값과 비슷한 데이터 추가해주기
X = 0.3 * state_value.randn(20, 2)
X_test = np.r_[X + 2, X - 2]

# 정규적이지 않은 데이터 추가해주기(인위적인 이상값 구현을 위함)
X_outliers = state_value.uniform(low=-4, high=4, size=(20, 2))

 

아웃라이어 탐지 모델을 만들어주고 위에서 만들어놓은 데이터셋 3개에 각각 피팅(또는 적합)을 시켜줄 것이다.생성한 모델을 살펴보면 max_samples라는 파라미터가 있는데 이것은 기본 추정량을 훈련하기 위해 X에서 추출 할 샘플 수를 말한다. 

또 사용해볼만한 파라미터로 contamination이 있는데 데이터셋의 오염 정도, 즉 데이터 세트의 이상값 비율을 말한다. 피팅 할 때 샘플 점수에 대한 임계 값을 정의하는 데 사용된다고 한다. 기본적으로 'auto'로 설정되어 있어서 나는 따로 설정을 하진 않았다. 만약 수치를 설정하고 싶다면 반드시 [0, 0.5] 범위에서 사용해야 한다고 한다.

# IsolationForest 모델 만들기
isol = IsolationForest(max_samples=100, random_state=state_value) 

# 만들어 둔 데이터셋에 알고리즘 피팅시키기
isol.fit(X_train)
y_pred_train = isol.predict(X_train)
y_pred_test = isol.predict(X_test)
y_pred_outliers = isol.predict(X_outliers)

 

피팅시킨 결과인 y_pred_train, y_pred_test, y_pred_outlier에서 1개만 확인해보도록 하겠다.

y_pred_test를 확인해보았더니 다음과 같은 결과의 array가 나왔다.

out :

array([-1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1])

 

이 배열은 각 데이터 포인트에 대한 예측을 출력한 것이다. 결과가 -1이면 데이터 포인트가 이상 값임을 의미한다. 결과가 1이면 데이터 포인트가 이상값이 아님을 의미한다.

 

y_pred_outlier를 확인해보면 전부 -1만으로 이루어진 배열값이 나온다.

아웃라이어들만 모여있으니 당연한 것이다 -ㅅ-;;

알고리즘이 작동하여 이상값들을 탐지해내었으니 시각화를 통하여 눈으로 확인해보도록 한다 'ㅡ'

 

# 샘플 데이터 및 가까운 벡터를 평면에 플로팅하기
xx, yy = np.meshgrid(np.linspace(-5, 5, 50), np.linspace(-5, 5, 50))
Z = isol.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

# 캔버스 사이즈 정의 및 타이틀 작성하기
plt.figure(figsize=(12,8))
plt.title("Isolation Forest Outlier visualization edited by Clary K")

# 학습 데이터, 테스트 데이터, 결측값 데이터 각각 스캐터플로팅 하기
plt.contourf(xx, yy, Z, cmap=plt.cm.binary)
ob1 = plt.scatter(X_train[:, 0], X_train[:, 1], c='white',
                 s=20, edgecolor='k')
ob2 = plt.scatter(X_test[:, 0], X_test[:, 1], c='yellow',
                 s=20, edgecolor='k')
ab = plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c='red',
                s=30, edgecolor='k')

# X, y축 범위 지정 및 범례 지정해주기 
plt.axis('tight')
plt.xlim((-5, 5))
plt.ylim((-5, 5))
plt.legend([ob1, ob2, ab],
           ["training observations",
            "test observations", "new abnormal observations"],
           loc="upper left")
plt.show()

 

짜잔! 요렇게 시각화가 출력되었다.

데이터 포인터들이 잘 보이도록 그래프 배경을 모노톤으로 해주었고, 이상값들은 조금 더 잘보이도록 사이즈를 살짝 키워주었다^^

(사이킷런에서 만든 것보다 좀 더 세련되게 만들어보았다 =___=;;)

그래프를 보면 이상값들이 대부분 정상 관측치들이 많은 영역 외에 포진되어 있는데 정상적인 관측값 영역 가까이에 있는 데이터 포인트들도 소수이긴 하지만 있긴 있다. 

 

 
 
 
 
 
 
 
 
 
 
다음 시간에는 다른 알고리즘 탐지 포스팅으로!! >.<
 
 
 
Clary K
 
 
 
 
 

[참고 사이트]

 

Anamoly Detection: Techniques to detect outliers

Anomaly detection is the identification of rare items, events, or observations that raise suspicions by differing significantly from the…

towardsdatascience.com

 

Outlier Detection with Isolation Forest

Learn how to efficiently detect outliers!

towardsdatascience.com

 

sklearn.ensemble.IsolationForest — scikit-learn 0.23.2 documentation

 

scikit-learn.org

 

 

다음 시간에는 다른 알고리즘 탐지 포스팅으로!! >.<

 

Clary K

728x90