web-dev-qa-db-ja.com

FeatureUnion +パイプライン内から機能名を取得する

FeatureUnionを使用して、イベントのタイトルと説明から見つかった機能を結合しています:

_union = FeatureUnion(
    transformer_list=[
    # Pipeline for pulling features from the event's title
        ('title', Pipeline([
            ('selector', TextSelector(key='title')),
            ('count', CountVectorizer(stop_words='english')),
        ])),

        # Pipeline for standard bag-of-words model for description
        ('description', Pipeline([
            ('selector', TextSelector(key='description_snippet')),
            ('count', TfidfVectorizer(stop_words='english')),
        ])),
    ],

    transformer_weights ={
            'title': 1.0,
            'description': 0.2
    },
)
_

ただし、union.get_feature_names()を呼び出すと、「トランスフォーマーのタイトル(タイプPipeline)ではget_feature_namesが提供されません」というエラーが表示されます。さまざまなベクトライザーによって生成されるいくつかの機能を確認したいと思います。どうすればよいですか?

17
Huey

これは、TextSelectorというカスタムトランスフォーマーを使用しているためです。 TextSelectorget_feature_namesを実装しましたか?

これを機能させるには、カスタム変換内にこのメソッドを実装する必要があります。

ここにあなたのための具体的な例があります:

from sklearn.datasets import load_boston
from sklearn.pipeline import FeatureUnion, Pipeline
from sklearn.base import TransformerMixin
import pandas as pd

dat = load_boston()
X = pd.DataFrame(dat['data'], columns=dat['feature_names'])
y = dat['target']

# define first custom transformer
class first_transform(TransformerMixin):
    def transform(self, df):
        return df

    def get_feature_names(self):
        return df.columns.tolist()


class second_transform(TransformerMixin):
    def transform(self, df):
        return df

    def get_feature_names(self):
        return df.columns.tolist()



pipe = Pipeline([
       ('features', FeatureUnion([
                    ('custom_transform_first', first_transform()),
                    ('custom_transform_second', second_transform())
                ])
        )])

>>> pipe.named_steps['features']_.get_feature_names()
['custom_transform_first__CRIM',
 'custom_transform_first__ZN',
 'custom_transform_first__INDUS',
 'custom_transform_first__CHAS',
 'custom_transform_first__NOX',
 'custom_transform_first__RM',
 'custom_transform_first__AGE',
 'custom_transform_first__DIS',
 'custom_transform_first__RAD',
 'custom_transform_first__TAX',
 'custom_transform_first__PTRATIO',
 'custom_transform_first__B',
 'custom_transform_first__LSTAT',
 'custom_transform_second__CRIM',
 'custom_transform_second__ZN',
 'custom_transform_second__INDUS',
 'custom_transform_second__CHAS',
 'custom_transform_second__NOX',
 'custom_transform_second__RM',
 'custom_transform_second__AGE',
 'custom_transform_second__DIS',
 'custom_transform_second__RAD',
 'custom_transform_second__TAX',
 'custom_transform_second__PTRATIO',
 'custom_transform_second__B',
 'custom_transform_second__LSTAT']

Feature Unionは、各トランスフォーマーからそれぞれのget_feature_namesから出力された2つのリストを連結することに注意してください。これが、1つ以上のトランスフォーマにこのメソッドがない場合にエラーが発生する理由です。

ただし、パイプラインオブジェクトにはget_feature_namesメソッドが含まれておらず、パイプライン(フィーチャユニオン内のパイプライン)がネストされているため、これだけでは問題が解決しないことがわかります。したがって、2つのオプションがあります。

  1. Pipelineをサブクラス化し、get_feature_namesメソッドを自分で追加します。これにより、チェーンの最後のトランスフォーマーから機能名が取得されます。

  2. 各トランスフォーマーから自分で機能名を抽出します。これには、これらのトランスフォーマーを自分でパイプラインから取得し、それらのget_feature_namesを呼び出す必要があります。

また、多くのsklearn組み込みトランスフォーマーはDataFrameで動作せず、numpy配列を渡すため、多くのトランスフォーマーをチェーンする場合は注意してください。しかし、これは何が起こっているのかを理解するのに十分な情報をあなたに与えると思います。

もう1つ、 sklearn-pandas をご覧ください。私自身は使用していませんが、解決策を提供するかもしれません。

10
hamel

これにより、さまざまなベクトライザーをネストされた機能として呼び出すことができます(edeszに感謝):

pipevect= dict(pipeline.named_steps['union'].transformer_list).get('title').named_steps['count']

次に、TfidfVectorizer()インスタンスを取得して、別の関数を渡します。

Show_most_informative_features(pipevect,
       pipeline.named_steps['classifier'], n=MostIF)
# or direct   
print(pipevect.get_feature_names())
2
Max Kleiner