从FeatureUnion + Pipeline中获取要素名称

Hue*_*uey 16 nlp feature-extraction python-3.x scikit-learn

我正在使用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
    },
)
Run Code Online (Sandbox Code Playgroud)

但是,调用union.get_feature_names()给我一个错误:"变换器标题(类型管道)不提供get_feature_names." 我想看看我的不同矢量化器生成的一些功能.我该怎么做呢?

ham*_*mel 8

这是因为您使用的是自定义变换器TextSelector.你实施get_feature_namesTextSelector吗?

如果要使用此方法,则必须在自定义转换中实现此方法.

这是一个具体的例子:

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']
Run Code Online (Sandbox Code Playgroud)

请记住,Feature Union这将连接get_feature_names每个变换器各自发出的两个列表.这就是为什么当一个或多个变压器没有这种方法时你会收到错误的原因.

但是,我可以看到,仅此一项不能解决您的问题,因为Pipeline对象中没有get_feature_names方法,并且您有嵌套管道(功能联合中的管道).所以你有两个选择:

  1. Subclass Pipeline并get_feature_names自己添加方法,它从链中的最后一个变换器获取特征名称.

  2. 从每个变换器中自己提取功能名称,这将要求您自己从管道中获取这些变换器并调用get_feature_names它们.

另外,请记住,许多内置变换器的sklearn不能在DataFrame上运行,而是绕过numpy数组,所以如果要将大量变换器链接在一起,请注意它.但我认为这可以为您提供足够的信息,让您了解正在发生的事情.

还有一件事,看看sklearn-pandas.我自己没有使用它,但它可能为您提供解决方案.


Max*_*ner 5

您可以通过此调用不同的矢量化器作为嵌套功能(感谢 edesz):

pipevect= dict(pipeline.named_steps['union'].transformer_list).get('title').named_steps['count']
Run Code Online (Sandbox Code Playgroud)

然后你得到 TfidfVectorizer() 实例来传递另一个函数:

Show_most_informative_features(pipevect,
       pipeline.named_steps['classifier'], n=MostIF)
# or direct   
print(pipevect.get_feature_names())
Run Code Online (Sandbox Code Playgroud)