Удалить список стоп-слов из счетчика в Python
У меня есть функция в NLTK для создания списка соответствия, который будет выглядеть
concordanceList = ["this is a concordance string something",
"this is another concordance string blah"]
и у меня есть другая функция, которая возвращает словарь счетчика с количеством каждого слова в concordanceList
def mostCommonWords(concordanceList):
finalCount = Counter()
for line in concordanceList:
words = line.split(" ")
currentCount = Counter(words)
finalCount.update(currentCount)
return finalCount
Проблема у меня заключается в том, как лучше всего удалить стоп-слова из полученного счетчика, чтобы при вызове
mostCommonWords(concordanceList).most_common(10)
результат не просто {"the": 100, "is": 78, "that": 57}.
Я думаю, что предварительная обработка текста для удаления стоп-слов не нужна, потому что мне все еще нужны строки соответствия, чтобы быть экземплярами грамматического языка. По сути, я спрашиваю, есть ли более простой способ сделать это, чем создать счетчик стоп-слов для стоп-слов, установить низкие значения, а затем сделать еще один счетчик, например, так:
stopWordCounter = Counter(the=1, that=1, so=1, and=1)
processedWordCounter = mostCommonWords(concordanceList) & stopWordCounter
который должен установить значения счетчика для всех стоп-слов в 1, но это выглядит странно.
Изменить: Кроме того, у меня возникают проблемы на самом деле сделать такой stopWordCounter, потому что, если я хочу включить зарезервированные слова, такие как "и", я получаю недопустимую синтаксическую ошибку. Счетчики имеют простые в использовании методы объединения и пересечения, которые делают задачу довольно простой; Есть ли эквивалентные методы для словарей?
6 ответов
Вы можете удалить стоп-слова во время токенизации...
stop_words = frozenset(['the', 'a', 'is'])
def mostCommonWords(concordanceList):
finalCount = Counter()
for line in concordanceList:
words = [w for w in line.split(" ") if w not in stop_words]
finalCount.update(words) # update final count using the words list
return finalCount
Во-первых, вам не нужно создавать все эти новые Counter
внутри вашей функции; ты можешь сделать:
for line in concordanceList:
finalCount.update(line.split(" "))
вместо.
Во-вторых, Counter
это своего рода словарь, поэтому вы можете удалять элементы напрямую:
for sword in stopwords:
del yourCounter[sword]
Неважно, sword
находится в Counter
- это не вызовет исключения независимо.
Я бы пошел на сглаживание элементов в слова, игнорируя любые стоп-слова и предоставляя это в качестве входных данных для одного Counter
вместо:
from collections import Counter
from itertools import chain
lines = [
"this is a concordance string something",
"this is another concordance string blah"
]
stops = {'this', 'that', 'a', 'is'}
words = chain.from_iterable(line.split() for line in lines)
count = Counter(word for word in words if word not in stops)
Или этот последний бит можно сделать так:
from itertools import ifilterfalse
count = Counter(ifilterfalse(stops.__contains__, words))
Лично я думаю, что ответ @JonClements был самым элегантным. Кстати, уже есть список stopwords
в NLTK, на случай, если OP не знает, смотрите проблему удаления стоп-слова NLTK
from collections import Counter
from itertools import chain
from nltk.corpus import stopwords
lines = [
"this is a concordance string something",
"this is another concordance string blah"
]
stops = stopwords.words('english')
words = chain.from_iterable(line.split() for line in lines)
count = Counter(word for word in words if word not in stops)
count = Counter(ifilterfalse(stops.__contains__, words))
Так же FreqDist
модуль в НЛТК имеет больше связанных с НЛП функций по сравнению с collections.Counter
, http://nltk.googlecode.com/svn/trunk/doc/api/nltk.probability.FreqDist-class.html
У вас есть несколько вариантов.
Во-первых, не считайте стоп-слова при обновлении Counter
- что вы можете сделать более кратко, так как Counter
объекты могут принимать итеративное, а также другое отображение для update
:
def mostCommonWords(concordanceList):
finalCount = Counter()
stopwords = frozenset(['the', 'that', 'so'])
for line in concordanceList:
words = line.strip().split(' ')
finalCount.update([word for word in words if word not in stopwords])
return finalCount
Кроме того, вы можете использовать del
на самом деле удалить их из Counter
как только вы закончите.
Я также добавил strip
позвонить на line
до split
, Если бы вы были использовать split()
и поведение разделения по умолчанию на все пустое пространство, вам это не нужно, но split(' ')
не будет рассматривать символ новой строки как разделенный, поэтому последнее слово каждой строки будет иметь конечный символ \n
и будет считаться отличным от любых других явлений. strip
избавится от этого.