静かなる名辞

pythonとプログラミングのこと



【python】sklearnでのカテゴリデータの取り扱いまとめ

概要

 カテゴリデータをone-hot表現として取り扱うという方法は、機械学習などでは一般的に行われます。

 しかし、この辺りの処理に対するsklearnでのサポートが微妙に悪いという問題が長年あり、やれpandasを使えだの、やれサードパーティ製ライブラリで凌げだのといった話題が乱立していました。

 sklearn 0.20からはOneHotEncoderが拡張され、sklearnの枠組みの中で簡単にカテゴリデータ、カテゴリ変数をone-hot特徴量に変換できるようになりました。

 目次

カテゴリデータを取り扱うために使用するクラス

 以下で使うクラスについて説明します。

LabelEncoder

 これはラベルの変換に使います。教師ラベルを変換するのに使えます。教師ラベルはあえて変換しなくても、そのまま受け付けてくれるモデルがsklearnでは多い気がするので、なくても良いような気はします。

>>> from sklearn.preprocessing import LabelEncoder
>>> le = LabelEncoder()
>>> le.fit_transform(["hoge", "fuga", "piyo"])
array([1, 0, 2])

 インデックスの順番は、たぶんソートして昇順でしょう。

sklearn.preprocessing.LabelEncoder — scikit-learn 0.20.1 documentation

OrdinalEncoder

 LabelEncoderに似ていますが、ラベルではなくデータを受け付けるもの、と認識しておけば良いと思います。要するに、慣れ親しんだ[n_samples, n_features]の配列を受け取ります。

>>> from sklearn.preprocessing import OrdinalEncoder
>>> oe = OrdinalEncoder()
>>> oe.fit_transform([["h", "ho", "hoge"], ["f", "fu", "fuga"], ["p", "pi", "piyo"]])
array([[1., 1., 1.],
       [0., 0., 0.],
       [2., 2., 2.]])

sklearn.preprocessing.OrdinalEncoder — scikit-learn 0.20.1 documentation

 これで良いときはこれを使えば良いのですが、one-hot表現がほしいときが多いと思います。その場合は、次節で示すOneHotEncoderが使えます。

OneHotEncoder

 最初に書いた通り、sklearn 0.20からOneHotEncoderがOrdinalEncoder相応のデータを受け付けるようになりました(それ以前はそういう仕様ではなく、LabelEncoderかOrdinalEncoderを通して数値化したデータを入れる必要がありました)。

 なので、今後は事実上これだけ使えば良いということです。

>>> from sklearn.preprocessing import OneHotEncoder
>>> ohe = OneHotEncoder()
>>> ohe.fit_transform([["h", "ho", "hoge"], ["f", "fu", "fuga"], ["p", "pi", "piyo"]])
<3x9 sparse matrix of type '<class 'numpy.float64'>'
	with 9 stored elements in Compressed Sparse Row format>
>>> ohe = OneHotEncoder(sparse=False)
>>> ohe.fit_transform([["h", "ho", "hoge"], ["f", "fu", "fuga"], ["p", "pi", "piyo"]])
array([[0., 1., 0., 0., 1., 0., 0., 1., 0.],
       [1., 0., 0., 1., 0., 0., 1., 0., 0.],
       [0., 0., 1., 0., 0., 1., 0., 0., 1.]])

 注意点として、上でも示していますがデフォルトパラメータでは返り値がsparse matrixです。sparse=False一発でnumpy配列を返すようになります。sklearnのモデルの疎行列対応はモデルによって対応していたり、していなかったりという具合なので、後段のモデルに色々なものを使いたければそちらを指定することをおすすめします。

sklearn.preprocessing.OneHotEncoder — scikit-learn 0.20.1 documentation

まとめ

 OneHotEncoderを使えばシンプルにやりたいことが実現できます。