【问题标题】:ColumnTransformer fails with CountVectorizer in a pipelineColumnTransformer 在管道中使用 CountVectorizer 失败
【发布时间】:2019-11-08 18:43:35
【问题描述】:

我正在尝试使用sklearnCountVectorizer 在管道中结合ColumnTransformer 转换文本。但是,管道返回不正确的数组。为什么我的带有 ColumnTransformer 的管道给了我一个错误的 CountVectorize-d 文本的 1×1 数组?

我意识到我可以简单地使用带有 CountVectorizer 的单个管道,并省略 ColumnTransformer。但是,稍后我将需要添加数字列,这使得ColumnTransformer 成为必要。我最初尝试过,发现了错误,并将问题与上述问题隔离开来。

我尝试将X 输入为系列而不是数据框,但出现另一个错误:IndexError: tuple index out of range

data = pd.DataFrame(data={'text_feat':['This is my first sentence.','This is my second.'], 
                          'numeric_feat':[1,2], 
                          'target':[3,4]})
X = data.loc[:,['text_feat', 'numeric_feat']]
y = data.loc[:,'target']

# first pipeline 
text_features = ['text_feat']
text_transformer = Pipeline(
        steps = [('vec', CountVectorizer())])

# wrap in ColumnTransformer
preprocessor = ColumnTransformer(
        transformers=[('text', text_transformer, text_features)])

# second pipeline
pipeline = Pipeline(steps=[('preprocessor', preprocessor)])

# single pipeline works as expected
X_expected = text_transformer.fit_transform(X['text_feat'])

# but this fails
X_test = pipeline.fit_transform(X)

print('Expected:')
print(X_expected.toarray())
print('Got:')
print(X_test)

我期望 2×6 数组 array([[1, 1, 1, 0, 1, 1], [0, 1, 1, 1, 0, 1]])(来自 CountVectorizer 的文档项矩阵)。相反,我得到了这个:array([[1]])。有什么想法吗?

【问题讨论】:

    标签: python pandas scikit-learn


    【解决方案1】:

    您可以使用make_column_transformer 并执行以下操作。其余是您可以应用其他转换的剩余功能。默认情况下,residual 设置为“drop”,这意味着将删除没有任何转换的剩余特征。:

    preprocess = make_column_transformer((CountVectorizer(), 'text_feat'), 
                                         remainder='passthrough')
    make_pipeline(preprocess).fit_transform(X)
    

    更多信息here

    以下博客详细介绍: https://jorisvandenbossche.github.io/blog/2018/05/28/scikit-learn-columntransformer/

    关于您的代码的一些提示: 在转换特征时,您不需要(阅读:不应该)传递 y(即目标)。 您的代码中的问题是因为您传递的是文本功能列表而不是命名列。如果你稍微改变你的代码,你应该得到相同的结果。

    preprocessor = ColumnTransformer(
            transformers=[('text', text_transformer, 'text_feat')])
    

    【讨论】:

    • 我进行了修复(文本列表功能仅针对字符串)。我想这就是我所需要的。现在,切换到make_column_transformer 会有什么额外的好处吗?
    • ColumnTransformer 的可定制性更高,因此需要更多参数。例如,命名您的变压器是强制性的。但是,它具有额外的好处,例如transformer_weights 等。make_column_transformer 更简洁一些。相同的论点适用于 make_pipeline 和 Pipeline 对象之间的差异。减去 transformer_weights 参数,因为它不适用于 Pipeline 对象。
    • 我也遇到了这个问题。将文本功能传递为 str 而不是 list 为我解决了这个问题。
    【解决方案2】:
    # wrap in ColumnTransformer
    preprocessor = ColumnTransformer(transformers=[('text', CountVectorizer(),'text_feat')])
    
    # second pipeline
    pipeline = Pipeline(steps=[('preprocessor', preprocessor)])
    
    X_test = pipeline.fit_transform(X)
    

    这很有效,对我来说似乎是最简单的。

    【讨论】:

      猜你喜欢
      • 2021-09-23
      • 2021-09-26
      • 2019-06-15
      • 2021-03-05
      • 2020-02-10
      • 1970-01-01
      • 2020-09-13
      • 2016-01-20
      • 2019-01-17
      相关资源
      最近更新 更多