我发现很难理解如何修复我创建的Pipeline(请阅读:大部分是从教程中粘贴过来的)。它是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)
当我运行它时,我得到:
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等尝试了很多解决方案,但我仍然不知道如何修复它。是的,类似的问题以前也出现过,但不是在管道中。我必须在哪里应用toarray
或todense
?
6条答案
按热度按时间3duebb1j1#
不幸的是,这两个是不兼容的。
CountVectorizer
产生一个稀疏矩阵,而RandomForestClassifier需要一个密集矩阵。可以使用X.todense()
进行转换。这样做会大大增加你的内存占用。下面是基于http://zacstewart.com/2014/08/05/pipelines-of-featureunions-of-pipelines.html的示例代码,它允许您在管道阶段调用
.todense()
。一旦有了
DenseTransformer
,就可以将其作为流水线步骤添加。另一种选择是使用用于稀疏数据的分类器,如
LinearSVC
。u7up0aaq2#
最简洁的解决方案是使用
FunctionTransformer
转换为密集:这将自动实现fit
、transform
和fit_transform
方法,如大卫的答案所示。另外,如果我不需要为我的管道步骤命名,我喜欢使用sklearn.pipeline.make_pipeline
便利函数来启用更简约的语言来描述模型:x0fgdtte3#
0.16-dev中的随机森林现在接受稀疏数据。
ykejflvf4#
你可以使用
.values
方法将pandasSeries
改为数组。然而,我认为这里的问题是因为
CountVectorizer()
默认返回一个稀疏矩阵,并且不能通过管道传输到RF分类器。CountVectorizer()
确实有一个dtype
参数来指定返回的数组类型。也就是说,通常你需要做某种降维来使用随机森林进行文本分类,因为词袋特征向量非常长66bbxpm55#
我发现FunctionTransformer和使用x.toarray()而不是x.todense()对我很有效。
uqjltbpv6#
使用此管道添加TfidTransformer plus
上面的第一行,以稀疏矩阵的形式获取文档的字数。然而,在实践中,您可能会使用TfidfTransformer在一组新的未见过的文档上计算tfidf分数。然后,通过调用tfidf transformer.transform(vectorizer),您最终将计算文档的tf-idf分数。在内部,这是计算tf * idf乘法,其中词频由其idf值加权。