NLTK - стоп-слова, хэширование списка - PullRequest
1 голос
/ 27 марта 2020

Я постараюсь сделать это как можно более легким для понимания, насколько я могу себе представить, как могут привести в бешенство длительные и затяжные проблемы.

У меня есть список твитов, все они хранятся в переменной с именем 'all_tweets'. (Это потому, что некоторые твиты попадают в категорию «текст», в то время как другие попадают в категорию «extended_tweet», поэтому мне пришлось объединить их вместе.

Я токенизировал твиты, и все это отлично работало. Я получил список каждого твита и каждого слова в твите разделен.

Сейчас я пытаюсь внедрить в код стоп-слова, чтобы я мог отфильтровать, как вы уже догадались, любые стоп-слова.

Мой код выглядит следующим образом:

wordVec = [nltk.word_tokenize(tweet) for tweet in all_tweets]
stopWords = set(stopwords.words('english'))
wordsFiltered = []

for w in wordVec:
    if w not in stopWords:
        wordsFiltered.append(w)

Я получаю следующую ошибку:

TypeError                                 Traceback (most recent call last)
<ipython-input-29-ae7a97fb3811> in <module>
      4 
      5 for w in wordVec:
----> 6     if w not in stopWords:
      7         wordsFiltered.append(w)

TypeError: unhashable type: 'list'

Я хорошо знаю, что не могу иметь sh над списком. Я просмотрел свои твиты и каждый набор слов находится в их собственном списке. Я очень хорошо знаю, что происходит, но есть ли способ обойти эту проблему?

Любая помощь будет признательна спасибо.

Ответы [ 3 ]

1 голос
/ 27 марта 2020

ваша переменная wordVec представляет собой список списков, поэтому, когда вы делаете:

for w in wordVec:
    if w not in stopWords:

вы проверяете, есть ли список в наборе, w - это список, поэтому вы получаете

TypeError: unhashable type: 'list'

вы можете исправить:

for w in wordVec:
    word_tokenize.append([e for e in w if e not in stop_words]))

или использовать понимание списка:

word_tokenize = [[e for e in w if e not in stop_words] for w in wordVec]
1 голос
/ 27 марта 2020

Вы сказали, что хорошо знаете, что происходит, но не так ли? wordVec это не список строк, это список списков строк.

Поэтому, когда вы говорите: for w in wordVec:

w это не слово, это список слова. Это означает, что если вы скажете:

if w not in stopWords:

Вы спрашиваете, есть ли в списке текущий список слов. Вы не можете помещать списки в наборы, потому что они изменчивы и не могут быть хэшированы, поэтому возникает ошибка.

Я предполагаю, что вы действительно хотели сделать, это перебрать списки слов, а затем перебрать над словами в текущем списке.

import nltk
from nltk.corpus import stopwords


tweets = [
    "Who here likes cheese? I myself like cheese.",
    "Do you have cheese? Do they have cheese?"
]

tokenized_tweets = [nltk.word_tokenize(tweet) for tweet in tweets]
stop_words = set(stopwords.words("english"))

filtered_tweets = []

for tokenized_tweet in tokenized_tweets:
    filtered_tweets.append(" ".join(word for word in tokenized_tweet if word.casefold() not in stop_words))

print(filtered_tweets)

Вывод:

['likes cheese ? like cheese .', 'cheese ? cheese ?']

Я просто произвольно решил присоединиться к списку отфильтрованных слов перед добавлением их в список filtered_tweets - как Вы можете видеть, что это приводит к тому, что знаки препинания разделяются пробелами, что может быть нежелательно. В любом случае вам не нужно объединять слова обратно в строку, вы можете просто добавить сам список.

0 голосов
/ 28 марта 2020

попробуйте это:

text = 'hello my friend, how are you today, are you ok?'
tokenized_word=word_tokenize(text)
stop_words = set(stopwords.words('english'))
stops = []
for w in tokenized_word:
    if w not in stop_words:
        stops.append(w)
print(stops)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...