在Naive Bayes中使用稀疏矩阵/在线学习(Python,scikit)

use*_*859 5 python scipy sparse-matrix scikit-learn

我正在尝试在数据集上做Naive Bayes,该数据集有超过6,000,000个条目,每个条目有150k的特征.我试图从以下链接实现代码: 在NLTK中实现Bag-of-Words Naive-Bayes分类器

问题是(据我所知),当我尝试使用dok_matrix作为参数运行train-method时,它无法找到iterkeys(我已将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
Run Code Online (Sandbox Code Playgroud)

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

谢谢你的时间.:)

编辑,第6节:

找到了iterkeys,所以至少代码运行.它仍然太慢,因为它花了几个小时的数据集大小为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))
Run Code Online (Sandbox Code Playgroud)

问题可能是所采取的每一行都不利用向量的稀疏性,而是通过150k条目中的每一个.作为该问题的延续,有没有人知道如何利用稀疏矩阵使用这个朴素贝叶斯,还是有其他方法来优化上述代码?

Fre*_*Foo 5

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

如果您的文档位于文本文件中,则只需将这些文本文件交给TfidfVectorizer,即可从中创建一个稀疏矩阵:

from sklearn.feature_extraction.text import TfidfVectorizer
vect = TfidfVectorizer(input='filename')
X = vect.fit_transform(list_of_filenames)
Run Code Online (Sandbox Code Playgroud)

现在,您有了XCSR稀疏矩阵格式的训练集,如果您还具有标签列表y(如果您使用文件名对类进行编码,则可能源自文件名),则可以将其提供给Naive Bayes分类器:

from sklearn.naive_bayes import MultinomialNB
nb = MultinomialNB()
nb.fit(X, y)
Run Code Online (Sandbox Code Playgroud)

如果事实证明这是因为文档集太大而导致的(由于TfidfVectorizer仅仅针对此数量的文档进行了优化,则不太可能),请查看核心文档分类示例,该示例演示了HashingVectorizerpartial_fitAPI小批量学习。您需要scikit-learn 0.14才能正常工作。

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