python

[python]인공지능 데이터의 이상치/추출/시각화

살랑춤춰요 2024. 8. 1. 10:00

IQR 을 이용해 통계학적 이상치를 알아보는 코드

 

## 이상치

  - 이상치 = 극단치 + 특이치
  - 극단치는 제거하는 것이 모형에 좋다        >> 통계적 자료 분석의 결과 왜곡 > 보정 또는 삭제
  - 특이치는 그대로 사용하는 것이 모형에 좋다 >> 중상적인 수집과정에 의한 이상치(이전까지 보지 못한 패턴이나 데이터)
 
 
## 이상치(outlier) 탐지 관련 참조 사이트
https://kr.machbase.com/deep-anomaly-detection-in-time-series-2-anomaly-detection-models/

기존 이상치 탐지 방법의 주요 종류
- 3-sigma : 정규 분포에서 3표준편차의 범위 외의 데이터를 이상 데이터 취급
- boxplot : 사분위수(Quartile)와 사분범위를 이용하여 이상 데이터의 기준을 정하는 방법
- ARIMA   : 자기회귀누적이동평균, 원래는 시계열을 예측하는데 주로 이용, 이를 이용해 미래의 시계열을 예측한 후,관측 데이터와의 오차 혹은 관측값이 발생할 확률 등을 통해 이상 데이터를 판별 - 단변량(단일변수) 시계열에만 국한되어 있음 >> 단변량에 비해 불확실성이 클 수 밖에 없는 다변량 시계열의 경우 예측 기반의 이상 감지는 큰 도움이 되지 않을 수 있음
           


비지도학습 기반 이상 감지

- 오토인코더 : 입력 데이터를 보다 작은 차원의 데이터로 압축하는 Encoder와, 압축된 데이터를 다시 입력 데이터와 가깝게 복원하는 Decoder로 이루어져 있음, >> 고차원의 데이터를 더 간단하게 표현할 수 있는 저차원의 공간이 있다는 가정 필요 데이터의 양이 매우 적은 이상 데이터의 특징은 포함되기 어려움, 그렇다면 학습이 끝났을 때 AutoEncoder에 정상 데이터를 넣으면 정상적으로 복원된 출력이 나오겠지만, 이상 데이터를 넣는다면 이상 데이터의 특징은 잘 추출되지 않고 대신 입력 데이터와 그나마 가장 가까운 정상 데이터가 나올 것, 입력 데이터와 출력 데이터의 차이는 정상 데이터에 비해 클 수 밖에 없고, 이러한 차이를 이용하여 이상 데이터 감지
 
# 4분위수를 이용한 이상치를 확인
https://colinch4.github.io/2020-12-04/outlier/

- 사분위수  설명
- 제 1 사분위수(Q1)  데이터의 25%가 이 값보다 작거나 같다.
- 제 2 사분위수(Q2)  중위수, 데이터의 50%가 이 값보다 작거나 같다.
- 제 3 사분위수(Q3)  데이터의 75%가 이 값보다 작거나 같다.
- 사분위 범위(IQR)   Q3 - Q1, 데이터의 중간 50%에 대한 범위이다.

- 이상치
- 제 1 사분위수 - 1.5 * IQR 보다 작은 수
- 제 3사분위수 + 1.5 * IQR 보다 큰 수

 

def outlier_iqr(data, column):

    # lower, upper 글로벌 변수 선언하기
    global lower, upper

    # 4분위수 기준 지정하기
    q25, q75 = np.quantile(data[column], 0.25), np.quantile(data[column], 0.75)

    # IQR 계산하기
    iqr = q75 - q25

    # outlier cutoff 계산하기
    cut_off = iqr * 1.5

    # lower와 upper bound 값 구하기
    lower, upper = q25 - cut_off, q75 + cut_off

    print('IQR은',iqr, '이다.')
    print('lower bound 값은', lower, '이다.')
    print('upper bound 값은', upper, '이다.')

    # 1사 분위와 4사 분위에 속해있는 데이터 각각 저장하기
    data1 = data[data[column] > upper]
    data2 = data[data[column] < lower]

    # 이상치 총 개수 구하기
    print('총 이상치 건수는', data1.shape[0] + data2.shape[0], '이다.')
    return data1,data2

 

columns = '    '          # 확인하고싶은 특정 컬럼이름 넣기

outlier_1, outlier_2 = outlier_iqr(df,columns)   # 데이터프레임에서 특정 컬럼(채널)의 전체 데이터 분포를 활용한 이상치 탐지

plt.figure(figsize=(10,5))

sns.distplot(df_98[columns], kde=False)


# 이상치 영역 박스 그리기
# alpha 값을 올리면 더욱 진하게 볼수있다!!
 
plt.axvspan(xmin=lower, xmax=df_98[columns].min(), alpha=0.5, color='red')

plt.axvspan(xmin=upper, xmax=df_98[columns].max(), alpha=0.5, color='red')

 

<코드 실행하면 아래의 그림과같이 표현된다.>

 

 

# 이 코드를 사용하면 이상치가 어디에 있는지 확인가능
print("\n 이상치가 존재하는 목록 : {}".format(outlier_1.uid.unique().tolist()))

'python' 카테고리의 다른 글

[python]파이썬 isdigit() - 백준 1620 파이썬  (0) 2024.08.06