세로형
Recent Posts
Recent Comments
Link
04-20 00:01
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Archives
Today
Total
관리 메뉴

꿈 많은 사람의 이야기

머신러닝, 딥러닝 이상치(outlier) 데이터 탐지 및 제거 하기 - outlier data detection and remove 본문

machine learning(머신러닝)

머신러닝, 딥러닝 이상치(outlier) 데이터 탐지 및 제거 하기 - outlier data detection and remove

이수진의 블로그 2019. 12. 15. 19:39

포스팅 개요 

이번 포스팅은 머신러닝과 딥러닝에서 많이 사용하는 데이터 이상치 탐지(outlier detection)에 대해서 작성합니다.

또한, 지난 포스팅인 캐글의 신용카드 사기 탐지 대회 데이터셋(kaggle credit card fraud detection data)을 이용하며 신용카드 사기 탐지 3편입니다.

 

참조한 자료는 kaggle의 커널(https://www.kaggle.com/janiobachmann/credit-fraud-dealing-with-imbalanced-datasets) 입니다. 그 외의 참조 자료는 구글링 자료입니다.

 

코드는 아래 github에 존재합니다.

https://github.com/lsjsj92/machine_learning_basic

 

lsjsj92/machine_learning_basic

Repo for everyone who wants a machine learning basic - lsjsj92/machine_learning_basic

github.com

의 11번 글입니다.

 

 

이전 글은 아래 링크와 같습니다.

https://lsjsj92.tistory.com/555

 

머신러닝으로 신용카드 사기 탐지하기 2편 - 데이터 정규화(data normalization)

포스팅 주제 더보기 이번 포스팅은 지난 포스팅에 이어서 캐글의 신용카드 사기 탐지(kaggle credit card fraud detection) 데이터를 활용합니다. 또한, kaggle credit card fraud detection의 커널 중 https://ww..

lsjsj92.tistory.com

 


포스팅 본문

들어가기 앞서

지난 포스팅까지 머신러닝으로 신용카드 사기를 탐지하는 것에 대해서 계속 올리고 있습니다.

첫 번째 포스팅에서는 데이터에 아무런 변화를 주지않고 진행해보았고 두 번쨰 포스팅에서는 로지스틱 회귀(logistic regression)의 성능을 올리기 위해 데이터 정규화(data normalization)을 진행했었죠.

하지만 캐글(kaggle)에서 제공해주는 이 신용카드 사기 탐지 데이터 셋(credit card fraud dataset)에서 상위 랭크에 올라가려면 한 가지 기술?을 써야합니다.

바로 데이터의 이상치 탐지(outlier data detection)을 해야합니다. 그리고 이상치 데이터를 제거해야하죠(remove outlier data)

그래서 먼저 이 데이터의 이상치 탐지를 하는 방법에 대해서 소개하고 가봅니다.

 

데이터 이상치 탐지(data outlier detection)

데이터의 이상치라는 것은 무엇일까요?

말 그대로 이상(문제)이 있는 데이터를 뜻합니다. 일반적인 데이터 패턴과 다르게 매우 이상한 패턴을 가지고 있는 등의 데이터를 뜻하죠.

머신러닝과 딥러닝에서는 이러한 이상치 데이터 때문에 모델의 성능이 크게 좌우됩니다. 

모델의 입장에서는 데이터의 패턴을 보아야 하는데 이러한 이상치 데이터(outlier)들 때문에 모델 입장에서는 좀 뜬금없는 패턴을 학습하게 되니까요. 그래서 이상치 탐지(outlier detection)은 정말 중요합니다.

그리고 보통 이러한 이상치 데이터를 제거합니다.(remove outlier data)

 

그러면 데이터 이상치 탐지는 어떻게 할까요?

대표적인 방법은 IQR이라는 방법이 있습니다. IQR(Inter Qunatile Range)은 사분위 값의 편차를 이용합니다. 이는 boxplot으로도 볼 수 있죠.

사분위는 데이터를 값이 높은 순으로 정려하고 1/4씩 쪼갠것을 뜻합니다. 즉, 아래와 같죠.

  • 25%(1/4 지점) : Q1
  • 50%(2/4 지점) : Q2
  • 75%(3/4 지점) : Q3
  • 100%(4/4 지점) : Q4

반응형

IQR은 여기서 Q1 ~ Q3 지점을 뜻합니다. 즉, IQR = Q3 - Q1가 되겠죠.

IQR을 이용해서 이상치(outlier)를 탐지하는 것은 IQR에서 어떤 숫자값을 곱해서 구합니다.

어떤 숫자는 보통 1.5를 사용합니다. 

즉, IQR * 1.5를 곱해서 이를 Q3에 더하고, IQR * 1.5 값을 Q1에서 뺍니다.

Q3에 더한 값을 최대값, Q1에서 뺀 값을 최소값이라고 합니다.

그리고 저 최대값, 최소값보다 크거나, 작은 값들을 이상치(outlier)라고 합니다.

이를 boxplot으로 보면 아래 그림과 같습니다.

 

 

저 아래에 있는 동그라미 점이 이제 outlier data가 되는 것입니다.

즉, lower extreme보다 작은 값, upper extreme보다 큰 값은 이상치 인 것이죠.

자! 이제 신용카드 사기를 머신러닝으로 탐지하기 위해서 이 이상치를 제거하려고 합니다.

 

머신러닝 신용카드 사기탐지를 위해 이상치 제거하기(remove outlier data)

그러나 문제가 있습니다.

모든 데이터에서 이상치를 제거하면 너무 많은 데이터가 제거가 됩니다.

그렇기 때문에 우리가 원하는 target(y)에 영향이 미치는 column에서 이상치를 탐지하고 제거해야합니다.

여기서의 target은 신용카드 사기 여부이겠죠?

자! 그러면 이 target과 연관성이 높은 column이 어떤 것인지 corr을 이용해 확인해보죠

 

 

python seaborn의 corr을 통해 확인해보면 위와 같은 그림을 볼 수 있습니다.

여기서 보니까 V14, V17의 색상이 class와 비교했을 때 낮게 나타나는 것을 볼 수 있습니다. 뭔가 음의 연관성을 보이는 것이죠. 그러면 이 V14, V17의 데이터를 확인해봅니다.

seaborn의 boxplot을 이용해서 V14, V17의 데이터가 target과 어떤 연관이 있는지 보죠.

sns.boxplot(x='Class', y='V17', data=data, ax=axs[0])과 같이 python seaborn을 이용해서 확인해봅니다.

V14, V17을 보니까 target이 0, 1에 있어서 서로 다른 분포를 보여주는 것이 보입니다.

즉, V14와 V17이 어떤 컬럼인지는 모르겠지만 0과 1을 구분할 수 있는 중요한 컬럼이라는 것을 확인할 수 있죠.

헷갈리실까봐 다른 컬럼과 비교해보겠습니다.

V20, V21은 target에 별 영향이 없는 컬럼인데요. 얘내를 똑같이 boxplot으로 확인해보죠

 

 

V14, V17과의 차이점이 보이시나요? 이 두개의 컬럼은 target이 0, 1일 때 둘 다 분포가 비슷합니다. 즉, target을 정할 수 있는 어떤 컬럼이 아니라는 뜻이죠.

그래서 V14, V17 컬럼을 사용해서 이상치를 제거하겠습니다.

 

자, 먼저 원본 데이터를 살리기 위해 data copy를 하겠습니다.

그리고 함수를 하나 만드는데요. IQR을 계산하고, 그 이상치를 탐지 후 제거하는 역할을 합니다.

np.percentile(data, 25)를 하게 되면 25% 즉, Q1 지점의 데이터를 가져올 수 있습니다.

마찬가지로 Q3를 구해서 Q3 - Q1을 해주면 iqr이 나오게 되는데요.

여기서 1.5를 곱한 뒤 Q1에서 빼주고(최소값), Q3에서 더해줍니다(최대값)

그리고나서 최소값보다 작은 데이터 또는 최대값보다 큰 데이터의 index를 가져와 그 index를 drop해줍니다.

 

300x250

V14의 컬럼을 확인하니 이상치 데이터가 14149개가 있네요. 그럼 이 제거된 데이터를 가지고

머신러닝 모델을 돌려보겠습니다.

기대기대!

 

 

오잉? 근데 어떻죠? 완전 망했습니다. 모델이 완전 박살이 났어요.

분명히 이상치 탐지를 하면 더 좋은 모델이 나온다고 말씀드렸는데 오히려 더 구린 모델이 나왔습니다. 왜일까요?

제가 생각하는 그 이유는 아래와 같습니다.

"전체 데이터 셋에서 outlier를 구하니까 데이터 셋 자체가 망가졌다. 즉, 전체 데이터 셋 기준 outlier이므로 데이터 셋이 틀어진 것으로 추측"

 

그래서 내가 원하는 컬럼에 대해서 outlier를 제거하는데 우리가 원하는 target에 따라서 데이터를 좀 더 세분화하려고 합니다.

즉, Class가 0이면 신용카드 사기가 아니고, 1이면 신용카드 사기인 데이터이므로

Class = 0일 때와 Class = 1일 때를 따로 나누어서 outlier를 탐지하고 그것을 기반으로 모델을 학습하려고 합니다.

그래서 함수를 아래와 같이 바꾸면 됩니다.

d_cp[d_cp['Class'] == 0][column] 또는 저 0을 1로 바꾸면 되는 것이죠!

 

 

자! 저는 가장 먼저 class가 1일 때 테스트를 해보았습니다. 

지난 포스팅 기준 lightgbm의 성능과 logistic regression 성능은 아래와 같습니다.

lightgbm

  • f1-score : 0.86
  • auc : 0.89

logistic regression

  • f1-score : 0.75
  • auc : 0.83

근데 제거한 뒤 성능은 어떤가요? 모델 성능이 좋아졌습니다.  1~3%정도 상승했죠.

그러면 class가 0일 때 기준으로 outlier를 제거하면 어떨까요?

성능이 훨씬 좋아졌습니다.

class가 0일 때 제거하면 더 성능이 좋은 이유가 0인 데이터가 더 많고, 0일 떄 outlier가 더 많기 때문입니다.

자!

이로써 머신러닝, 딥러닝에서 많이 활용하는 이상치 데이터(outlier data detection and remove) 를 탐지하고 제거하는 방법에 대해서 알아보았습니다.

반응형
그리드형
Comments