Как удалить стоп-слова из документов в gensim?

Я создаю приложение чата NLP, используя технику Doc2Vec в Python, используя его пакет gensim. Я уже сделал токенизацию и стемминг. Я хочу удалить стоп-слова (чтобы проверить, работает ли он лучше) как из тренировочного набора, так и из вопроса, который бросает пользователь.

Вот мой код.

import gensim
import nltk
from gensim import models
from gensim import utils
from gensim import corpora
from nltk.stem import PorterStemmer
ps = PorterStemmer()

sentence0 = models.doc2vec.LabeledSentence(words=[u'sampl',u'what',u'is'],tags=["SENT_0"])
sentence1 = models.doc2vec.LabeledSentence(words=[u'sampl',u'tell',u'me',u'about'],tags=["SENT_1"])
sentence2 = models.doc2vec.LabeledSentence(words=[u'elig',u'what',u'is',u'my'],tags=["SENT_2"])
sentence3 = models.doc2vec.LabeledSentence(words=[u'limit', u'what',u'is',u'my'],tags=["SENT_3"])
sentence4 = models.doc2vec.LabeledSentence(words=[u'claim',u'how',u'much',u'can',u'I'],tags=["SENT_4"])
sentence5 = models.doc2vec.LabeledSentence(words=[u'retir',u'i',u'am',u'how',u'much',u'can',u'elig',u'claim'],tags=["SENT_5"])
sentence6 = models.doc2vec.LabeledSentence(words=[u'resign',u'i',u'have',u'how',u'much',u'can',u'i',u'claim',u'elig'],tags=["SENT_6"])
sentence7 = models.doc2vec.LabeledSentence(words=[u'promot',u'what',u'is',u'my',u'elig',u'post',u'my'],tags=["SENT_7"])
sentence8 = models.doc2vec.LabeledSentence(words=[u'claim',u'can,',u'i',u'for'],tags=["SENT_8"])
sentence9 = models.doc2vec.LabeledSentence(words=[u'product',u'coverag',u'cover',u'what',u'all',u'are'],tags=["SENT_9"])
sentence10 = models.doc2vec.LabeledSentence(words=[u'hotel',u'coverag',u'cover',u'what',u'all',u'are'],tags=["SENT_10"])
sentence11 = models.doc2vec.LabeledSentence(words=[u'onlin',u'product',u'can',u'i',u'for',u'bought',u'through',u'claim',u'sampl'],tags=["SENT_11"])
sentence12 = models.doc2vec.LabeledSentence(words=[u'reimburs',u'guidelin',u'where',u'do',u'i',u'apply',u'form',u'sampl'],tags=["SENT_12"])
sentence13 = models.doc2vec.LabeledSentence(words=[u'reimburs',u'procedur',u'rule',u'and',u'regul',u'what',u'is',u'the',u'for'],tags=["SENT_13"])
sentence14 = models.doc2vec.LabeledSentence(words=[u'can',u'i',u'submit',u'expenditur',u'on',u'behalf',u'of',u'my',u'friend',u'and',u'famili',u'claim',u'and',u'reimburs'],tags=["SENT_14"])
sentence15 = models.doc2vec.LabeledSentence(words=[u'invoic',u'bills',u'procedur',u'can',u'i',u'submit',u'from',u'shopper stop',u'claim'],tags=["SENT_15"])
sentence16 = models.doc2vec.LabeledSentence(words=[u'invoic',u'bills',u'can',u'i',u'submit',u'from',u'pantaloon',u'claim'],tags=["SENT_16"])
sentence17 = models.doc2vec.LabeledSentence(words=[u'invoic',u'procedur',u'can',u'i',u'submit',u'invoic',u'from',u'spencer',u'claim'],tags=["SENT_17"])

# User asks a question.

document = input("Ask a question:")
tokenized_document = list(gensim.utils.tokenize(document, lowercase = True, deacc = True))
#print(type(tokenized_document))
stemmed_document = []
for w in tokenized_document:
    stemmed_document.append(ps.stem(w))
sentence19 = models.doc2vec.LabeledSentence(words= stemmed_document, tags=["SENT_19"])

# Building vocab.
sentences = [sentence0,sentence1,sentence2,sentence3, sentence4, sentence5,sentence6, sentence7, sentence8, sentence9, sentence10, sentence11, sentence12, sentence13, sentence14, sentence15, sentence16, sentence17, sentence19]

#I tried to remove the stop words but it didn't work out as LabeledSentence object has no attribute lower.
stoplist = set('for a of the and to in'.split())
texts = [[word for word in document.lower().split() if word not in stoplist]
          for document in sentences]
..

Есть ли способ удалить стоп-слова из sentences напрямую и получить новый набор слов без стоп-слов?


person Kshitiz    schedule 22.06.2017    source источник


Ответы (1)


Ваш объект sentences уже представляет собой список объектов LabeledSentence. Вы строите их выше; они включают список строк в words и список строк в tags.

Таким образом, к каждому элементу в этом списке (document в вашем понимании списка) не может быть применен строковый метод, такой как .lower(). (И это не обязательно должно быть .split(), поскольку его words уже являются отдельными токенами.)

Самый чистый подход — удалить стоп-слова из списков слов перед их использованием для создания LabeledSentence объектов. Например, вы можете создать функцию without_stopwords(), определенную сверху. Тогда ваши строки, создающие объекты LabeledSentence, могут быть такими:

sentence0 = LabeledSentence(words=remove_stopwords([u'sampl', u'what', u'is']), 
                            tags=["SENT_0"])

Кроме того, вы можете мутировать существующие объекты LabeledSentence, чтобы в каждом из их атрибутов words теперь не было стоп-слов. Это заменит вашу последнюю строку чем-то вроде:

for doc in sentences:
    doc.words = [word for word in doc.words if word not in stoplist]
texts = sentences

Отдельно то, о чем вы не спрашивали, но должны знать:

  • TaggedDocument теперь является предпочтительным именем примера класса для текстовых объектов Doc2Vec, но на самом деле любой объект, имеющий два обязательных свойства words и tags, будет работать нормально.

  • Doc2Vec не показывает многие желаемые свойства на крошечных наборах данных размером с игрушку — не удивляйтесь, если модель, построенная на десятках предложений, не делает ничего полезного или вводит в заблуждение относительно того, какие варианты предварительной обработки/метапараметров являются лучшими. (Десятки тысяч текстов, а также тексты, состоящие не менее чем из десятков слов, намного лучше подходят для значимых результатов.)

  • Большая часть работы Word2Vec/Doc2Vec не связана с удалением корней или стоп-слов, но иногда это может быть полезно.

person gojomo    schedule 22.06.2017
comment
Да вы правы. Это не точно и в большинстве случаев дает неправильное косинусное сходство, но с этим ничего не поделаешь. Это данные, предоставленные мне. Вот почему я пытаюсь проверить, поможет ли удаление корней или стоп-слов. Не могли бы вы также предложить мне лучший подход к построению системы ответов на вопросы, когда у меня есть список примеров вопросов и ответов. Спасибо. - person Kshitiz; 23.06.2017
comment
Система ответов на вопросы — это довольно широкая область, и то, что может работать, может потребовать гораздо большего, чем Doc2Vec, и зависит от того, сколько и какие данные QA у вас есть. Для простого сходства новых вопросов с предыдущими может работать Doc2Vec, но вам потребуется намного больше обучающих данных. Существует также интересный метод сходства предложений под названием Word Mover's Distance, для которого нужны только слова (а не векторы, обученные для каждого документа). Это может сработать для поиска наиболее похожих более ранних вопросов. Он доступен в gensim Word2Vec/KeyedVectors как wmdistance(), но довольно медленно вычисляет попарно на больших наборах данных. - person gojomo; 23.06.2017