티스토리 뷰

Study/AI

[ML] Categorical Variable을 수치화시키기

생각많은 소심남 2017. 12. 26. 00:12

 사실 이전 포스트에 이어서 계속하던 작업은 국가와 나이, 연봉의 data를 가지고 이 사람이 물건을 살 것인가 아닌가에 대한 예측을 하기 위한 강의 예제를 따라하고 있었다. 그래서 주어진 dataset을 다시 가져오면 다음과 같다.

주어진 field는 4가지 인데, 우리가 구해야 할 결과는 Purchased라고 표기된 부분이고, 이를 위해서 활용해야 할 field는 Country와 Age, Salary field이다. 보통 전자와 같은 자료를 dependent variable, 후자와 같은 자료를 independent variable이라고 말한다. 이중 다른건 모르겠는데 Country field나 Purchased field 같은 경우는 자료가 String 형식으로 되어 있다. 이런 학습에 대해서 잘 모르는 사람이라면 "머신러닝이면 뭐든 학습을 시킬 수 있으니 저 값도 그대로 학습시킬 수 있겠지" 라고 생각할 수 있지만, 사실 뭔가 모델화시키고 학습을 시키기 위해서는 data를 모두 수치화시켜야 한다. 특히 Country와 같은 자료는 정해진 범위내에서 각 data를 구분지을 수 있는데 이런 형식의 data를 categorical variable 이라고 말하고, 이를 수치화하는 과정이 필요하다. 예를 들어 위와 같이 Spain과 Germany,France가 있는 경우에는 Spain은 0, Germany는 1, France는 2라고 내부적으로 정의를 두고 학습을 해야 한다는 것이다. 이때 사용되는게 LabelEncoder라는 것이다. (아마 이전 ANN 구현때도 이 package 사용을 봤을 것이다.)

 labelEncoder 사용은 무척 간단하다. 역시 sklearn.preprocessing package에 포함되어 있고, 이를 사용하기 위해서는 labelEncoder 객체를 생성한 후, 수치화시키고자 하는 field를 해당 객체를 통해서 변형시키면 되는 것이다. 

  1. # Importing the libraries
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. import pandas as pd
  5.  
  6. np.set_printoptions(threshold=np.nan)
  7.  
  8. # Importing the dataset
  9. dataset = pd.read_csv("Data.csv")
  10. = dataset.iloc[:, :-1].values
  11. = dataset.iloc[:, 3].values
  12.  
  13. # Taking care of missing data
  14. from sklearn.preprocessing import Imputer
  15. imputer = Imputer(missing_values='NaN', strategy='mean', axis=0)
  16. imputer = imputer.fit(X[:, 1:3])
  17. X[:, 1:3] = imputer.transform(X[:, 1:3])
  18.  
  19. # Encoding categorical data
  20. from sklearn.preprocessing import LabelEncoder
  21. le = LabelEncoder()
  22. X[:, 0] = le.fit_transform(X[:, 0])

 이렇게 하면 X는 다음과 같이 변경된다.

그런데 여기서 유의를 해야할 부분이 있다. 막상 수치화를 시켜놓으면 위와 같이 France는 0, Germany는 1, Spain은 2로 변하는데, 이 값을 잘 못 분석하면 Spain이 Germany보다 좋구나, 혹은 Spain이 France보다 훨씬 좋구나 하는 결론을 내릴 가능성이 생긴다. 원인은 0,1,2 자체가 가지는 대소관계 때문이다. 이런 관계를 가지는 변수는 보통 Ordinal Variable이라고 하는데, 우리가 분석하고자 하는 데이터는 이런 대소 관계를 가지면 안되기 때문에 다른 방식으로 값을 처리해야 한다. 내가 듣는 강의에서는 다음과 같이 소개하고 있다.

<Dummy Encoding>

 우리는 하나의 Country 라는 field내에서 세가지 값을 구분했지만, 이를 분석할 때는 실제 data에 없는 변수들을 임의로 만들어 처리하는 것이고, 보통 이런 변수들을 Dummy Variable이라고 하고, 강의에서는 이와 같은 처리 방식을 Dummy Encoding이라고 표현하고 있다. (좀 이상한게 강의에서는 dummy encoder와 one hot encoder를 동일하게 정의하고 있다. 그런데 실제 찾아보면 dummy encoder와 one hot encoder가 다른 것으로 언급되어 있는데 이부분은 좀 찾아봐야 할것 같다...출처)

 아무튼 위와 같이 Dummy variable을 생성해서 처리하고 싶으면 잠깐 소개한 것처럼 One Hot Encoder를 사용해야 한다. 참고로 OneHotEncoder의 정의는 다음과 같이 되어 있다.

 여기서 우리가 정의해야 할 인자는 categorical_features이다. 여기에는 우리가 실제로 dummy variable을 생성하고자 하는 원래 data field를 정의해줘야 하는데 위의 예제에서는 0번 column이므로 이를 집어넣어주면 된다. 그래서 아래 코드를 수행한 후에 결과를 살펴보면 다음과 같다.

  1. # Encoding categorical data
  2. from sklearn.preprocessing import LabelEncoder, OneHotEncoder
  3. le = LabelEncoder()
  4. X[:, 0] = le.fit_transform(X[:, 0])
  5.  
  6. # Add One Hot Encoder(ohe)
  7. ohe = OneHotEncoder(categorical_features=[0])
  8. = ohe.fit_transform(X).toarray()


 정상적으로 dummy variable이 생성되고 각 country 별로 field가 정의된 것을 확인할 수 있다. 이와 마찬가지로 Purchased field도 labelEncoder를 통해서 값을 수치화시킬 수 있다. 참고로 이때는 Yes냐 No냐에 대해서만 구분하면 되므로 일부러 Dummy variable을 생성할 필요가 없다.

  1. # Encoding categorical data
  2. from sklearn.preprocessing import LabelEncoder, OneHotEncoder
  3. le = LabelEncoder()
  4. X[:, 0] = le.fit_transform(X[:, 0])
  5.  
  6. # Add One Hot Encoder(ohe)
  7. ohe = OneHotEncoder(categorical_features=[0])
  8. = ohe.fit_transform(X).toarray()
  9.  
  10. # Encoding categorical data in y
  11. le = LabelEncoder()
  12. = le.fit_transform(y)


 위와 같이 LabelEncoder만 사용해서 Yes/No를 각각 0과 1로 변환시킨 것을 확인할 수 있다.

서두에서 이야기한 것처럼 우리가 뭔가 학습을 시키고자 할 때는 학습 모델이 해당 데이터를 인지할 수 있도록 수치화된 값으로 변환하는 과정이 필요하고 이를 위한 tool로 LabelEncoder와 조금더 많은 categorical data를 분리할 수 있는 OneHotEncoder에 대해서 사용하는 방법을 알아봤다.


출처 : Machine Learning A-Z : Categorical Data

댓글