LoginSignup
20
16

More than 3 years have passed since last update.

[scikit-learn]OneHotEncoderの使い方

Last updated at Posted at 2019-05-20

指定した配列を(0,1)の2値で構成される配列に変換するためのクラス。

機械学習を実行する際の前処理として、カテゴリ変数を処理するために利用する。
例えば、

\begin{pmatrix}
a & c\\
b & c\\
a & d
\end{pmatrix}

のようなデータを

\begin{pmatrix}
1 & 0 & 1 & 0 \\
0 & 1 & 1 & 0 \\
1 & 0 & 0 & 1 \\
\end{pmatrix}

といった形に変換できる。

コンストラクタ

主なパラメータは以下の通り。

categories

デフォルト値は'auto'

'auto':列に含まれる値から、カテゴリ値を自動的に抽出し決定する。

list:リストのリスト。
 1) 各リスト内の値は文字列か数値で、同一リスト内の値は型が統一されている必要あり。
 2) リストを数値で構成している場合は、昇順ソートされていないとNG。
 3) i列目に含まれる値がcategories[i]に含まれていない場合の挙動は、handle_unknownの設定次第。(※1)
 4) categories[i]に含まれている値が、i列目に含まれていない場合は問題なし。
  この場合、結果として得られる配列に全て0の列ができるだけ。
 5) リストの長さは、配列の列数と同じとする必要がある。

sparse

transform、fit_transformの実行結果の型を指定する。デフォルト値はTrue。
・True : 2次元のscipy.sparse.csr.csr_matrix
・False : 2次元のnumpy.ndarray

handle_unknown

※1に記載した部分の挙動に影響する。デフォルト値は'error'。
'error':※1のケースにて、処理が異常終了する。
'ignore':※1のケースにて、categories[i]に含まれていないカテゴリ値を無視する。

メソッド

set_params( **params )

エンコーダが適用するパラメータを設定(または変更)する。

get_params()

エンコーダに設定されているパラメータを取得する。

fit_transform(X[, y])

Xを変換した行列を取得する。

サンプルコード

サンプル1:sparse=Falseの場合

import sklearn.preprocessing as sp
import numpy as np
import pandas as pd

df = pd.DataFrame( ['c','b','a'] )
enc = sp.OneHotEncoder( sparse=False )

# 結果(ndarray)
print( enc.fit_transform( df ) )
[[0. 0. 1.]
 [0. 1. 0.]
 [1. 0. 0.]]

OneHotEncoderのコンストラクト時にcategoriesを指定していないので、取り扱うカテゴリ変数としは"fit(あるいはfit_transform)実行時の入力に含まれる値"をカテゴリ変数として選択します。
また、どの列にどのカテゴリ変数を対応させるか、その順序は文字列の場合は辞書式での"昇順ソート結果"となるようです。

このため、上記の例では1列目/2列目/3列目が、それぞれ「入力配列の各要素がaかどうか」「同bかどうか」「同cかどうか」を表現することになります。


サンプル2:sparse=Trueの場合

df = pd.DataFrame( ['c','b','a'] )
# パラメータ変更
enc.set_params( sparse=True )

# 結果(csr_matrix)
print( enc.fit_transform( df ) )
  (0, 2)    1.0
  (1, 1)    1.0
  (2, 0)    1.0

csr_matrix型を結果として取得するので、保持している情報が簡素になります。


サンプル3:カテゴリ指定(文字列)


df = pd.DataFrame( ['c','b','a'] )
# 入力配列には'c'を含んでいるが、指定するcategoriesには含めていない
enc = sp.OneHotEncoder( categories=[['a','b']] )
enc.fit_transform( df )

# エラー発生
ValueError: Found unknown categories ['c'] in column 0 during fit

# handle_unknownにignoreを指定すれば処理は正常終了。
enc = sp.OneHotEncoder( categories=[['a','b']], handle_unknown='ignore', sparse=False )
print( enc.fit_transform( df ) )

# 結果(カテゴリ値が'a','b'以外の場合、全ての値が0の行に変換される)
[[0. 0.]
 [0. 1.]
 [1. 0.]]

# 入力配列には'd'を含んでいないが、指定するcategoriesには含めている(これは問題なし)。
enc = sp.OneHotEncoder( categories=[['d','b','c','a']],sparse=False )

# 結果
print( enc.fit_transform( df ) )
[[0. 0. 1. 0.]
 [0. 1. 0. 0.]
 [0. 0. 0. 1.]]

結果の1列目は「入力配列のi行目の値が'd'の場合1」となりますが、入力配列には値として'd'を持つ行が存在しないため、結果の1列目はすべての値が0となっています。
また、categoriesの指定内容が昇順ソートになっていませんが、特に問題はありません。


サンプル4:カテゴリ指定(数値)

# 正常に動作する例
df = pd.DataFrame( [1,3,5,1,3] )
enc = sp.OneHotEncoder( categories='auto', sparse=False )
print( enc.fit_transform( df ) )

# 結果
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]
 [1. 0. 0.]
 [0. 1. 0.]]

# カテゴリ指定も可能(入力配列にない値をカテゴリ指定に含めても問題なし)
enc.set_params( categories=[[1,2,3,4,5]] )
print( enc.fit_transform( df ) )

# 結果
[[1. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0.]
 [0. 0. 0. 0. 1.]
 [1. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0.]]

# カテゴリ指定時に数値を指定する場合は、昇順ソートしていないとエラー
enc.set_params( categories=[[1,3,4,2,5]] )
print( enc.fit_transform( df ) )

# 結果(fit_transform実行時にエラー発生)
ValueError: Unsorted categories are not supported for numerical categories

参考サイト

-https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html

20
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
16