在朴素贝叶斯中使用稀疏矩阵/在线学习(Python,scikit)



我正在尝试对拥有超过 6,000,000 个条目和每个条目 150k 个特征的数据集进行朴素贝叶斯。我尝试从以下链接实现代码:在 NLTK 中实现词袋朴素贝叶斯分类器

问题是(据我了解(,当我尝试使用dok_matrix作为参数运行训练方法时,它找不到迭代键(我已经将行与 OrderedDict 配对为标签(:

Traceback (most recent call last):
  File "skitest.py", line 96, in <module>
    classif.train(add_label(matr, labels))
  File "/usr/lib/pymodules/python2.6/nltk/classify/scikitlearn.py", line 92, in train
    for f in fs.iterkeys():
  File "/usr/lib/python2.6/dist-packages/scipy/sparse/csr.py", line 88, in __getattr__
    return _cs_matrix.__getattr__(self, attr)
  File "/usr/lib/python2.6/dist-packages/scipy/sparse/base.py", line 429, in __getattr__
    raise AttributeError, attr + " not found"
AttributeError: iterkeys not found

我的问题是,有没有办法通过逐个条目(在线(教授分类器条目来避免使用稀疏矩阵,或者在这种情况下是否可以有效地使用稀疏矩阵格式而不是dok_matrix?还是我错过了一些明显的东西?

谢谢大家的时间。 :)

编辑,9月6日:

找到了迭代键,所以至少代码可以运行。它仍然太慢了,因为使用32k大小的数据集已经花费了几个小时,但仍然没有完成。这是我目前得到的:

matr = dok_matrix((6000000, 150000), dtype=float32)
labels = OrderedDict()
#collect the data into the matrix
pipeline = Pipeline([('nb', MultinomialNB())])
classif = SklearnClassifier(pipeline)
add_label = lambda lst, lab: [(lst.getrow(x).todok(), lab[x])
                              for x in xrange(lentweets-foldsize)] 
classif.train(add_label(matr[:(lentweets-foldsize),0], labels))
readrow = [matr.getrow(x + foldsize).todok() for x in xrange(lentweets-foldsize)]
data = np.array(classif.batch_classify(readrow))

问题可能是,获取的每一行都没有利用向量的稀疏性,而是遍历 150k 条目中的每一个。作为问题的延续,有谁知道如何利用这个带有稀疏矩阵的朴素贝叶斯,或者有没有其他方法来优化上面的代码?

查看scikit-learn中的文档分类示例。诀窍是让库为您处理特征提取。跳过 NLTK 包装器,因为它不适用于如此大的数据集。(*)

如果你有文本文件中的文档,那么你可以将这些文本文件交给TfidfVectorizer,这会从它们创建一个稀疏矩阵:

from sklearn.feature_extraction.text import TfidfVectorizer
vect = TfidfVectorizer(input='filename')
X = vect.fit_transform(list_of_filenames)

您现在有一个 CSR 稀疏矩阵格式的训练集X,如果您还有标签列表y(如果您在其中对类进行编码,则可能派生自文件名(,则可以将其馈送到 Naive Bayes 分类器:

from sklearn.naive_bayes import MultinomialNB
nb = MultinomialNB()
nb.fit(X, y)

如果事实证明这不起作用,因为文档集太大(不太可能,因为TfidfVectorizer只针对这么多文档进行了优化(,请查看核心外文档分类示例,该示例演示了用于小批量学习的HashingVectorizerpartial_fit API。你需要scikit-learn 0.14才能工作。

(*( 我知道,因为我写了那个包装纸。像NLTK的其他部分一样,它用于教育目的。我还致力于scikit-learn的性能改进,我宣传的一些代码是我自己的。

最新更新