NLTK - стоп-слова, хэширование списка

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

У меня есть список твитов, все они хранятся в переменной «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'

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

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

Всего 3 ответа


Вы сказали, что хорошо знаете, что происходит, но не так ли? 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 - как вы можете видеть, это приводит к тому, что знаки препинания разделяются пробелами, что может быть нежелательно. В любом случае вам не нужно объединять слова обратно в строку, вы можете просто добавить сам список.


ваша переменная 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]

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

    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)

Есть идеи?

10000