Python 如何为tf idf矢量器创建scikit管道?

Python 如何为tf idf矢量器创建scikit管道?,python,machine-learning,scikit-learn,pipeline,tf-idf,Python,Machine Learning,Scikit Learn,Pipeline,Tf Idf,我正在学习如何创建用于文本数据分析的管道,然后将其用于网格搜索。但是,我遇到了一个问题,给定的方法不适用于这种情况 我希望此代码能够正常工作: 将numpy导入为np 作为pd进口熊猫 从sklearn.pipeline导入管道 从mlxtend.feature\u选择导入列选择器 从sklearn.feature_extraction.text导入TFIDF转换器 从sklearn.naiver_bayes导入贝努林b 从sklearn.feature\u extraction.text导入T

我正在学习如何创建用于文本数据分析的管道,然后将其用于网格搜索。但是,我遇到了一个问题,给定的方法不适用于这种情况

我希望此代码能够正常工作:

将numpy导入为np
作为pd进口熊猫
从sklearn.pipeline导入管道
从mlxtend.feature\u选择导入列选择器
从sklearn.feature_extraction.text导入TFIDF转换器
从sklearn.naiver_bayes导入贝努林b
从sklearn.feature\u extraction.text导入TfidfVectorizer
df_Xtrain=pd.DataFrame({'tweet':['thisatweet']*10,
“标签”:0})
y_train=df_Xtrain['label'].to_numpy().ravel()
管道([
('col_selector',ColumnSelector(cols=('tweet')),
('tfidf',tfidftranformer()),
('bernoulli',BernoulliNB()),
])
管道安装(df_Xtrain,y_train)
此代码适用于:

将numpy导入为np
作为pd进口熊猫
从sklearn.pipeline导入管道
从mlxtend.feature\u选择导入列选择器
从sklearn.feature_extraction.text导入TFIDF转换器
从sklearn.naiver_bayes导入贝努林b
从sklearn.feature\u extraction.text导入TfidfVectorizer
#资料
df_Xtrain=pd.DataFrame({'tweet':['thisatweet']*10,
“标签”:0})
y_train=df_Xtrain['label'].to_numpy().ravel()
#造型
mc=‘推特’
vec_tfidf=TfidfVectorizer()
向量拟合(df_Xtrain[mc])
X_train=vec_tfidf.transform(df_Xtrain[mc]).toarray()
模型=BernoulliNB()
模型拟合(X\U系列、y\U系列)
模型预测(X_列车)
模型分数(X_列、y_列)
问题 如何创建一个用于上述文本分析的管道

使现代化 版本

[('numpy', '1.17.5'),
 ('pandas', '1.0.5'),
 ('sklearn', '0.23.1'),
 ('mlxtend', '0.17.0')]

Python 3.7.7
错误日志
---------------------------------------------------------------------------
ValueError回溯(最近一次调用上次)
在里面
19
20
--->21管道安装(df_Xtrain,y_train)
~/opt/miniconda3/envs/spk/lib/python3.7/site-packages/sklearn/pipeline.py-in-fit(self,X,y,**fit_参数)
328         """
329配合参数步骤=自我检查配合参数(**配合参数)
-->330 Xt=自拟合(X,y,**拟合参数步数)
331,带有“打印”经过的时间(“管道”,
332自我记录信息(len(self.steps)-1):
~/opt/miniconda3/envs/spk/lib/python3.7/site-packages/sklearn/pipeline.py in\u fit(self、X、y、**fit\u参数步骤)
294消息_clsname='Pipeline',
295消息=自我记录消息(步骤idx),
-->296**fit_params_steps[名称])
297#将阶梯变压器更换为已安装的变压器
298#变压器。这在加载变压器时是必要的
~/opt/miniconda3/envs/spk/lib/python3.7/site-packages/joblib/memory.py in\uuuuu调用(self,*args,**kwargs)
350
351定义调用(self,*args,**kwargs):
-->352返回self.func(*args,**kwargs)
353
354 def呼叫和搁置(self、*args、**kwargs):
~/opt/miniconda3/envs/spk/lib/python3.7/site-packages/sklearn/pipeline.py in_-fit_-transform_-one(变压器、X、y、重量、消息名称、消息、**fit_参数)
738带有“打印”经过的时间(消息名称,消息):
739如果hasattr(变压器,“拟合变换”):
-->740 res=变换器。拟合变换(X,y,**拟合参数)
741其他:
742 res=变换器.fit(X,y,**fit_参数).transform(X)
拟合变换中的~/opt/miniconda3/envs/spk/lib/python3.7/site-packages/sklearn/base.py(self、X、y、**拟合参数)
691其他:
692算术2的拟合方法(监督变换)
-->693返回自拟合(X,y,**拟合参数).transform(X)
694
695
~/opt/miniconda3/envs/spk/lib/python3.7/site-packages/sklearn/feature\u extraction/text.py in fit(self,X,y)
1429术语/标记计数矩阵。
1430         """
->1431 X=检查数组(X,接受稀疏=('csr','csc'))
1432如果不是sp.issparse(X):
1433 X=sp.csr_矩阵(X)
内部文件中的~/opt/miniconda3/envs/spk/lib/python3.7/site-packages/sklearn/utils/validation.py(*args,**kwargs)
71未来警告)
72 kwargs.update({k:arg代表k,arg在zip中(sig.parameters,args)})
--->73返回f(**kwargs)
74返回内部\u f
75
检查数组中的~/opt/miniconda3/envs/spk/lib/python3.7/site-packages/sklearn/utils/validation.py
597 array=array.astype(dtype,casting=“不安全”,copy=False)
598其他:
-->599数组=np.asarray(数组,顺序=order,dtype=dtype)
600除复杂警告外:
601 raise VALUERROR(“不支持复杂数据\n”
asarray中的~/opt/miniconda3/envs/spk/lib/python3.7/site-packages/numpy/core//\u asarray.py(a,数据类型,顺序)
83
84     """
--->85返回数组(a,数据类型,副本=False,顺序=order)
86
87
ValueError:无法将字符串转换为浮点:“这是一条tweet”

您的代码有两个主要问题-

  • 您使用的是
    tfidftransformer
    ,之前没有使用
    countvectorier
    。相反,只需使用一个
    tfidvectorier
    ,它一次完成这两个功能
  • 您的
    columnselector
    正在返回一个2D数组
    (n,1)
    ,而
    TFIDFvectorier
    需要一个1D数组
    (n,)
    。这可以通过设置参数
    drop\u axis=True来完成
  • 进行上述更改后,这应该会起作用-

    import numpy as np
    import pandas as pd
    from sklearn.pipeline import Pipeline
    from mlxtend.feature_selection import ColumnSelector
    from sklearn.feature_extraction.text import TfidfVectorizer
    from sklearn.naive_bayes import BernoulliNB
    
    
    
    df_Xtrain = pd.DataFrame({'tweet': ['This is a tweet']*10,
                              'label': 0})
    y_train = df_Xtrain['label'].to_numpy().ravel()
    
    pipe = Pipeline([
        ('col_selector', ColumnSelector(cols=('tweet'),drop_axis=True)),
        ('tfidf', TfidfVectorizer()),
        ('bernoulli', BernoulliNB()),
    ])
    
    
    pipe.fit(df_Xtrain,y_train)
    


    编辑:对问题的回答-“没有mlxtend包,这可能吗?为什么我需要这里的ColumnSelector?只有sklearn有解决方案吗?”

    是的,我也是
    import numpy as np
    import pandas as pd
    from sklearn.pipeline import Pipeline
    from mlxtend.feature_selection import ColumnSelector
    from sklearn.feature_extraction.text import TfidfVectorizer
    from sklearn.naive_bayes import BernoulliNB
    
    
    
    df_Xtrain = pd.DataFrame({'tweet': ['This is a tweet']*10,
                              'label': 0})
    y_train = df_Xtrain['label'].to_numpy().ravel()
    
    pipe = Pipeline([
        ('col_selector', ColumnSelector(cols=('tweet'),drop_axis=True)),
        ('tfidf', TfidfVectorizer()),
        ('bernoulli', BernoulliNB()),
    ])
    
    
    pipe.fit(df_Xtrain,y_train)
    
    Pipeline(steps=[('col_selector', ColumnSelector(cols='tweet', drop_axis=True)),
                    ('tfidf', TfidfVectorizer()), ('bernoulli', BernoulliNB())])
    
    class SelectColumnsTransformer():
        def __init__(self, columns=None):
            self.columns = columns
    
        def transform(self, X, **transform_params):
            cpy_df = X[self.columns].copy()
            return cpy_df
    
        def fit(self, X, y=None, **fit_params):
            return self
    
    
    # Add it to a pipeline 
    pipe = Pipeline([
        ('selector', SelectColumnsTransformer([<input col name here>]))
    ])