PythonにおけるOneHot(ワンホット)エンコーディングのやり方をそれぞれのライブラリ毎にまとめてご紹介いたしますので、忘れてしまった、使い方がごちゃごちゃになってしまった時にご参照ください。
NumpyにおけるOneHotエンコーディング
numpyにおけるエンコーディング方法はeye関数を使用します。
書き方は以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import numpy as np #配列を定義 values = [1, 0, 3] #分類数を取得 n_values = np.max(values) + 1 #np.eye(n_values)[values] #分類数分の単位行列を生成 a = np.eye(n_values) #単位行列から配列のインデックス値だけ取得 one_hot = a[values] """ array([[1., 0., 0., 0.], [0., 1., 0., 0.], [0., 0., 1., 0.], [0., 0., 0., 1.]]) """ |
eye関数は単位行列を生成する関数なのですが、分類数分の単位行列を生成した後に、配列の値からそのままインデックスを指定して行を引っこ抜けばワンホットされているという手法です。

PandasにおけるOneHotエンコーディング
Pandasの場合はget_dummies関数というものを使います。numpyに比べるとだいぶ簡単に利用することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import pandas as pd df = pd.DataFrame({"カテゴリ" : ["RPG" , "アクション" , "ADV" , "FPS" , "スマホ"] , "年齢" : ["28" , " 23" , "31" , "18" , "12"] , "ゲーム歴" : ["10" , "7" , "21" , "4" , "2"]}) print(pd.get_dummies(df, columns=["カテゴリ"])) """ 年齢 ゲーム歴 カテゴリ_ADV カテゴリ_FPS カテゴリ_RPG カテゴリ_アクション カテゴリ_スマホ 0 28 10 0 0 1 0 0 1 23 7 0 0 0 1 0 2 31 21 1 0 0 0 0 3 18 4 0 1 0 0 0 4 12 2 0 0 0 0 1 """ |
get_dummies関数は第1引数にpandasのデータフレームを、第2引数にワンホットエンコーディングするカラム名をリストで指定します。
変換すると変換した列の種類ごとに列が生成されます。

scikit-learnにおけるOneHotエンコーディング
scikit-learnについてはOneHotEncoderというモジュールを使用します。numpyの配列に対して使用します。PandasのDataFrameでもできなくはないですけど結構面倒くさいので、get_dummies関数かもしくは後述するCategory Encodersを使用しましょう。
Numpyの場合
1 2 3 4 5 6 7 8 9 10 |
import numpy as np from sklearn.preprocessing import OneHotEncoder # エンコーダーで読み込めるように形を修正 beforeEnc = np.array([1, 0, 3]).reshape(-1,1) #エンコーダーのプロパティを設定 enc = OneHotEncoder(categories="auto", sparse=False, dtype=np.float32) #エンコードを実施 afterEnc = enc.fit_transform(beforeEnc) print(afterEnc) |
numpyの場合は読み込めるように配列の形を修正→エンコーダーのプロパティをセッティング→エンコード実施という流れです。読み込めるように形を変更しなければいけない場合がある点に注意しましょう。
Pandasの場合
Pandasの場合のやり方も一応記載しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import pandas as pd from sklearn.preprocessing import OneHotEncoder df = pd.DataFrame({"カテゴリ" : ["RPG" , "アクション" , "ADV" , "FPS" , "スマホ"] , "年齢" : ["28" , " 23" , "31" , "18" , "12"] , "ゲーム歴" : ["10" , "7" , "21" , "4" , "2"]}) #OneHotエンコーディングしたい行だけ抜き出し、読み込めるように形を修正 reshapeDf = df["カテゴリ"].values.reshape(-1, 1) #エンコーダーのプロパティを設定 encoder = OneHotEncoder(handle_unknown='ignore') #エンコーディングを実施 encoder.fit(reshapeDf) #エンコーダーからOneHotエンコーディングしたデータを取り出し afterEnc = encoder.transform(df["カテゴリ"].values.reshape(-1, 1)) #pandasの形に戻す afterEnc_df = pd.DataFrame(afterEnc.toarray().astype('int64'), columns=encoder.categories_) print(afterEnc_df) |
一つのカテゴリのデータに対して、読み込めるようにNumpy形式にデータを変えてエンコーディングして、エンコーダーからエンコーディングしたデータを取り出してPandasに戻して…って滅茶苦茶面倒くさいことになってます。1行で終わったget_dummies関数と見比べるとその差は歴然です。
あとプロパティに設定している [handle_unknown]ですが項目が存在しなかったデータをどうするかを設定してます。”ignore”は文字通り無視します。
Category Encoders におけるOneHotエンコーディング
個人的におすすめな方法ですが、Category Encodersというライブラリを利用したワンホットエンコーディングの方法があります。
1 2 |
#Colab等でも事前にインストールが必要 pip install category_encoders |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import pandas as pd import category_encoders as ce df = pd.DataFrame({"カテゴリ" : ["RPG" , "アクション" , "ADV" , "FPS" , "スマホ"] , "年齢" : ["28" , " 23" , "31" , "18" , "12"] , "ゲーム歴" : ["10" , "7" , "21" , "4" , "2"]}) #プロパティを設定 ce_oe = ce.OneHotEncoder(cols = "カテゴリ",handle_unknown='impute') #エンコードを実施 afterEncDf = ce_oe.fit_transform(df) print(afterEncDf) |
注意してほしいのはローカル環境ではもちろんですがColabでも別途インストールが必要なので、使えないよー!っていう人はインストールするコマンドをColab上で実施してみてください。(普通にコードのテキストエリアにコマンドを張り付けて実行ボタンを押すだけでいいです)
実行結果はget_dummies関数と同じ感じですが、プロパティを設定できたりほかにも様々なエンコーディングができるので便利です。
あと例の[handle_unknown]プロパティですが、今回は”impute”を指定しています。imputeを項目が存在しないデータには-1を設定します。
以上です。
やり方がわからない、他にもこういう方法がある等ございましたらご連絡いただければ幸いです。
コメント