从 FeatureUnion + Pipeline 中获取功能名称

Posted

技术标签:

【中文标题】从 FeatureUnion + Pipeline 中获取功能名称【英文标题】:Getting feature names from within a FeatureUnion + Pipeline 【发布时间】:2017-07-17 16:33:15 【问题描述】:

我正在使用 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() 会给我一个错误:“Transformer title (type Pipeline) 不提供 get_feature_names。”我想看看我的不同 Vectorizer 生成的一些功能。我该怎么做?

【问题讨论】:

您在调用union.get_feature_names()时是否遇到任何错误? 这是错误:“变压器标题(管道类型)不提供 get_feature_names。” 您可能想从另一个类似问题中查看此答案:***.com/questions/28822756/… 【参考方案1】:

这是因为您使用的是名为 TextSelector 的自定义变压器。你在TextSelector 中实现了get_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 发出的两个列表。这就是为什么当您的一个或多个变压器没有此方法时会出现错误的原因。

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

    子类管道并自己添加get_feature_names方法,它从链中的最后一个转换器获取特征名称。

    自己从每个转换器中提取功能名称,这需要您自己从管道中取出这些转换器并调用get_feature_names

另外,请记住,许多 sklearn 内置转换器不会在 DataFrame 上运行,而是传递 numpy 数组,因此如果您要将大量转换器链接在一起,请注意它。但我认为这为您提供了足够的信息,让您了解正在发生的事情。

还有一点,看看sklearn-pandas。我自己没有使用过,但它可能会为您提供解决方案。

【讨论】:

(1)相关公关:get_feature_names support for pipelines【参考方案2】:

您可以通过以下方式将不同的矢量化器称为嵌套功能(感谢 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())

【讨论】:

以上是关于从 FeatureUnion + Pipeline 中获取功能名称的主要内容,如果未能解决你的问题,请参考以下文章

sklearn中pipeline的用法和FeatureUnion

如何使用 sklearn Pipeline 和 FeatureUnion 选择多个(数字和文本)列进行文本分类?

使用 Python Scikit-learn 中的 Pipeline 和 featureUnion 将多个功能合二为一

如何在 FeatureUnion 中对 scikit 转换器进行特征选择

featureUnion vs columnTransformer?

如何使 FeatureUnion 返回数据框