Вопрос: Использование разреженных матриц / онлайн-обучения в Naive Bayes (Python, scikit)


Я пытаюсь сделать Naive Bayes в наборе данных, который имеет более 6 000 000 записей и каждая запись 150k. Я попытался реализовать код по следующей ссылке: Внедрение классификатора наивного байеса в НЛТК

Проблема (насколько я понимаю), что когда я пытаюсь запустить метод train с dok_matrix как его параметр, он не может найти 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

Мой вопрос в том, есть ли способ избежать использования разреженной матрицы, изучая запись классификатора путем записи (онлайн), или есть разреженный матричный формат, который я мог бы использовать в этом случае эффективно вместо dok_matrix? Или я пропущу что-то очевидное?

Спасибо за чужое время. :)

EDIT, 6-й сегмент:

Найдено iterkeys, так что по крайней мере код работает. Он все еще слишком медленный, так как он занял несколько часов с набором данных размером 32 тыс. И до сих пор не закончен. Вот что я получил в данный момент:

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. Как продолжение этой проблемы, кто-нибудь знает, как использовать этот Naive Bayes с разреженными матрицами, или есть ли другой способ оптимизировать вышеуказанный код?


5


источник


Ответы:


Проверьте пример классификации документов  в scikit-learn. Хитрость заключается в том, чтобы позволить библиотеке обработать извлечение функции для вас. Пропустите оболочку NLTK, поскольку она не предназначена для таких больших наборов данных. (*)

Если у вас есть документы в текстовых файлах, вы можете просто передать эти текстовые файлы TfidfVectorizer, который создает из них разреженную матрицу:

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

Теперь у вас есть тренировочный набор X в разрешенном матричном формате CSR, который вы можете подавать в классификатор Naive Bayes, если у вас также есть список меток y (возможно, выведенные из имен файлов, если вы закодировали в них класс):

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

Если это окажется, это не сработает, потому что набор документов слишком велик (маловероятно, поскольку TfidfVectorizer был оптимизирован только для этого количества документов), посмотрите стандартная классификация документов  пример, демонстрирующий HashingVectorizer и partial_fit API для обучения в микроавтобусах. Для этого вам понадобится scikit-learn 0.14.

(*) Я знаю, потому что я написал эту обертку. Как и остальные НЛТК, он предназначен для образовательных целей. Я также работал над улучшением производительности в scikit-learn, а часть кода, который я рекламирую, является моей.


3