OneHotEncoder

概要

OneHotEncoderは、あるクラスデータの特徴量をエンコードする。LabelEncoderOrdinalEncoderが特徴量内のクラスに一連の数値を振るのに対して、OneHotEncoderはクラスの数だけ列を確保し、データごとに該当するクラスのみに1を立てる。エンコードされたデータは、該当するクラスのみに反応するインデックス引数となる。

なお、DataFrameget_dummis()メソッドでもone-hotエンコーディングができる。

使い方

fit()~インデックス列の生成

以下の例は、2つのクラス特徴量を持つ6個のデータセットをOneHotEncoderで変換。

  • sklearn.prreprocessingからOneHotEncoderをインポート
  • エンコーダーのインスタンスを生成
    • デフォルトではスパース行列になるので、オプションでsparse=Falseを指定
  • fit()メソッドでデータをフィッティングし、変換器を準備
  • この段階でcategories_プロパティーには各特徴量ごとのインデックス構成がセットされる

以下の例では、1つ目の特徴量は3つのクラス、2つ目の特徴量は2つのクラスを持つので、3要素、2要素の配列を要素に持つリストがcategories_にセットされる。

transform()~インデックスデータへの変換

fit()メソッドで準備された変換器によってデータを変換する。変換後のデータは特徴量のクラス数分の列を持つ2次元のndarrayで返される。なおfittransformを一度に行うfit_transform()メソッドも準備されている。

出力の右3列は3つの都市、それに続く2列は性別に対応していて、たとえば1行目のデータの都市はcategories_[0]の3番目'Tokyo'、性別はcategories_[1]の2番目の'Male'であることがあらわされている。

DataFrameによる操作

OneHotEncoderpandas.DataFrameも扱える。ただしtransfrom()fit_transform()メソッドの戻り値はndarrayなので、以下の例ではこれをDataFrameの形にしている。このときcolumns引数にエンコーダーのインスタンスのcategories_プロパティーを使うと個別のクラス名まで打ち込まずに済んで便利。

数値データとクラスデータが混在する場合

DataFrameの準備

以下の例では、2つのクラス特徴量と2つの数値特徴量を持つデータセットをDataFrameとして扱う。

クラスデータのヘッダーの準備

クラスデータを複数のインデックスデータの列にするための準備。

  • 特徴量のうち、クラスデータのものと数値データのもののヘッダーを分けておく
  • クラスデータ用のDataFrameを準備して、元データからクラスデータの列だけを切り出し
  • エンコーダーを生成してfit_trans()を実行
  • 実行後にエンコーダーのcategories_に保持されているクラスリストを取得

このクラスリストが変換後のデータのヘッダーになる。

クラスデータと数値データの合体

以下の処理では、変換されたクラスデータ列と元の数値データ列を合わせて最終的なデータセットとしている

  • クラスリストをヘッダーとして、変換後のクラスデータ(ndarray)をDataFrameとして読み込み
  • 上記DataFrameに元データの数値データを追加

この処理によって元データセットから特徴量の順番が変わるが、学習過程で特徴量の順番は影響しない。

inverse_transform()

上でdf_X_trans = df_X_class_trans.copy()としたので、df_X_class_transは保存されている。このデータをエンコーダーのinverse_transform()に与えると、複数列で表現されていたクラスが元の表現で得られる。

新しいデータの変換

訓練済みモデルにデータを与えて予測する場合、前処理のエンコーディングでは、フィッティング済みのエンコーダーに新しいデータを与えて変換する。

未知のクラスへの対処

フィッティング時になかったクラスに遭遇した場合の動作は、エンコーダーのインスタンス生成時に指定する。

OneHotEncoder(handle_unknown='error'/'ignore')

デフォルトは'error'で、未知のクラスに遭遇するとエラーを投げる。'ignore'を指定すると未知のクラスの場合はその特徴量のすべてのクラスラベルが0になる。

以下の例では、2行目のデータにフィッティングでは含まれていなかった”Nagoya”があるため、変換後のデータの2行目の1~3列が0となっている。

この変換データをinverse_transform()で逆変換すると、未知のクラスであったところは'None'に変換される。

 

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です