Evalml: 1つのホットエンコーダ:2つのカテゴリを持つ機能の場合、デフォルトで1つの冗長機能を削除します

作成日 2021年03月05日  ·  14コメント  ·  ソース: alteryx/evalml

1つのホットエンコーダーは、元のカテゴリ機能のすべてのレベルの機能を作成します。

from evalml.pipelines import OneHotEncoder
import pandas as pd
df = pd.DataFrame({"category": ["a", "b"], "number": [4,5 ]})
OneHotEncoder().fit_transform(df).to_dataframe()

image

category_a category_b列と

参考までに@rpeck

enhancement

最も参考になるコメント

法典の第3法則:あなたは==フロートとの比較をしてはならない

全てのコメント14件

💯%負の場合の列を削除する必要があります。

最初にOHEを自分で行う場合、sklearnはそれらを拡張しないことを願っています。 フレディが言ったように、これは完全な共線性を持つ2つの列を生成するものと考えることができます。

バイナリを1列ではなく2列に拡張すると、2つの問題が発生します。

  1. 他の形式の特徴の共線性と同様に、1つの元のソース列の効果が2つのOHE列に分割されるため、解釈可能性において多くのことを台無しにします。 フレディの新しいSHAPロールアップは明らかにこれに対処しますが、特徴重要度や部分依存関係のプロットなどにはまだ問題があります。
  2. ランダムフォレストやGBMなどのツリーモデルは、入力特徴をランダムにサンプリングします。 この場合のソース列は、実際の2倍の頻度でランダムにサンプリングされるため、モデルに大きな影響を与える可能性があります。

@freddyaboulton Q:OHE列の上記のデータフレームは、それらを浮動小数点数として示しています。 これは本当に本当ですか?

@rpeckはい!

@freddyaboultonなに? それは変だ。 真のブール値、つまり0/1整数以外は見たことがありません。 ツリーモデルが実際にこれをどのように処理するのだろうか。 臭いがします。

法典の第3法則:あなたは==フロートとの比較をしてはならない

Math.NaNない限り、わかりました)

うーん、これをやっていると思った!

私はそうすべきだと同意します。 これは、基礎となるimplに設定する必要のあるフラグにすぎないと思いました。

@dsherry @freddyaboulton dropパラメーターを介してサポートされているようですが、ユーザー入力のみが考慮され、implでは使用されないため、この問題はdropデフォルトの設定を追跡するだけです。なし以外に?

https://github.com/alteryx/evalml/blob/91775ffc26c47205adc0fb255832d828ead6e7c9/evalml/pipelines/components/transformers/encoders/onehot_encoder.py#L28

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

firstまたはif_binaryどちらかを使用できますが、正しい呼び出しが何であるかはわかりません。

@ angela97linデフォルト値を変更するだけで十分です! カテゴリの数が2を超える場合でも、完全に同一線上の特徴を避ける必要があるため、 first最適な方法だと思います。 ますか?

これを少し読んで、このリンクを見つけました: https

重要なポイント:

  • 列の削除は、正則化なしでOLSモデルを作成する場合にのみ必要です(線形回帰はこのカテゴリに分類されると思います:https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html、https:// scikit-learn.org/stable/modules/linear_model.html#ordinary-least-squares)
  • ワンホットエンコードされた列を削除すると、線形回帰モデルのパラメーターと予測が変更され、返されるモデルに影響します。 それでも、これが良いかどうかを判断するのは難しいです。

RE @rpeckの最初のコメント:「他の形式の特徴共線性と同様に、1つの元のソース列の効果が2つのOHE列に分割されるため、解釈可能性で多くのことを台無しにします。フレディの新しいSHAPロールアップは、明らかにこれに対処します。ただし、特徴の重要性や部分的な依存関係のプロットなどには、引き続き問題があります。」

これはバイナリの場合には意味がありますが、複数のカテゴリがある場合でも、1つの列を削除するとこの問題が発生します。

おそらく、デフォルトでこれを行うべきではありませんが、推定量が線形リグレッサである場合、パラメータとしてfirstを使用してOHEを作成するためにmake_pipelineを更新する必要がありますか?

残念ながら、私は判断を下すための基礎となる数学をしっかりと把握していないので、あなたの考えを聞いてみたいです@ freddyaboulton @rpeck @dsherry

@freddyaboulton @rpeck @dsherry @ chukarsten @ jeremyliweishihとのポストディスカッション

  • これは、バイナリの場合にのみ行います。
  • 「必要なもの」は、バイナリの場合は少数派クラスを使用することですが、それ以外の場合は、2つのカテゴリのいずれかを選択するだけで十分です。

@ angela97linは、REのデフォルトの動作として

@dsherry正しく理解していれば、デフォルト値のdrop (パラメーター)を更新しているので、ユーザーはコンポーネントパラメーターを手動で設定することでこれをオーバーライドできますか?

これを実装するために何が必要かを確認するために掘り下げました。 特に、バイナリの場合に少数派クラスを常に削除することがどれほど難しいかについて興味がありました。

その掘り出しの結果は次のとおりです。

  • scikit-learnでは、削除するカテゴリを選択するのは非常に困難です。 ドキュメントから、これはdropパラメーターの配列オプション(https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html)を介して実行可能であるように思われます。 ただし、試してみると、列ごとにインデックス値を指定する必要があります。 したがって、以下は、列0のインデックス0で指定されたカテゴリを削除しようとしており、列1および2のエラーには他の値はありません。
import pandas as pd
import numpy as np
from sklearn.preprocessing import OneHotEncoder

X = pd.DataFrame({'col_1': ["a", "b", "b", "a", "b"],
                      'col_2': ["a", "b", "a", "c", "b"],
                      'col_3': ["a", "a", "a", "a", "a"]})

indices_to_drop = np.array([0, None, None])

ohe = OneHotEncoder(drop=indices_to_drop)
ohe.fit(X)
ValueError                                Traceback (most recent call last)
<ipython-input-4-a099fa2fc4a7> in <module>
----> 1 ohe.fit(X)

~/Desktop/venv/lib/python3.7/site-packages/sklearn/preprocessing/_encoders.py in fit(self, X, y)
    417         self._fit(X, handle_unknown=self.handle_unknown,
    418                   force_all_finite='allow-nan')
--> 419         self.drop_idx_ = self._compute_drop_idx()
    420         return self
    421 

~/Desktop/venv/lib/python3.7/site-packages/sklearn/preprocessing/_encoders.py in _compute_drop_idx(self)
    394                                 ["Category: {}, Feature: {}".format(c, v)
    395                                     for c, v in missing_drops])))
--> 396                 raise ValueError(msg)
    397             return np.array(drop_indices, dtype=object)
    398 

ValueError: The following categories were supposed to be dropped, but were not found in the training data.
Category: 0, Feature: 0
Category: 1, Feature: None
Category: 2, Feature: None

これもこの問題が指摘していることの半分だと思います: https

これをサポートするために実行できる別の方法は、フィッティング中にドロップする列と値を手動で追跡することです。 データをscikit-learnに渡します。 次に、保存して削除するように指定した列を削除します。 ただし、これには、変換された列名から元の(機能、値)を判別するためのロジック処理が必要です。 (このロジックはget_feature_namesが、何も削除しないと仮定して列名を接続するのに役立ちます...)

つまり、今のところ、デフォルトのscikit-learn if_binaryするだけで十分であり、別の問題を提出して、常に少数派クラスを使用することができます。 正直なところ、scikit-learnのOHE実装から離れることにも賛成です。これは、回避する必要があったことを考えるとです。

役立つリソース:
OHEドキュメント: https
柔軟性の欠如を引き起こすscikit-learnのコード: https
関連する問題: https


if_binary :scikit-learnでは、 handle_unknownerrorます。 これは、 top_nパラメータではうまく機能しません。変換するデータは新しいカテゴリをどう処理するかわからないため、上位N個のカテゴリ以外はすべて削除されます。 Beccaがhttps://github.com/alteryx/evalml/pull/830で述べているように、これらのパラメーターを機能させるには、 top_nをNoneに設定する必要があります。

これを念頭に置いて、私たち自身のimplをロールするのが最善かもしれません🤔

このページは役に立ちましたか?
0 / 5 - 0 評価