機械学習:前処理 非数値データの扱い:Nominal Data その3: OneHot Encoding
前記事の終わりに書きましたが、自作辞書やLabelEncoderを使ってエンコーディングした場合、暗示的にでもNominalデータに順序性が含まれてしまうと、機械学習のアルゴリズムによって生成された結果に疑問が出てきてしまいます。
これを補うには、dummy feature(擬特性)を一つ加えて、例えば、blueを、blue=1, green=0, red=0と表現するOneHot Encodingを使います。この方法を自力でするのは…やめましょう。
サンプルデータは、前記事のデータフレームにもう一つ値段をつけてみましょう。
import pandas as pd
df = pd.DataFrame({
'Size':['S', 'M', 'L', 'S', 'M', 'P', 'M', 'L', 'XP', '2XL', 'XL'],
'Color':['green','red','yellow','yellow','blue',
'black','white','red','yellow','green','red'],
'Price':[20,40,10,15,60,15,50,35,20,55,100]
})
df.transpose()
第一の手段として、scikit_learnのOneHotEncodingがあります。
from sklearn.preprocessing import OneHotEncoder
X=df[['Size','Color','Price']].values
color_ohe=OneHotEncoder()
color_ohe.fit_transform(X[:,1].reshape(-1,1)).toarray()
このコードでは、データフレームの一列目のColorのみを取り出してエンコーディングを行い、行列化しています。
このカラー列のエンコーディングの結果はこちらです。
第二の手法は、sklearn.compose のColumn Transformer を使って、列指定でエンコードします。
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
X=df[['Size','Color','Price']].values
c_transf=ColumnTransformer(
[('onehot',OneHotEncoder(),[1]),
('nothing','passthrough',[0,2])])
c_transf.fit_transform(X)
ColumnTransformerの行で、一列目のみOneHotEncodingで、0列目と1列目は何もせずに通過させるように書きます。
この方法だと、出力はSizeと値段の情報を保っています。
第3の方法は、pandasのget_dummiesですが、これは文字列を含む列がすべてエンコードされてしまうので、順序データのサイズを先に辞書方式でエンコードしておきましょう。
size_mapping = {'XP':0, 'P':1, 'S':2, 'M':3, 'L':4, 'XL':5, '2XL':6}
df['Size']=df['Size'].map(size_mapping)
df.transpose
pd.get_dummies(df[['Size','Color','Price']])
ただし、このOneHotEncodingだと、情報に多重性が入ってきます。
つまり、簡単な例として、最初の黒、青、緑の三色のみがある場合、このエンコーディングを行うと、青でもなければ(blue=0)、緑でもない(green=0)のであるならば、残りの黒でしかないわけで、黒列はあってもなくても良くて、逆に計算機側としては、無い方がデータ量も計算量も少なくて都合が良いのです。
よって、特徴量の列を一つ削除しましょう(黒、青、緑の上記の例ならば黒を削除)。
pd.get_dummies(df[['Size','Color','Price']],drop_first=True)
この特徴量の列を一つ削除する作業は、OneHotEncoderを使う場合も同じく必要です。
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
X=df[['Size','Color','Price']].value
color_ohe=OneHotEncoder(drop='first')
c_transf=ColumnTransformer(
[('onehot',color_ohe,[1]),
('nothing','passthrough',[0,2])])
c_transf.fit_transform(X)
この記事が気に入ったらサポートをしてみませんか?