하마가 분석하마

[machine learning class] 5. 범주형 변수 처리-1 본문

Machine learning class

[machine learning class] 5. 범주형 변수 처리-1

Rrohchan 2021. 2. 26. 12:50

 범주형 변수는 실무에서 흔하게 접하는 변수형이다. 다양한 종류의 범주형 변수에 접근하는 방법을 알아보자. 범주형 변수는 다음 2가지 종류로 분류된다.

  • 명목형(nominal) 변수
  • 순서형 (ordinal) 변수

 명목형 변수는 범주 간의 순서가 정의 되지 않는 둘 혹은 그 이상의 범주를 가진 변수이다. 예로 성별을 들 수 있다.

 순서형 변수는 범주 간의 순서, 혹은 수준이 존재하는 범주형 변수이다. 예로 저임금, 중임금, 고임금의 3가지 수준을 갖는 임금 변수는 순서형 변수이다.

 

 두 가지 범주를 갖는 이진 변수 역시 범주형 변수에 포함시킬 수 있다. 또한 범주 간에 주기가 존재하는 주기형 (cyclic) 변수도 있다. 예로 요일과 같이 월요일부터 일요일까지 일곱 가지 범주 일주일 주기로 반복된다.

 

케글 범주형 변수 인코딩 대회 데이터

 4 종류의 범주형 변수로 구성됨

  • 명목형
  • 순서형
  • 주기형
  • 이진형

타겟 변수가 이진수인 이진분류 데이터이다.  위와 같이 타겟 변수의 분포가 편향되어있다. 따라서 AUC, 정밀도, 리콜과 같이 편향된 타겟 변수에 적합한 메트릭을 사용해야 한다. 여기선 정밀도와 리콜을 조합한 AUC를 사용하겠다.

 

 ord_2 변수를 살펴보자.

  • Freezing
  • Warm
  • Cold
  • Boiling Hot
  • Hot
  • Lava Hot

 

1. 레이블 인코딩 (Label Encoding)

 레이블 인코딩은 각각의 범주를 수치형 레이블로 인코딩하는 방식이다. 컴퓨터가 이해할 수 있도록 텍스트로 된 범주를 수치로 변환해야 한다. 가장 쉬운 방법은 총 N개의 점주가 있을 때, 각 범주를 0에서 N-1의 숫자로 매핑하는 사전을 만드는 것이다.

레이블 인코딩을 하는 방법으로 map() 메소드와 사이킷런의 LabelEncoder가 있다.
사이킷런의 LabelEncoder는 NaN을 처리하지 않기에 미리 처리해 주어야 한다.

 

2. 이진화

 트리 기반 모델에서는 레이블 인코딩된 변수를 별도의 변환없이 바로 사용할 수 있다. 그러나 변수를 표준화하여 사용하는 선형 모델, SVM, 신경망 모델에서는 레이블 인코딩된 변수를 사용할 수 없다. 이러한 모델에서는 변수를 이진화하여 사용할 수 있다.

 

ord_2 변수를 이진화변수로 변환하여 보자.

이진화

 범주 개수가 늘어남에 따라 이진화에 필요한 행의 개수도 늘어난다. 이진변수는 sparse (희소) 포맷으로 저장할 수 있다. sparse 포맷은 모든 데이터를 저장하지 않고 필요한 값만 저장하는 방식이다. 이진변수의 경우 1의 값만 저장한다. 

 

 범주형 변수 하나에 3개의 수준이 들어있다면 다음과 같이 이진화 할 수 있다.

수준이 3개인 범주형 변수를 이진화 한 결과

 

 데이터가 커질 수록 데이터를 메모리에 저장하는데 더 큰 바이트가 필요하다. 위의 경우 각각의 값이 8바이트라면 3*3크기의 데이터이므로 72바이트가 필요한 것이다. 데이터의 모든 값을 저장할 필요는 없다. 이진 행렬에서 0의 값은 다른 값에 변화를 주지 않으므로 많은 경우 무시할 수 있다. 0의 값을 무시하고 1의 값만 저장하는 한 가지 방법은 사전을 사용하는 것이다. 행과 열의 인덱스를 키로, 1을 값으로 저장할 수 있다.

 

 사전 형식을 사용하면 32바이트의 메모리만 사용한다.

 

데이터의 크기가 커질 수록 메모리 차이는 더욱 커진다. 이에 대한 예는 코드를 통해 확인할 수 있으며 깃허브에 올려놓았다.

 

 피처에 0의 값이 많은 경우  sparse  포맷이 선호된다. sparse 행렬에는 다양한 포맷이 있다. CSR 포맷은 가장 널리쓰이는 sparse 포맷이다. 더 자세한 내용은 scipy 문서에서 확인할 수 있다.

 

 위에서 본 것과 같이 범주형 변수를 이진화하여 sparse 포맷으로 저장하면 메모리를 상당히 절약할 수 있다. 그런데 이진화보다 메모리를 더 적게 사용하는 변환법이 바로 one-hot 인코딩이다.

 

3. 원핫인코딩

 원핫인코딩 역시 이진수를 사용하여 변수를 나타내지만 이진화와는 차이가 있다.

수준이 3개인 범주형 변수를 이진화 한 결과

 

원핫인코딩한 결과

 각각의 벡터는 하나의 값만 1이고 나머지 값은 0이다. 이진화보다 더 많은 0의 값을 가지는 것을 알 수 있다. 원핫인코딩 또한 이진화와 마찬가지로 범주가 커질 수록 원래의 배열과 메모리 차이가 커진다.

 

 

 범주형 변수를 사용하는 방법 중 하나로 여러 개의 범주형 변수로부터 새로운 변수를 생성하는 방법도 있다. 두 개의 범주형 변수를 결합하여 새로운 범주형 변수를 만드는 것이다. 이 경우, 값을 문자열로 변환하여 NaN값을 처리해주어야 한다.

 

 

 어떤 범주형 변수를 결합해야 하는가에 대한 답은 없다. 데이터와 피처의 종류, 그리고 해당 분야에 대한 지식이 필요하다. 머신러닝 모델링에서 범주형 변수를 처리하는 과정을 보자.

1. NaN 값을 대체한다.
2. 사이킷런의 Label Encoder나 매핑 사전을 사용하여 레이블 인코딩하여 각각의 범주를 정수로 변환한다.
3. 레이블 인코딩된 정수를 원핫인코딩한다.

 

 다양한 방법으로 NaN 값을 대체하여서 분석을 하는데 최고의 성능을 도출하도록 해야 한다.

 

 


 

 

History 변수의 수준별 개수와 타겟변수와의 관계

 데이터에 NaN 값을 대체하지 않고 사이킷런의 Label Encoder를 사용하면 오류가 뜬다. NaN 값을 대체하는 가장 간단한 방법은 해당 샘플을 삭제하는 것이다. 이 방법은 간단하지만 이상적인 방법은 아니다. 어떤 변수의 NaN 값이 중요한 정보일 수 있고 대부분의 관측치가 NaN 값일 수 있기 때문이다.

 연속형 변수일 경우, 평균, 중앙값 등으로 결측치를 대체하고 범주형 변수일 경우 최빈값 등으로 대체하기도 한다. 분석의 목적 데이터의 특성에 따라서 얼마든지 달라질 수 있다. 필자는 '직접 우편 판매 마케팅을 위한 구매 금액 예측' 프로젝트에서 과거 고객이 얼마나 구매했었는지를 알려주는 변수인 'history' 변수의 결측치를 예측하여 대체하였다. 도메인 지식을 찾아본 결과 과거 고객의 구매 정도 구매 금액에 많은 영향을 미치는 것을 알 수 있었고 여러 알고리즘을 사용하여 feature importance를 확인해 보았을 때도 'history' 변수의 중요도가 가장 높았기 때문이다. 1/5이 결측치였기에 전부 삭제하는 데에는 무리가 있었고 3가지 수준 모두 분포에서 큰 차이가 나지 않았기에 최빈값으로 대체하기에도 무리가 있다 판단하였다.

 결측치를 어떻게 처리하느냐에 따라 성능이 크게 달라진다. 저 당시에 알고리즘을 많이 알지 못하였기에 knn을 통해서 history 변수의 결측치를 예측했다. '구매 금액 예측' 프로젝트는 R을 사용했다. 코드는 링크로 달아놓겠다.

 

https://github.com/rch1025/Direct-Mail-Sales-Forecast

 

rch1025/Direct-Mail-Sales-Forecast

Predict the amount of consumers' purchases for direct mail sales forecasting We select potential customers with high purchasing power and apply them to marketing later. - rch1025/Direct-Mail-Sa...

github.com

https://github.com/rch1025/Machine-learning-class

 

rch1025/Machine-learning-class

Several concepts and several tips that are important for data analysis can be learned. I studied based on 'Machine Learning Master Class'. - rch1025/Machine-learning-class

github.com