본문 바로가기
ML | DL | Big data/Data Science

비대칭(skewed) 데이터를 처리하는 3가지 방법 / Skewed Data

by 썽하 2020. 8. 13.

photo by Luke Chesser on unsplash

 

실세계의 데이터는 복잡하다. 완벽하지도 않다. 그렇기 때문에 일부 학습 데이터셋은 모델링에 사용되기 전에 전처리가 필요하다.

 

Linear regression 모델을 예로 들어 보자. 

  1. Linearity : 선형성. 예측 변수와 목표 변수 간의 관계가 선형이라고 가정한다.
  2. No noise : 특이치(outlier)가 없어야 한다.
  3. No collinearity : 상관관계가 높은 예측 변수가 있는 경우 과적합(overfit)이 될 가능성이 높다.
  4. Normal distribution : 예측 변수와 목표 변수가 정규 분포를 따를 때 더 신뢰할 수 있는 예측이 이루어진다.
  5. Scale : 거리 기반의 알고리즘이므로 표준 scaler처럼 모델을 스케일링해야 한다.

 

오늘은 네 번째 요점에 초점을 맞추고자 한다. 예측 변수와 목표 변수가 가우스 분포(혹은 정규분포)를 따라야 한다는 것이다. 이게 무조건 가능한 건 아니다. 어떤 분포도 완벽한 정규 분포로 변환할 수는 없지만, 그렇다고 해서 시도하지 말아야 한다는 뜻도 아니다. 

 

간단한 데이터 세트를 통해 몇 가지 마술을 시전 해보겠다.

 


데이터셋

내가 사용할 데이터는 Kaggle에 공개된 주택 가격 데이터이다.

sklearn을 통해 간단하게 가져올 수도 있겠지만, 이왕 하는 거 Kaggle 데이터로 분석해보자.(데이터 위치)

 

 

일단 캐글 데이터를 다운로드하고, 읽은 후 출력하면 다음과 같이 나온다.

 

 

나는 이 데이터로 몇 가지 테스트를 해본 적이 있고 LotArea 컬럼이 충분히 높은 skew를 가지고 있다고 알고 있기 때문에 해당 변수만 확인하겠다.

skewness를 확인하는 명령어와 seaborn 라이브러리를 사용해서 KDE plot을 확인해보자.

 

편향된 데이터가 확인된다

한눈에 봐도 정규분포를 따르지 않는다, 

skewness 값이 매우 높으며 그래프는 좌측으로 편향되어 있는 것을 확인할 수 있다.

이것을 positive skewness 혹은 left skewness라고 한다.

 

자 이제 skewed 데이터를 처리하는 몇 가지 방법을 살펴보자.

 

1. Log Transform / 로그 변환

로그 변환은 skewness(왜도)를 제거하기 위해 가장 먼저 해볼 수 있는 방법이다.

 

Numpy를 이용해 원하는 컬럼에 log() 함수를 호출하는 것만으로 쉽게 할 수 있다. 그런 다음 skew를 확인해보자.

 

 

로그 변환 전에 describe() 함수를 통해 최솟값을 확인해주었다. 만약 0보다 작다면 (최솟값 + 1)을 모든 값에 더해주는 것이 보편적이다.

 

이후 로그를 취해 변환하고 skew를 확인하니 12.x 에서 -0.1x 정도로 0에 가까운 왜도(skewness)가 나온다.

 

성급한 결론을 내리기 전에 KDE plot도 확인해보았다.

Log Transform

정규분포는 아니지만 꽤나 괜찮은 그래프가 나온다.

 

로그 변환만 사용할 수 있는 건 아니니 다른 방법도 알아보자.

 

2. Square Root Transform / 루트(제곱근) 변환

Numpy의 sqrt() 함수를 호출하여 Numpy를 통해 루트 변환을 취할 수 있다. 루트 변환도 데이터의 최솟값이 0보다 커야 한다.

 

왜도가 12.x에서 4.x까지 떨어졌다. 하지만 로그 변환보다는 효과가 덜한듯하다.

그래프도 확인해보자.

Square Root Transform

확실히 log보다는 효과가 덜하다.

 

로그 변환을 승자로 선언하기 전에 한 가지 더 살펴보자.

 

3. Box-Cox Transform / Box-Cox 변환

오늘 마지막으로 해 볼 변환 방법이다. 수식에 대해 깊이 파고들고 싶진 않으므로, 궁금한 사람들은 이 글을 참고하기 바란다.

 

다른 변환들과 마찬가지로 데이터를 변환하기 위해서는 데이터가 양수여야 한다.

scipy 라이브러리를 통해서 사용할 수 있다.

skew값을 확인해보자.

대박! 12.x에서 0.02까지 떨어졌다. 그래프는 어떨지 확인해보자.

Box-Cox Transform

log 변환과 꽤나 비슷하지만, 수치로는 Box-Cox가 더 좋다.

 

Negative(Right) Skewed Data는 어떻게 하지?

생각보다 간단하다. 그럴경우 Positive(Left) Skewed Data로 변형해 준후 동일한 변환을 진행해주면 된다.

어떻게 하느냐? -부호를 바꿔준 후 양수가 될 수 있게 적당한 값을 더해주자.

y'= -y - min(-y)
y'= -y - min(-y) + c(상수)

마무리하며

비대칭(skewed) 데이터는 머신러닝 모델을 엉망으로 만들 수 있다. 그렇기에 원본 데이터를 변환하는 과정이 필수적이다.

당연한 말이겠지만, 어떤 특성에 대해서 어떤 변환을 수행했는가를 기억해야 하는데, 예측을 할 때 동일한 절차를 진행해야 하기 때문에 이에 대해서 명심해야 한다.

 

Reference

 

 

댓글