Получение имен функций из FeatureUnion + Pipeline

Я использую 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». Я хотел бы увидеть некоторые функции, созданные моими различными векторизаторами. Как мне это сделать?


person Huey    schedule 27.02.2017    source источник
comment
Вы получаете сообщение об ошибке при вызове union.get_feature_names()?   -  person Vivek Kumar    schedule 27.02.2017
comment
Это ошибка: заголовок преобразователя (тип Pipeline) не предоставляет имена get_feature_name.   -  person Huey    schedule 14.03.2017
comment
Возможно, вы захотите посмотреть на этот ответ из другого аналогичного вопроса: stackoverflow.com/questions/28822756/   -  person Guillaume Chevalier    schedule 17.10.2019


Ответы (2)


Это потому, что вы используете специальный трансформер под названием TextSelector. Вы реализовали get_feature_names в TextSelector?

Вам придется реализовать этот метод в своем настраиваемом преобразовании, если вы хотите, чтобы это работало.

Вот вам конкретный пример:

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 каждым из ваших преобразователей. вот почему вы получаете сообщение об ошибке, если один или несколько ваших трансформаторов не имеют этого метода.

Однако я вижу, что это само по себе не решит вашу проблему, поскольку в объектах конвейера нет get_feature_names метода, а у вас есть вложенные конвейеры (конвейеры в рамках Feature Unions). Итак, у вас есть два варианта:

  1. Создайте подкласс Pipeline и добавьте его get_feature_names метод, который получает имена функций из последнего преобразователя в цепочке.

  2. Извлеките сами имена функций из каждого из трансформаторов, что потребует от вас самого вытащить эти трансформаторы из конвейера и вызвать на них get_feature_names.

Кроме того, имейте в виду, что многие встроенные в преобразователи sklearn не работают с DataFrame, а передают множество массивов, поэтому просто следите за этим, если вы собираетесь объединять множество преобразователей вместе. Но я думаю, что это дает вам достаточно информации, чтобы дать вам представление о том, что происходит.

Еще одна вещь, взгляните на sklearn-pandas. Я сам не использовал его, но он может предоставить вам решение.

person hamel    schedule 09.08.2017
comment
Связанный PR по (1): поддержка get_feature_names для конвейеров - person ruhong; 30.04.2018

Вы можете вызывать различные векторизаторы как вложенную функцию (спасибо 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())
person Max Kleiner    schedule 12.03.2019