嵌套分词语料库中快速移除非通用词的高效实现方法
原代码的核心问题
- 有硬性逻辑bug,根本没法正确跑出结果:原代码里
Counter(corpus)直接传嵌套的文档列表,会把每一篇文档(本身是列表类型)当计数单元,一来列表不可哈希,这行代码跑起来直接抛类型错误;二来就算强行修通,统计的也是文档出现次数,完全不是单个词在全语料的出现频次。 - 慢的根本原因是数据结构选得不对:把要过滤的低频词存在普通列表里,每次判断词留不留,都要把整个低频词列表从头扫到尾找有没有匹配项。等语料规模上去、低频词数量多了,这部分的耗时会翻得特别夸张。
提效优化方案
核心优化逻辑
- 用生成器遍历全语料统计词频,不额外生成存所有词的临时大列表,省内存还快。
- 用集合替换原来的列表存待过滤的词,把成员查找从线性遍历改成哈希查表,这步能带来几倍到几十倍的速度提升,是整个优化里收益最高的改动。
- 完全不改变原功能的输出结果,只是把执行逻辑换得更高效。
优化后的可用代码
from collections import Counter from itertools import chain def remove_uncommon_words(corpus, threshold): # 基于生成器逐词统计全语料词频,无临时大列表的内存开销 word_freq = Counter(chain.from_iterable(corpus)) # 用集合存储需要过滤的低频词,替换原有的列表结构 uncommon_words = {word for word, count in word_freq.items() if count < threshold} # 逐文档生成清洗后的语料 clean_corpus = [[word for word in doc if word not in uncommon_words] for doc in corpus] return clean_corpus
可选的进一步提速
如果统计下来发现绝大多数词都满足阈值要求、属于要保留的通用词,可以反过来建一个“可保留词”的集合,只判断当前词在这个集合里就保留,和原功能完全等价,还能缩小集合体积,让查找速度再快一点:
# 替换低频词集合的定义 keep_words = {word for word, count in word_freq.items() if count >= threshold} # 对应调整判断逻辑 clean_corpus = [[word for word in doc if word in keep_words] for doc in corpus]
内容的提问来源于stack exchange,提问作者Emil
相关产品推荐
相关产品推荐

