OneHotEncoderで「categorical_features」のTypeErrorが発生した時の対処法

dollar, money, bank Python

今回も今勉強中の「Pythonによるデータ分析の教科書」でscikit-learnの写経中に発生したエラー「TypeError: __init__() got an unexpected keyword argument ‘categorical_features’」の対処法の備忘録として残しておきます。

Pythonによるデータ分析の教科書でこれまで発生したエラーの対処は以下記事にあります。

Pandasで「UnicodeDecodeError」エラーが出た時の対処法

Matplotlibで「missing from current font」エラーで文字化けする

環境

  • Windows10
  • jupyter notebook
  • scikit-learn 0.23.2

やったこと

今回やっていたことはカテゴリ変数のエンコーディングというもので簡単に説明すると、機械学習のデータを使うときに文字を一定の数字に変換するという作業です。

例えば、アンケートの結果が「a、b、c」と表示されていた場合に、以下のように変換することです。

  • a→1
  • b→2
  • c→3

そのための方法として、「One-hotエンコーディング」という仕組みがあり、それを利用している時に発生したエラーです。

コードは以下です。

import pandas as pd
from sklearn.preprocessing import LabelEncoder, OneHotEncoder

df = pd.DataFrame( 
  {
    'A': [1, 2, 3, 4, 5, 6],
    'B': ['a', 'b', 'a', 'c', 'd', 'd' ], 
  } 
)
#Data Frameをコピー
df_one = df.copy()
#ラベルエンコーダのインスタンス化
le = LabelEncoder()
#英語のa,b,cを1,2,3に変換
df_one['B'] = le.fit_transform(df_one['B'])
#One-hotエンコーダのインスタンス化
one = OneHotEncoder(categorical_features=[1])
#One-hotエンコーディング
one.fit_transform(df_one).toarray()

エラー内容

上記コードを実行すると次のエラーが発生していました。

TypeError: __init__() got an unexpected keyword argument 'categorical_features'

大体TypeErrorが発生した場合は、変数が定義されていないとか、利用しているパッケージのバージョンにより関数が無い場合が多いです。

今回もグーグル先生に、「categorical_features エラー」で検索したところ以下サイトに同じようなエラーが発生した方のサイトが見つかりましたので参考にさせていただきました。ありがとうございます。

写経中に遭遇したscikit-learnのワーニングに対応してみた

OneHotEncoder categorical_features depreciated, how to transform specific column

どうやら、「categorical_features」キーワードは、version0.20で非推奨で0.22からは削除されたみたいです。その代わりに「ColumnTransformer」という関数を使うみたいです。

The ‘categorical_features’ keyword is deprecated in version 0.20 and will be removed in 0.22. 

In the future, you should not define the columns in the OneHotEncoder directly, unless you want to use “categories=’auto'”. The first message also tells you to use OneHotEncoder directly, without the LabelEncoder first. Finally, the second message tells you to use ColumnTransformer, which is like a Pipe for columns transformations.

一応公式サイトも確認しましたが、たしかに公式サイトの最新バージョン(0.24)のドキュメントから消えてました。

6.3. Preprocessing data

対処法

というわけで先ほどの、コードを変更して「ColumnTransformer」を追加します。

import pandas as pd
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer

df = pd.DataFrame(
    {
        'A': [1, 2, 3, 4, 5],
        'B': ['a', 'b', 'a', 'c', 'b' ],
    }
)

#Data Frameをコピー
df_one = df.copy()

ct = ColumnTransformer([("test", OneHotEncoder(),
                         [1])], remainder='passthrough')

ct.fit_transform(df_one)
  • 結果
array([[1., 0., 0.],
       [0., 1., 0.],
       [1., 0., 0.],
       [0., 0., 1.],
       [0., 1., 0.]])

 補足

ちょっとこの「ColumnTransformer」ではまってましたので、忘れないように詳細を記載しておきます。

ColumnTransformerの使い方

以下はColumnTransformerの使い方です。

class sklearn.compose.ColumnTransformer(transformers, *, remainder=’drop’, sparse_threshold=0.3, n_jobs=None, transformer_weights=None, verbose=False)

公式サイト
sklearn.compose.ColumnTransformer

少しだけ、今回のコードの内容を元にCloumnTrasformerの引数について説明します。

書いたコード

ColumnTransformer([(“test”, OneHotEncoder(), [1])], remainder=’passthrough’)

transformers:このトランスフォーマーズは「List of tuples」になっていてタプルのリストで以下3つのパラメータを指定します。

  1. name:任意の名前を指定します。
  2. transformer:利用するEstimator(統計量)の方法を指定します。OneHotEncoderやCountVectorizerなど指定できます。
  3. columns:対象とする列を指定します。インデックス番号の指定や、辞書のキー名などで指定することができます。

今回のコードで言うと以下になります。

  1. name:test
  2. transformer:OneHotEncoder()
  3. columns:1(’B’でも指定可能です)

ここまでが、transformersの引数の話しです。続いて次のremainder引数です。

remainder:ColumnTransformerのデフォルトではtransformers引数で指定した列のみが表示される仕様になっています。もし、指定していない列も表示させたい場合にこのremainder引数を使用します。
引数は以下の2つです。

  1. drop:列を表示しない(デフォルト設定)
  2. passthrough:列を表示する

今回のコードではすべての列を表示させたいめ、passthroughを指定しています。
もし、指定しない場合はこんな感じの結果になります。

  • 結果
#passthrough無し
array([[1., 0., 0.],
       [0., 1., 0.],
       [1., 0., 0.],
       [0., 0., 1.],
       [0., 1., 0.]])

#passthrough有り
array([[1., 0., 0., 1.],
       [0., 1., 0., 2.],
       [1., 0., 0., 3.],
       [0., 0., 1., 4.],
       [0., 1., 0., 5.]])

以上、エラーの対処法と簡単なColumnTransformerの使い方でした。

以上です。ありがとうございました。

勉強中の参考書はこちらです。

コメント

タイトルとURLをコピーしました