데이터에서 이상치를 찾아보자 "1. EDA"

2022. 9. 25. 20:04Data Science

* anomaly / outlier란?

  평소 데이터에서 거리가 먼 녀석, 특이한 녀석이라고 생각하면 되겠다. 보통은 이런 녀석들이 실제 우리 real-life에서 문제를 일으키는 녀석들이다.  

 


 예를 들면 본인이 무언가를 관리하는 엔지니어라고 생각해보자. 실질적으로 엔지니어의 메인 role중 하나는 이러한 이상치를 모니터링 하고 억제하기 위한 행위이지 않는가? 하다 못해 갑자기 내 주식 계좌가 녹으면 그것 또한 이런 케이스에 빗댈 수도 있겠다. 

 

우선 이러한 이상치 찾는 문제는 3가지로 볼수 있다. 


1. Supervised : 쉽게 말해서 데이터 내에 이것 이상치, 이건 정상치가 아니란 라벨이  다 나와있는 것 들이다. 족보가 있고 원리를 학습해서 새로운 문제에 대응하는 개념으로 보면 되겠다.  Classification 알고리즘을 씀.

 

2. Semi-Supervised : 이것도 유사한데 정상치 데이터만을 가지고 학습하고,  새로운 데이터에 대해서 정상치와 다르다는 것을 예측하는 개념으로 보자.  Autoencoder가 주로 이용된다. 

 

3. Un-supervised : 이건 아예 정보가 없는 상태에서 학습해서 찾아내는 개념이다.

 

우리 내 삶도 그렇다. 항상 우리는 기대한다. 이미 잘 정리되어 있는 업무를 받고 싶지만, 실제에서는 답을 주지 않는다. 대부분은 케이스는 3번을 요구할 것이 자명 한게 그 이유.

 

그럼 1번,2번은 실제로 쓸일이 없을 것 같으니 다음으로 미루고, 3번에 대해서 모카 커피 한잔 마시면서 봐보자.

 

우선은 전통적인 방법 

삼성전자 주식을 생각해보자

 나같으면..

 5만원 이하면 = 풀 매수 (당연히 분할 매수)

 5만원 이상이면 = 단타/단기 스윙

 6만원 이상이면 = 매도

이런 룰을 생각하고 있다. 주가 차트를 보고 만들어 보았다.

 

이말인 즉슨 가지고 있는 데이터를 탐색하고 들여다 보는게 선행 되어야 되지 않겠는가?

결국에는 EDA (Exploartory Data Analysis) 말만 어렵지 이런 개념 아니겠는가

 

들여다 봐야 한다는 말인데.. 숫자를 시각화 해서 먼가 추론해 볼 수 있을 것 같다.

 

우선은 실제 case를 좀 가지고 와서 그래프를 그려보자.

우리가 간단하게 들여다볼 데이터는 저항측정 값이다.

 

선으로 좀 그려볼까?

pandas 데이터 프레임에 집어 넣은 후 간단히 그려보자.

df2.Meas.plot(figsize = (10,4))

 

<약 25000개의 측정 값>

0.0023~0.0024 사이쯤을 중심으로 랜덤하게 있는 듯한 데이터 형상. 

감이 잘 안오는데 점으로 그려보고 히스토그램도 그려보자 그럼 감이 잡힐듯..

import seaborn as sns
fig, axes = plt.subplots(3,1,figsize=(10,8))
sns.histplot(data=df2,x='Meas', ax= axes[1])
df2.Meas.plot(ax=axes[0])
sns.scatterplot(data= df2.reset_index(), x='index', y ='Meas', ax = axes[2])
plt.show()

 

두번째 히스토그램에서 먼가 gaussican 분포 같은 모양을 확인 할 수 있다.

표준 시편을 측정한 데이터라면 측정기의 성능을 확인 하는데도 활용 가능 하겠지만. 이 데이터는 그런 의미는 아니다.

 

fig, axes = plt.subplots(3,1,figsize=(10,8))

hist_plot =sns.histplot(data=df2,x='Meas', ax= axes[1])
hist_plot.axvline(0.00205, c ='r', ls = '--',label = 'LSL 0.00205')
hist_plot.axvline(0.00265, c ='b', ls = '--',label = 'USL 0.00265')
axes[1].legend(loc = 'upper right')

line_plot = df2.Meas.plot(ax=axes[0])
line_plot.axhline(0.00205, c = 'r', ls = '--', label = 'LSL 0.00205')
line_plot.axhline(0.00265, c = 'b', ls = '--', label  = 'USL 0.00265')
axes[0].legend(loc = 'upper right')

scatter_plot = sns.scatterplot(data= df2.reset_index(), x='index', y ='Meas', ax = axes[2])
scatter_plot.axhline(0.00205, c = 'r', ls = '--', label = 'LSL 0.00205')
scatter_plot.axhline(0.00265, c = 'b', ls = '--', label  = 'USL 0.00265')
axes[2].legend(loc = 'upper right')
plt.show()

별다른 테크닉 없이 히스토그램을 믿고, 그리고 나를 믿고. 허허..

직관적으로 LSL, USL을 그려보면. 이상치가 찔끔 보이기는 하는 구만.

이른바 시각화로 EDA를 해봤다. 

 

그런데 문제는 이렇게 처다보고 설정하는 개념의 치명적인 단점이 있다.

별다른 Rule없이 내맘대로 선을 그었지 않는가?

그리고, 데이터 분포는 시스템과 주변 환경에 영향을 받지 않겠는가?

결국엔 좀 더 고급진 방법을 시도해봐야 한다. 

 

물론 고급진 음식을 먹기 전에 이러한 디저트나 식전 음료를 먹는 것은 국롤이다.

간을 보지 않고 요리 하는 게 손님들한테 먹힐 리 만무 하지 않은가?

 

우선은 EDA를 간단하게 해봤고

내가 가져온 데이터는 단일 변수 데이터임으로 다음시간에는 Turkey's Method에 대해서

살짝 확인해보고 실제로 실행 해보자. 

 

모카 커피를 다 후루룩 해버렸으니 이제 일어나야 겠다.