반응형

이상치 제거에서 통계적인 방법은 유용하게 사용되지만, 다루는 데이터가 복잡하고, 차원이 커질수록, 단순 분포의 개념을 활용하기는 어렵다. 이를 해결하기 위한, 이상치 제거 방법 중, 머신 러닝 기반 방법들을 몇가지 알아보기로한다. 


머신러닝을 이용한 이상치(Outlier) 제거 방법

1. Cook Distance를 이용한 방법

  • Cook Distance는 회귀분석 문제에서 이상치를 찾기 위해 많이 사용되는 방법이다.
  • 각 데이터포인트가 회귀분석 모델의 예측력에 어느 정도 영향을 미치는지를 확인하여, 이상치 제거에 활용할 수 있다. (해당 데이터 포인트를 제거한 모델이 오히려 더 좋은 예측력을 가질 때, 해당 데이터 포인트를 이상치로 간주할 수 있다. )
  • Cook Distance를 이용한 이상치 제거의 단계는 다음과 같다.
    1. 데이터 전체를 이용해서, 회귀 모델을 예측한다.
    2. 각 데이터 포인트를 제외한 데이터들로 회귀 모델을 예측한다.
    3. Cook Distance를 구한다.
    4. Cook Distance가 일정 값 (일반 적으로 1) 이상인 값들은 이상치로 취급한다.  
  • Cook Distance의 수식은 다음과 같다. 

Cook Distance

 

  • 파이썬 코드 구현
    • 파이썬의 statsmodels 패키지를 사용하면, 쉽게 Cook Distance를 구할 수 있다.
import numpy as np
import statsmodels.api as sm



if __name__ == '__main__':
    
    x = np.random.rand(10)*100
    y = 0.8*x+np.random.randn(10)*5

    alpha = 70
    beta = 10

    X = np.append(x,alpha)
    Y = np.append(y,beta)
    
    model = sm.OLS(Y, X).fit()

    influence = model.get_influence()
    cd, _ = influence.cooks_distance

    outliers = np.where(cd > 1)[0]

 

2. DBSCAN을 이용한 방법

  • DBSCAN(Density-Based Spatial Clustering of Applications with Noise)은 머신 러닝에 주로 사용되는 클러스터링 알고리즘으로 Multi Dimension의 데이터를 밀도 기반으로 서로 가까운 데이터 포인트를 함께 그룹화하는 알고리즘이다.
  • DBSCAN에 대한 자세한 내용은 https://devhwi.tistory.com/7을 참고하면 된다. 
  • DBSCAN에서 어느 Cluster에도 속하지 못한 데이터들을 Outlier로 판단한다. 

 

  • 파이썬 코드 구현
    • 파이썬의 statsmodels 패키지를 사용하면, 쉽게 Cook Distance를 구할 수 있다.
from sklearn.cluster import DBSCAN
import numpy as np
from sklearn.datasets import make_blobs


if __name__ == '__main__':
    X, y = make_blobs(n_samples=1000, centers=5, random_state=10, cluster_std=1) # 데이터 생성
    x = np.array([[-7.5,-3]]) # 이상치 데이터
    X = np.concatenate((X,x), axis=0)
    
    # DBSCAN 알고리즘 적용
    dbscan = DBSCAN(eps=1.5, min_samples=2)
    dbscan.fit(X)

    # 이상치 제거
    mask = np.zeros(len(X), dtype=bool)
    mask[dbscan.labels_ == -1] = True
    X_cleaned = X[~mask]

 

 

Cook Distance나 DBSCAN 말고도, 의사결정트리를 이용한 방법이나, LOF를 이용한 방법 등이 있다. 다시 한번 명심할 것은 이상치로 구해진 값들이, 실제 모델링에서 제거해도 되는 값들인지 꼭 확인해보아야한다. 

'Data Science' 카테고리의 다른 글

DTW(Dynamic Time Warping)  (1) 2023.06.02
PCA(Principal Component Analysis)  (1) 2023.05.04
이상치(Outlier) 제거 방법(1) - 통계적 방법  (5) 2023.03.19
반응형

이상치 제거는 데이터 분석에서 매우 중요하다. 특히, 요즘에는 어떤 모델을 사용하나 보다, 어떤 데이터로 학습할지가 모델 성능에 더 중요한 요소가 된 만큼, 이상치 제거는 그 중요성이 더욱 커졌다. 이상치 제거 방법은 정말 많지만, 자주 사용하는 몇 가지 방법을 알아보기로 한다.


이상치(Outlier) 란?

  • 이상치란 일반적인 데이터 분포를 따르지 않는 값으로, 다른 데이터와 차이가 매우 큰 값을 가진 데이터 포인트를 의미한다. 
  • 이상치가 생기는 요인은 데이터 수집 과정에서 오류가 발생하거나, 데이터 자체가 이상치를 포함하고 있는 경우, 변경점 발생으로 인한 데이터 분포 변화 등이 존재한다.
  • 이상치는 상대적인 개념이다. 즉, 어떤 데이터를 어떻게 분석하고, 어느 기준으로 이상치를 판별할 것이냐에 따라, 이상치 데이터들이 달라진다.

이상치(Outlier) 제거 방법

1. 사분위수(Quartiles) 방법

  • 사분위수 방법은 데이터분포와 값의 크기를 이용하여, 대략적인 이상치 구간을 설정해주는 방법이다.
  • 간단하고, 직관적이여서, 이상치 제거에서 많이 활용된다.
  • 통계적인 값을 기반으로 해서, 1D 데이터에서도 쉽게 활용 가능하다. 
  • 방법은 다음과 같다. 
    • 데이터를 값 기준으로 정렬한 후, 데이터의 분포에 따라 4등분하여, 각 부분의 값을 각각 1사분위, 2사분위, 3사분위, 4사분위로 나타낸다. (하위 0~25%, 25~50%, 50~75%, 75~100%)
    • 1사분위 수(값 기준 하위 25%되는 값)와 3사분위 수(값 기준 상위 25%되는 값)을 찾는다.
    • 3사분위 수와 1사분위 수의 차로 IQR(Interquartile Range)을 구한다. 
    • 일반적으로 1사분위 수와 3사분위 수에서 IQR의 특정 배수(일반적으로 1.5) 이상 벗어난 값들을 이상치로 판정하고 제거해준다.

  • 파이썬 코드 구현
import numpy as np

def outlier_remove(data, threshold=1.5):
	q1, q3 = np.percentile(data, [25, 75]) # 1사분위수, 3사분위수 계산
	IQR = q3 - q1 # IQR 계산

	lower_bound = q1 - (threshold * IQR) # Outlier 판단 Lower Bound 계산
	upper_bound = q3 + (threshold * IQR)  #Outlier 판단 Upper Bound 계산
    
	filtered_data = [x for x in data if x >= lower_bound and x <= upper_bound]
	outlier = [x for x in data if x not in filtered_data]
    
	return filtered_data, outlier, q1, q3, iqr, lower_bound, upper_bound

if __name__ =='__main__':
	X = np.random.normal(0, 1000, 1000)
	filtered_data, outlier, q1, q3, IQR, lower_bound, upper_bound = outlier_remove(X)

 
2. Z-score 방법

  • Z-score 방법은 데이터의 평균과 표준편차를 이용해, 이상치를 제거하는 방법이다. 
  • Z-score 방법은 데이터의 분포가 정규분포를 따른다는 가정이 필요하다. 
  • 통계적인 값을 기반으로 해서, 1D 데이터에서도 쉽게 활용 가능하다.
  • 방법은 다음과 같다.
    • 데이터 포인트들의 평균과 표준편차를 구한다.
    • 각 데이터 포인트의 Z-score (Z = |x - μ|/ σ)를 구한다. Z-score는 데이터 포인트가 평균과의 거리가 몇 sigma 범위에 있는지를 의미한다.
    • Z-score가 특정 threshold(일반적으로 3) 이상인 값들은 이상치로 판정하고, 제거해준다.

  • 파이썬 코드 구현
import numpy as np

def outlier_remove(data, threshold=3):
    z_scores = np.abs(data - np.mean(data)) / np.std(data) # Z-score 계산
    
    filtered_data = data[z_scores < threshold]
    outlier = data[z_scores>threshold]
    
    return filtered_data, outlier

if __name__ == '__main__':
    X = np.random.normal(0, 1000, 1000)
    filtered_data, outlier = outlier_remove(X)

 

+ Recent posts