Scikit-Learn 的流水线:传递了一个稀疏矩阵,但需要密集数据 [英] Scikit-Learn's Pipeline: A sparse matrix was passed, but dense data is required

查看:17
本文介绍了Scikit-Learn 的流水线:传递了一个稀疏矩阵,但需要密集数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现很难理解如何修复我创建的管道(阅读:主要从教程中粘贴).这是python 3.4.2:

I'm finding it difficult to understand how to fix a Pipeline I created (read: largely pasted from a tutorial). It's python 3.4.2:

df = pd.DataFrame
df = DataFrame.from_records(train)

test = [blah1, blah2, blah3]

pipeline = Pipeline([('vectorizer', CountVectorizer()), ('classifier', RandomForestClassifier())])

pipeline.fit(numpy.asarray(df[0]), numpy.asarray(df[1]))
predicted = pipeline.predict(test)

当我运行它时,我得到:

When I run it, I get:

TypeError: A sparse matrix was passed, but dense data is required. Use X.toarray() to convert to a dense numpy array.

这是针对行 pipeline.fit(numpy.asarray(df[0]), numpy.asarray(df[1])).

我通过 numpy、scipy 等对解决方案进行了大量实验,但我仍然不知道如何解决它.是的,以前也出现过类似的问题,但不是在管道内.我必须在哪里应用 toarraytodense?

I've experimented a lot with solutions through numpy, scipy, and so forth, but I still don't know how to fix it. And yes, similar questions have come up before, but not inside a pipeline. Where is it that I have to apply toarray or todense?

推荐答案

不幸的是,这两者不兼容.CountVectorizer 产生一个稀疏矩阵,而 RandomForestClassifier 需要一个密集矩阵.可以使用 X.todense() 进行转换.这样做会大大增加您的内存占用.

Unfortunately those two are incompatible. A CountVectorizer produces a sparse matrix and the RandomForestClassifier requires a dense matrix. It is possible to convert using X.todense(). Doing this will substantially increase your memory footprint.

以下是基于 http 执行此操作的示例代码://zacstewart.com/2014/08/05/pipelines-of-featureunions-of-pipelines.html 允许您在管道阶段调用 .todense().

Below is sample code to do this based on http://zacstewart.com/2014/08/05/pipelines-of-featureunions-of-pipelines.html which allows you to call .todense() in a pipeline stage.

class DenseTransformer(TransformerMixin):

    def fit(self, X, y=None, **fit_params):
        return self

    def transform(self, X, y=None, **fit_params):
        return X.todense()

一旦您拥有 DenseTransformer,您就可以将其添加为管道步骤.

Once you have your DenseTransformer, you are able to add it as a pipeline step.

pipeline = Pipeline([
     ('vectorizer', CountVectorizer()), 
     ('to_dense', DenseTransformer()), 
     ('classifier', RandomForestClassifier())
])

另一种选择是使用用于稀疏数据的分类器,例如 LinearSVC.

Another option would be to use a classifier meant for sparse data like LinearSVC.

from sklearn.svm import LinearSVC
pipeline = Pipeline([('vectorizer', CountVectorizer()), ('classifier', LinearSVC())])

这篇关于Scikit-Learn 的流水线:传递了一个稀疏矩阵,但需要密集数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆