カテゴリカル変数を変換するsklearnのLabel/OneHotEncoderとpandasのget_dummies

pythonmachinelearning

次のデータを用いる。

data = ["tokyo", "berlin", "paris", "amsterdam", "paris", "amsterdam", "berlin"]
partial_data = data[:4]

preprocessing.LabelEncoder

カテゴリカル変数を数値のラベルに変換する。

from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(data)
encoded = le.transform(partial_data)
print(encoded) # [3 1 2 0]
print(le.inverse_transform(encoded)) # ['tokyo' 'berlin' 'paris' 'amsterdam']

preprocessing.OneHotEncoder

One-hot vectorに変換する。デフォルトだとカテゴリーと同じ数の次元に変換されるので変数同士に相関がある多重共線性が生まれてしまうが、drop='first'で最初の次元を消すことで回避できる。

oh = preprocessing.OneHotEncoder(drop='first')
oh.fit([[d] for d in data])
encoded = oh.transform([[d] for d in partial_data]).toarray()
print(encoded) # [[0. 0. 1.] [1. 0. 0.] [0. 1. 0.] [0. 0. 0.]]
print(oh.inverse_transform(encoded)) # [['tokyo'] ['berlin'] ['paris'] ['amsterdam']]

get_dummies()

pandasでOne-hot vectorに変換する関数。

import pandas as pd
print(pd.get_dummies(data, drop_first=True))
'''
   berlin  paris  tokyo
0       0      0      1
1       1      0      0
2       0      1      0
3       0      0      0
4       0      1      0
5       0      0      0
6       1      0      0
'''

カテゴリ変数を扱える決定木ではLabelEncoderを使うとパラメータが少なくなるので良いが、 通常はラベルの数値の大小の影響を受けないようにOne-hot vectorにする。 ただ、カテゴリが多いとその分次元も増えるので、次元の呪いを抑えるため必要なら主成分分析(PCA)で次元削減する。

参考

scikit learn - When to use One Hot Encoding vs LabelEncoder vs DictVectorizor? - Data Science Stack Exchange