使用NLTK的FreqDist统计词频却返回字母频次的问题求助
问题原因与解决方法
问题根源
你犯了两个关键错误:
- 调用
word_tokenize后,本来得到的是单词列表,但你用str()把它转成了字符串。比如['good', 'movie']会变成"['good', 'movie']",这时候tokens1里存的已经不是单词集合,而是带括号、引号的文本字符串了。 - 后续循环拼接的
review_comments是一堆这类字符串的拼接结果,本质是长文本字符串。FreqDist处理字符串时,会默认按单个字符统计频次,所以你得到的是字母、空格、符号的频率,而非单词频率。
修正后的代码
# 第一步:只做分词,不要转成字符串 newdf['tokens1'] = newdf['review'].apply(word_tokenize) # 第二步:合并所有单词到一个列表,而非拼接字符串 review_comments = [] for tokens in newdf['tokens1']: review_comments.extend(tokens) # 第三步:统计单词频率 from nltk.probability import FreqDist fdist = FreqDist(review_comments) print(fdist)
或者用更简洁的写法:
newdf['tokens1'] = newdf['review'].apply(word_tokenize) # 用列表推导式合并所有单词 all_words = [word for tokens in newdf['tokens1'] for word in tokens] fdist = FreqDist(all_words) print(fdist)
额外优化提示
如果需要过滤停用词、标点,让统计结果更精准,可以在分词后再加一步处理:
from nltk.corpus import stopwords import string stop_words = set(stopwords.words('english')) punctuations = set(string.punctuation) def clean_tokens(tokens): return [word.lower() for word in tokens if word.lower() not in stop_words and word not in punctuations] newdf['tokens1'] = newdf['review'].apply(word_tokenize).apply(clean_tokens) all_words = [word for tokens in newdf['tokens1'] for word in tokens] fdist = FreqDist(all_words) print(fdist.most_common(10)) # 直接输出频次最高的10个单词
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

