scikit-learn の LabelEncoder を説明変数の変換に使っている例はたくさん見つかる。 しかし、実は本来 LabelEncoder は目的変数の変換に使うことが想定されていることは、あまり知られていない。 これは公式のドキュメントで確認できる。
上記から一部を引用する。
This transformer should be used to encode target values, i.e. y, and not the input X.
このように、入力として想定されているのが本来は目的変数であることが読み取れる。 ようするに Iris データセットでいう setosa とか versicolor を 0 とか 1 に変換するのが本来の目的ということ。
メソッドの引数名を見ても X
ではなく y
になっている。
なので Pipeline と併用した場合には X
の内容は渡ってこない。
説明変数の変換には、代わりに OrdinalEncoder を使うのが良い。
OrdinalEncoder を使うと、未知の値がテストデータにあったときに指定した値に変換できる。
この機能は LabelEncoder には含まれていない。
ただし、デフォルトでは LabelEncoder と同じように未知の値に遭遇したときは例外を上げるようになっている。
そのため、明示的に handle_unknown
パラメータと unknown_value
を指定する。
サンプルコードを以下に示す。
import numpy as np from sklearn.preprocessing import OrdinalEncoder def main(): # 説明変数を仮定しているため 2D 配列の必要がある train = np.array(["apple", "banana", "cherry"]).reshape(-1, 1) # 未知の値は -1 に変換する # デフォルトでは例外になるので LabelEncoder と変わらない ordinal_encoder = OrdinalEncoder( handle_unknown="use_encoded_value", unknown_value=-1, ) ordinal_encoder.fit(train) train_transformed = ordinal_encoder.transform(train) print(train_transformed) # 未知の値は -1 に変換される test = np.array(["dates", "fig"]).reshape(-1, 1) test_transformed = ordinal_encoder.transform(test) print(test_transformed) if __name__ == "__main__": main()
上記を実行してみよう。
$ python example.py [[0.] [1.] [2.]] [[-1.] [-1.]]
未知のデータが含まれた配列が例外にならず -1
に変換できていることが確認できる。
いじょう。