为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 scikit-learn 管道中的 CountVectorizer 之前包含

如何在 scikit-learn 管道中的 CountVectorizer 之前包含

杨__羊羊 2023-03-22 16:56:58
我有一个DataFrame包含一列文本的熊猫,我想使用 scikit-learn对文本进行矢量化CountVectorizer。但是,文本包含缺失值,因此我想在矢量化之前估算一个常数值。我最初的想法是创建一个PipelineofSimpleImputer和CountVectorizer:import pandas as pdimport numpy as npdf = pd.DataFrame({'text':['abc def', 'abc ghi', np.nan]})from sklearn.impute import SimpleImputerimp = SimpleImputer(strategy='constant')from sklearn.feature_extraction.text import CountVectorizervect = CountVectorizer()from sklearn.pipeline import make_pipelinepipe = make_pipeline(imp, vect)pipe.fit_transform(df[['text']]).toarray()但是,fit_transform错误是因为SimpleImputeroutputs a 2D array and CountVectorizerrequires 1D input。这是错误消息:AttributeError: 'numpy.ndarray' object has no attribute 'lower'问题:我如何修改它Pipeline才能使其正常工作?注意:我知道我可以估算熊猫中的缺失值。但是,我想在 scikit-learn 中完成所有预处理,以便可以使用Pipeline.
查看完整描述

3 回答

?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

我发现的最佳解决方案是将自定义转换器插入到 中Pipeline,在将输出SimpleImputer从 2D 传递到 1D 之前将其重塑CountVectorizer。


这是完整的代码:


import pandas as pd

import numpy as np

df = pd.DataFrame({'text':['abc def', 'abc ghi', np.nan]})


from sklearn.impute import SimpleImputer

imp = SimpleImputer(strategy='constant')


from sklearn.feature_extraction.text import CountVectorizer

vect = CountVectorizer()


# CREATE TRANSFORMER

from sklearn.preprocessing import FunctionTransformer

one_dim = FunctionTransformer(np.reshape, kw_args={'newshape':-1})


# INCLUDE TRANSFORMER IN PIPELINE

from sklearn.pipeline import make_pipeline

pipe = make_pipeline(imp, one_dim, vect)


pipe.fit_transform(df[['text']]).toarray()

GitHub上已经提出只要CountVectorizer第二个维度为1(意思是:单列数据)就应该允许2D输入。那个修改CountVectorizer将是这个问题的一个很好的解决方案!


查看完整回答
反对 回复 2023-03-22
?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

一种解决方案是创建一个 SimpleImputer 类并覆盖其transform()方法:


import pandas as pd

import numpy as np

from sklearn.impute import SimpleImputer



class ModifiedSimpleImputer(SimpleImputer):

    def transform(self, X):

        return super().transform(X).flatten()



df = pd.DataFrame({'text':['abc def', 'abc ghi', np.nan]})


imp = ModifiedSimpleImputer(strategy='constant')


from sklearn.feature_extraction.text import CountVectorizer

vect = CountVectorizer()


from sklearn.pipeline import make_pipeline

pipe = make_pipeline(imp, vect)


pipe.fit_transform(df[['text']]).toarray()


查看完整回答
反对 回复 2023-03-22
?
手掌心

TA贡献1942条经验 获得超3个赞

当我有一维数据时,我将这个一维包装器用于 sklearn Transformer。我认为,在您的情况下,此包装器可用于包装一维数据(具有字符串值的 pandas 系列)的 simpleImputer。


class OneDWrapper:

    """One dimensional wrapper for sklearn Transformers"""


    def __init__(self, transformer):

        self.transformer = transformer


    def fit(self, X, y=None):

        self.transformer.fit(np.array(X).reshape(-1, 1))

        return self


    def transform(self, X, y=None):

        return self.transformer.transform(

            np.array(X).reshape(-1, 1)).ravel()


    def inverse_transform(self, X, y=None):

        return self.transformer.inverse_transform(

            np.expand_dims(X, axis=1)).ravel()

现在,您不需要管道中的额外步骤。


one_d_imputer = OneDWrapper(SimpleImputer(strategy='constant'))

pipe = make_pipeline(one_d_imputer, vect)

pipe.fit_transform(df['text']).toarray() 

# note we are feeding a pd.Series here!


查看完整回答
反对 回复 2023-03-22
  • 3 回答
  • 0 关注
  • 149 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信