【问题标题】:Getting feature names from within a FeatureUnion + Pipeline从 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。”
  • 您可能想从另一个类似问题中查看此答案:stackoverflow.com/questions/28822756/…

标签: python-3.x scikit-learn nlp feature-extraction


【解决方案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 中的管道。)。所以你有两个选择:

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

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

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

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

【讨论】:

【解决方案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())

【讨论】:

    猜你喜欢
    • 2022-11-26
    • 1970-01-01
    • 2016-02-01
    • 2021-10-29
    • 2016-06-23
    • 1970-01-01
    • 2017-07-12
    • 1970-01-01
    • 2022-08-12
    相关资源
    最近更新 更多