☰
中文分词与停用词过滤:用jieba构建高效文本分析管线
2026/10/12 5:46:50 网站建设 项目流程

1. 为什么要折腾中文分词和停用词

搞Python文本处理的人,迟早都会撞上中文分词这堵墙。英文天然按空格切开,中文却连词与词之间连个分界线都没有,不提前处理,后续做词频统计、关键词提取、情感分析都会变成一锅粥。我在处理一批用户反馈文本时,最开始直接按字符切,结果统计出来的“高频词”全是“的”“了”“是”这类没有任何分析价值的虚词,真正反映用户痛点的“卡顿”“闪退”“加载慢”反而被淹没了。后来切到jieba分词,再配合一套精心维护的停用词表,整个分析结果才终于对得起“洞察”这两个字。

先说清楚这篇东西适合谁看。如果你正在做文本分类、舆情监控、搜索建议、词云可视化,或者单纯想把一大段中文评论拆成有意义的词语,那你来对了。即使你完全没接触过jieba,跟着这篇操作也能在十分钟内跑通一个带停用词过滤的分词管线。

jieba是目前Python生态里使用最广泛的中文分词库,没有之一。它的核心优势有三个:一是分词准确率日常够用,二是支持自定义词典和停用词过滤,三是部署简单,pip装完直接用,不需要加载几百兆的模型文件。它的分词原理不像早期那些纯词典匹配的方案,而是基于前缀词典实现高效的词图扫描,再结合动态规划找出最大概率路径。简单说,就是它会把一句话切成若干种可能的分词方案,然后计算哪种切法整体概率最高,选概率最大的那个作为最终结果。这个机制保证了它在大多数场景下都能给出让人满意的切分。

不过,光有分词还远远不够。jieba切出来的结果里,依然会有大量“的”“了”“在”“是”“以及”这类功能词。它们语法上确实算词,但对分析任务来说基本是噪音。这时候就需要停用词表出马,把这些高频但无意义的词提前过滤掉,让剩下的词真正承载文本的主题信息。

2. 分词方案的技术拆解

2.1 jieba的三种分词模式,怎么选

jieba提供了三种分词模式,对应不同的使用场景,新手最常犯的错就是不分场合一律用全模式,导致结果又碎又乱。

精确模式是默认模式,也是我日常用最多的。它试图把句子切分成最合理的词序列,适合文本分析、关键词提取这类需要保留完整词语语义的场景。比如“我来到北京清华大学”,精确模式会切出“我/来到/北京/清华大学”,干净利落。

全模式则会把所有可能成词的组合都扫出来,速度极快,但结果冗余严重。同一句话它会输出“我/来到/北京/清华/清华大学/华大/大学”,因为“清华”“清华大学”“华大”“大学”都是词库里存在的词。全模式适合用来做词频统计的候选集召回,但不适合直接作为分析结果展示。

搜索引擎模式是精确模式和全模式的折中,它在精确模式的基础上,对长词再次切分,得到更细粒度的组合。比如“中华人民共和国”会被拆成“中华/人民/共和国/中华人民共和国”。这个模式适合搜索引擎的分词索引环节,能提高召回率。

用一句话总结选型思路:做分析用精确模式,做索引用搜索引擎模式,做候选召回可以用全模式但必须配合二次过滤。我的建议是默认就用精确模式,它能在速度和准确率之间取得最佳平衡。

2.2 底层原理:动态规划找最优路径

jieba分词的精髓在于它把分词问题转化成了路径规划问题。具体来说,它首先根据前缀词典构建一个有向无环图,图中的每个节点是句子中的一个位置,每条边代表一个可能的词。然后它用动态规划算法,从所有可能的切分路径中找出概率乘积最大的一条。

这个概率怎么来的?jieba基于大量语料统计了每个词的出现频率,频率越高的词,被选中的概率越大。所以“清华大学”这个词如果整体频率够高,jieba会倾向于把它作为一个整体词保留,而不是拆成“清华”和“大学”。这也解释了为什么领域术语如果没有出现在词库里,就会被错误地切开——因为它没被统计过,不被认为是一个词。

这个理解很重要,因为后续你遇到分词不准的问题时,第一反应不应该是怀疑算法不行,而应该检查这个词是否在词典里。解决办法也很明确:要么往自定义词典里加词,要么在加载时指定领域词典。

2.3 自定义词典:让分词更懂你的业务

jieba默认词库覆盖的是通用语料,一旦遇到专业术语、人名地名、网络新词,就会力不从心。我处理某家电品牌的售后评论时,“变频压缩机”总是被切成“变频/压缩机”,看起来没错,但我更希望它作为一个整体被识别,因为后续我要按整词做统计分析。

这时候用add_word方法或者词典文件就能解决。词典文件格式非常简单,每行一个词,后面可以跟词频和词性,用空格隔开:

变频压缩机 100 n 智能温控 50 n 不制冷 80 v

加载方式也简单,在初始化时指定词典路径即可:

import jieba jieba.load_userdict("custom_dict.txt")

自定义词典的优先级高于默认词库,所以即使默认词典里已经有相同词条的切分,也会优先使用你定义的切分方式。这个机制在处理业务专有名词时能省下大量手动修正的功夫。

3. 停用词表的构建与实战

3.1 什么是停用词,为什么要过滤

停用词指的是在文本中出现频率很高但携带信息量极低的词语。中文里最典型的就是“的”“了”“吗”“啊”“在”“是”“把”“被”这类虚词,以及“可以”“但是”“因为”“所以”这类连接词。

把这些词过滤掉,核心收益有两个。第一,词频统计会更有区分度。不过滤的时候,“的”字可能出现上千次,稳居榜首,其他所有词都显得微不足道;过滤之后,真正反映文本主题的名词、动词才能浮出水面。第二,后续算法效果更好。无论是做TF-IDF、训练词向量,还是做主题建模,减少噪音词都能提升模型的质量和收敛速度。

我在最早做词云的时候,因为没过滤停用词,生成的词云里最大的字永远是“的”“是”,整个图看起来毫无信息量。加了停用词表之后,词云的视觉重心才真正落到了业务关键词上。

3.2 如何构建一份够用的停用词表

网上能搜到很多现成的停用词表,比如哈工大停用词表、百度停用词表,但我一般不会直接拿过来用。原因是每个业务场景的噪音词都不一样。通用停用词表里没有“客服”“售后”这类词,但如果我分析的是客服聊天记录,这两个词出现频率极高且没有区分意义,就应该把它加进停用词表。

我的构建方法是三步走。第一步,收集通用的停用词,覆盖绝大多数虚词和代词,这步直接下载开源词表就能搞定。第二步,根据业务场景,把明显无意义的领域高频词加入其中。第三步,对第一批分词结果做词频统计,把排在前面的那些明显没有分析价值的词加进去,迭代两三轮之后,词表就会非常贴合自己的数据了。

这里给一个最小可用的停用词表示例,直接保存成stopwords.txt就能用:

的 了 是 在 我 有 和 就 不 人 都 一 一个 上 也 很 到 说 要 去 你 会 着 没有 看 好 自己 这 那 这个 那个 吧 吗 啊 呢 于是 但是 因为 所以 如果 而且 并且 或者 虽然 即使 尽管 以及 然后

3.3 过滤停用词的两种姿势

第一种姿势是在分词前过滤,也就是把停用词表传给自定义词典之外的逻辑处理。但这种方式其实不太现实,因为你没法让jieba不分出某些词。更通用的做法是在分词后过滤,对分词结果遍历一遍,把停用词表里的词剔除掉。

推荐的做法是这样:

import jieba def load_stopwords(path): with open(path, encoding="utf-8") as f: return {line.strip() for line in f if line.strip()} stopwords = load_stopwords("stopwords.txt") def filter_words(text, stopwords): words = jieba.lcut(text) return [w for w in words if w not in stopwords and w.strip()] text = "这款手机的屏幕显示效果很好,但电池续航不太行,而且充电速度也一般。" filtered = filter_words(text, stopwords) print(filtered)

用集合来存储停用词是关键,in操作的时间复杂度是O(1)。如果用小列表,每次判断都要遍历,句子一多整个程序会慢得你怀疑人生。

输出结果里,无效词被剔除,剩下的都是值得分析的实词。这一步做完,后面的词频统计、关键词提取才能真正反映文本主题。

4. 实操案例:从用户评论到词频洞察

4.1 场景设定与数据准备

我拿一个实际做过的案例来演示完整流程。假设我们拿到了某APP的一批用户评论,目标是分析用户最关注的功能点在哪,痛点集中在哪些方面。原始评论大概长这样:

这款软件安装包很大,每次打开都要等好久,不过界面设计挺好看的。 更新之后闪退了好几次,旧版本从来没这个问题,赶紧修复吧。 希望增加夜间模式,躺在床上刷的时候眼睛太难受了。 搜索功能很好用,结果很准,但历史记录不能同步是个遗憾。

这类短文本是典型的分析对象,信息密度高,虚词多,不处理没法看。直接对原始文本做词频统计的话,“的”“了”“很”“太”会霸榜,分析价值几乎为零。

4.2 完整分词过滤流水线

我把完整代码整合成一段可以直接跑的脚本:

import jieba from collections import Counter # 加载停用词表 def load_stopwords(path): with open(path, encoding="utf-8") as f: return {line.strip() for line in f if line.strip()} stopwords = load_stopwords("stopwords.txt") # 加载自定义词典 jieba.load_userdict("custom_dict.txt") # 分词的过滤 def clean_words(text, stopwords): words = jieba.lcut(text) result = [] for w in words: w = w.strip() if not w: continue if w in stopwords: continue if len(w) == 1: continue result.append(w) return result # 数据模拟 comments = [ "这款软件安装包很大,每次打开都要等好久,不过界面设计挺好看的。", "更新之后闪退了好几次,旧版本从来没这个问题,赶紧修复吧。", "希望增加夜间模式,躺在床上刷的时候眼睛太难受了。", "搜索功能很好用,结果很准,但历史记录不能同步是个遗憾。", ] # 统计 counter = Counter() for comment in comments: words = clean_words(comment, stopwords) counter.update(words) # 输出 for word, count in counter.most_common(15): print(f"{word}: {count}")

里面加了一个单字过滤逻辑,因为中文单字词绝大多数都是噪音,比如“大”“好”“刷”,除非你的业务确实需要统计单字,否则直接过滤掉能省不少事。

4.3 结果解读与踩坑记录

运行上面的脚本,你得到的高频词一定会集中在“闪退”“更新”“搜索”“夜间模式”“同步”“界面”“安装包”这些实义词上。只看词频你就能得到初步结论:用户提到最多的负面词是“闪退”,提到最多的功能诉求是“夜间模式”“历史记录”“同步”。这些词如果用原始文本统计是根本看不出来的。

这个案例里的一个隐性坑是“很好用”会被切成“很好/用”还是“很/好用”。jieba在不同版本里可能给出不同答案,解决办法是结合你的分析目标:如果关注点是功能,最好把“搜索功能”“夜间模式”这类词加入自定义词典,确保它们作为整体被切分和统计。

另一个坑是标点符号。上面代码里我用了jieba.lcut,它默认不会去掉标点,所以结果里还可能残留“,”和“。”。如果发现标点混入词频榜,可以在过滤逻辑里加一个正则约束,只保留中文字符和少量英文数字:

import re def is_valid_word(w): return re.fullmatch(r"[\u4e00-\u9fa5a-zA-Z0-9]+", w) is not None

把is_valid_word的判断加到过滤逻辑里,标点就不会再混进来了。

5. 进阶:自定义词典和停用词的协同优化

5.1 为什么自定义词典必须配合停用词表

在真实的文本分析任务里,这两者往往是配套使用的,缺一个效果都会打折。自定义词典解决的是“该合的词没合”的问题,停用词表解决的是“没用的词太多”的问题。

举个例子。评论里出现“不制冷”三个字,如果词库里没有整体词条,jieba会切成“不/制冷”,然后“不”又会因为不在自定义词典里而被保留。如果这时候停用词表里没有“不”,词频统计里“不”就会成为一个高频词,但它恰恰是判断用户负面反馈的关键修饰语,丢掉会损失语义,保留又会污染统计。

我的做法是,把“不制冷”“不流畅”“不耐用”这类业务强相关的否定词整体加入自定义词典,同时确保“不”这个单字不在停用词表的关键位置被误删。这样既保证了业务词的整体性,又避免了被通用规则误伤。

5.2 停用词表的分层维护策略

维护停用词表不是一次性工作,它需要跟着语料迭代。我的迭代策略是把停用词表分成基础层和业务层两份文件。

基础层存通用虚词,基本不需要频繁改动。业务层存与特定项目相关的噪音词,每个项目独立维护。代码里加载时把两层合并:

import os def load_stopwords_from_dir(dir_path): stopwords = set() for fname in os.listdir(dir_path): if fname.endswith(".txt"): with open(os.path.join(dir_path, fname), encoding="utf-8") as f: stopwords.update(line.strip() for line in f if line.strip()) return stopwords

这样有个好处:换了新项目只需要改业务层,基础层所有项目共用,不会互相污染。踩过这种坑的人自然明白,一份词表在不同项目里反复手工增删,迟早会出乱子。

5.3 词频迭代法:三分钟做出一份定制词表

如果你一时找不到合适的业务停用词,最快的办法是词频迭代法。

第一步,先用一个基础停用词表跑一遍全量分词,把词频Top 50列出来。第二步,人工扫一遍这50个词,把明显无分析价值的词挑出来,比如研究评论时“觉得”“感觉”“可以”“还是”这类词,加进业务停用词表。第三步,重新跑一遍分词,观察新结果中的Top词是否有明显偏移。通常迭代两三轮就能得到一份非常贴合当前语料的词表。

这个办法比直接网上找词表靠谱得多,因为每个业务领域的高频噪音词都不同。电商评论里的“快递”“物流”是高频词,但如果你分析的对象是餐饮评论,这两个词根本不该出现在停用词表里。

6. 常见问题和避坑建议

6.1 jieba分词结果不符合预期

最常见的情况是专有名词被切开,比如人名“张三丰”被切成“张三/丰”。原因很简单,这个词不在jieba词典里。解决办法有两个方向:一是用add_word添加这个词;二是如果领域专业词多,统一写进自定义词典文件。

第二个常见情况是分词结果过碎。比如“大数据分析”可能被切成“大/数据/分析”。这通常是因为“大数据分析”在词典里的整体频次不够高。解决办法同样是加入自定义词典,并给出足够的词频数值。

6.2 停用词过滤后重要信息被误删

这是比较隐蔽的坑。有些词在大多数场景是噪音,但在特定场景里承载重要信息。比如“没有”这个词,在评论“没有售后”里,如果把它当作停用词删掉,就丢了关键信息。解决办法是对业务词汇表做交集检查,把那些在停用词表和自定义词典里都出现的词挑出来,逐个人工确认。我吃过这个亏,后来写了个脚本自动对比两份词表,把重复的词打印出来,人工筛一遍,彻底杜绝了这类问题。

6.3 性能问题:分词太慢怎么办

jiba分词本身是纯Python实现,瓶颈主要在处理速度上。如果你面对的是百万级文本,逐条调用jieba.lcut会非常慢。我的优化方案是先做批量切分,再考虑并行。Python多线程受GIL限制,对CPU密集型的分词任务帮助有限,这时候推荐使用多进程。可以用multiprocessing池把文本列表分块,每个进程负责一部分。

一个更保守但有效的优化是减少不必要的重复加载。把自定义词典和停用词表放在模块导入时加载一次,不要在每个处理函数里重复读文件。很多人在性能排查时忽略了这个点,实际影响往往比分词算法本身还大。

6.4 字符编码引发的血泪教训

读文件编码问题,几乎每个人都会遇到。最典型的症状是中文分词结果变成乱码,或者读取停用词表时报UnicodeDecodeError。解决办法是在打开文件时显式指定编码,不要依赖系统默认:

with open("stopwords.txt", encoding="utf-8") as f: ...

尤其是Windows环境下,默认编码可能是gbk,不指定编码大概率会翻车。我的习惯是所有文本类文件统一用UTF-8,并且读文件时永远写上encoding="utf-8"。

6.5 词频统计中的“一”和长尾低频词

“一”这个字很特别,它既是数词又有实际含义,在不同语境里角色完全不同。“一个”“一天”里的“一”没分析价值,但“第一名”里的“一”有。我通常会把单字词都过滤掉,这样“一”这种词自然就没了,代价是会漏掉极少数有意义的单字领域词。如果你的业务里确实需要统计单字,可以对这部分单独处理,不要在通用停用词表里动刀。

长尾低频词是另一个容易踩的坑。词频统计结果里,百分之八十的词可能只出现一次,这些词对整体洞察没有太大贡献,反而会让结果列表变得又臭又长。我在输出分析结果时一般只保留词频前20~50的词汇,低词频部分直接忽略,分析报告的可读性会明显提升。

7. 从词频到洞察:后续还能怎么玩

分词和停用词过滤只是文本分析的入口,做完这一步,你会发现后续能做的事情突然变多了。

一个非常自然的扩展是向量化。把过滤后的词拼接成干净的文本,直接交给TF-IDF向量器或者Word2Vec训练词向量。停用词表在这里的作用尤为关键,因为训练词向量时噪音词会拉低向量的质量,过滤干净等于给模型减负。

另一个方向是词云展示。把过滤后的词作为词云输入,生成的可视化图表会直观展示用户讨论的热点。前期做过一次词云,因为没过滤停用词,出来的图里“我们”“他们”巨大无比,业务方看完一脸困惑。后来加上过滤逻辑,展示效果立刻专业了很多。

还可以把分词结果接入情感分析。情感模型通常以词序列作为输入,过滤掉“的”“了”这类纯语法功能词后,情感分类器的输入特征质量会明显提升。

而且这套流程完全可以用在非Python项目里。比如你在写数据分析报告时用Excel做了一版处理,回头看手工清洗的颗粒度远远达不到jieba加停用词表的效果。把Python脚本写好后,复用成本几乎为零,换一份语料改个路径就能跑。

我个人在实际操作中的体会是,分词和停用词这件事,看起来只是文本分析的第一步,但它决定了后续所有环节的下限。停用词表一开始可以先用开源现成的,但一定要留出迭代的空间,结合自己的数据不断修改,把业务里的高频噪音词收进去,把重要词捞出来。你在最开始多花十分钟维护词表,后面能省掉几个小时的人工校对时间。最后再分享一个小技巧:每次跑完分词统计之后,把词频结果保存成带时间戳的文件,连续收集几次,就能清晰地看到不同时段用户关注点的变化趋势,这对产品迭代决策和运营精细化管理都很有实际价值。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询