Scikit-Learn에서는 OneHotEncoder 클래스를 이용하여 범주형 변수를 One-Hot Encoding으로 변환할 수 있다. 이번 포스팅에서는 OneHotEncoder을 이용하여 One-Hot Encoding을 수행하는 방법을 알아본다.
OneHotEncoder 사용법
여기서는 붓꽃 데이터의 붓꽃 범주를 One-Hot Encoding으로 변환해보고자 한다. OneHotEncoder는 범주형 변수가 반드시 2차원 배열로 되어있어야 한다.
import numpy as np
from sklearn.preprocessing import OneHotEncoder
from sklearn.datasets import load_iris
iris = load_iris()
category = np.array([iris.target_names[x] for x in iris.target])
category = category.reshape(-1, 1)
print('범주 벡터 사이즈 :', category.shape)
이제 OneHotEncoder를 이용하여 범주형 변수를 One-Hot Encoding으로 변환해 보자.
1) 변환 : tranform
OneHotEncoder 인스턴스를 생성하고 fit 메서드에 2차원 배열의 범주형 변수를 넣어준다. 이는 범주와 One-Hot Encoding간 매핑을 생성한다고 보면 된다. 하지만 실제로 One-Hot Encoding으로 변환된 것은 아니며 이는 transform 메서드를 통해 변환할 수 있다. OneHotEncoder는 기본적으로 sparse=True로 지정되어 있어서 transform은 scipy.sparse.csr.csr_matrix 객체를 반환한다. 따라서 실제로 변환된 결과를 보려면 toarray를 이용한다.
encoder = OneHotEncoder().fit(category) ## 범주와 One-Hot Encoding간 매핑 생성
sparse_mat = encoder.transform(category) ## 실제로 변환할 때에는 transform 사용
sparse_mat.toarray()
array([[1., 0., 0.],
[1., 0., 0.],
[1., 0., 0.],
[1., 0., 0.],
[1., 0., 0.],
'''중략'''
[0., 0., 1.],
[0., 0., 1.],
[0., 0., 1.],
[0., 0., 1.],
[0., 0., 1.]])
만약 transform을 이용하여 바로 변환 결과를 얻고 싶다면 sparse=False로 지정해줘야 한다.
encoder = OneHotEncoder(sparse=False).fit(category)
result = encoder.transform(category)
result
array([[1., 0., 0.],
[1., 0., 0.],
[1., 0., 0.],
[1., 0., 0.],
[1., 0., 0.],
'''중략'''
[0., 0., 1.],
[0., 0., 1.],
[0., 0., 1.],
[0., 0., 1.],
[0., 0., 1.]])
만약 원 범주를 확인하고 싶다면 categories_ 속성을 이용하자.
encoder.categories_
이때 각 범주의 순서대로 더미 변수가 만들어지는 것이다. 예를 들어 One-Hot Encoding으로 변환된 행렬에서 첫 번째 칼럼은 setosa, 두 번째 칼럼은 versicolor 인지를 나타내는 더미 변수인 것이다.
OneHotEncoder은 기본적으로 범주 개수만큼의 더미 변수(칼럼)를 만든다. 하지만 선형 회귀 모형에서는 선형 종속성을 피하기 위해 더미 변수 중 하나를 제거한다. OneHotEncoder의 drop 인자에 제거하고자 할 범주를 리스트에 담아서 전달하면 해당 더미 변수를 제거할 수 있다(2개 이상도 제거 가능하다). 만약 첫 번째만 제거해도 된다면 drop='first'를 하면 된다.
## versicolor에 대응하는 더미 변수 제거
encoder = OneHotEncoder(sparse=False, drop=['versicolor']).fit(category)
result = encoder.transform(category)
result
array([[1., 0.],
[1., 0.],
[1., 0.],
'''중략'''
[0., 1.],
[0., 1.],
[0., 1.]])
2) One-Hot Encoding을 범주로 바꾸기 : inverse_transform
inverse_transform을 이용하면 One-Hot Encoding으로 변환된 데이터를 원 범주로 변환할 수 있다.
encoder = OneHotEncoder(sparse=False).fit(category)
encoder.inverse_transform([[0, 1, 0],
[1, 0, 0]]) ## 원 범주로 변환
댓글