NLP 分词实战:用 Python 和 jieba 做中文分词(原理、实战与代码全解析)

发布时间:2026/5/28 2:14:09

NLP 分词实战:用 Python 和 jieba 做中文分词(原理、实战与代码全解析) 一、前言从“我爱自然语言处理”说起在学习 NLP 的过程中很多人一开始都会有一个困惑“英文文本分析好像挺简单直接用空格分词就行为什么中文要搞一个‘分词’这么麻烦的步骤”我们先看两句话英文I love natural language processing.中文我爱自然语言处理。在英文中天然就有空格I / love / natural / language / processing / .而在中文中没有显式的分隔符计算机看到的是我爱自然语言处理。如果不做分词后面的所有分析基本无法顺利进行。做文本分类不知道“自然语言处理”是一个整体很容易丢失关键信息做搜索引擎用户搜“自然语言处理”而你的文档里刚好是“自然语言处理和大模型”如果没有分词很难召回做推荐/标签提取关键词就无从谈起所以中文 NLP 的第 0 步几乎永远是——分词。二、中文分词的核心挑战与常见方法1. 为什么中文分词比你想象的难中文分词有两个核心难点词边界不明显“研究生命起源”到底是研究 / 生命 / 起源还是研究生 / 命 / 起源机器需要根据语境、词典、统计信息等综合判断。新词层出不穷互联网热词、行业术语、公司产品名……一大堆在传统词典中都没有。比如大模型、知识蒸馏、对话机器人、知识图谱等这些词出现之前老词典根本不认识。2. 常见的中文分词思路简要了解一下在工业界常见分词方法大致有几类这里不展开算法细节只做概念级介绍基于规则和词典维护一个大词典从左到右/从右到左扫描进行最大匹配。优点简单直观速度快。缺点完全依赖词典新词识别差。基于统计的模型利用大规模语料统计“某个切分方式”出现的概率选最可能的一种。典型方法HMM、CRF、双向 LSTM 等序列标注模型。基于深度学习/预训练模型把分词看成序列标注或者序列到序列问题结合 BERT、GPT 等大模型来做。效果好但训练、部署成本较高一般用于大型系统。jieba 的实现是一个**“词典 统计 HMM”混合方案**既能利用词典的效率又能通过统计和 HMM 做一定程度的新词识别对大多数应用场景来说已经足够好用。三、jieba 快速上手安装与最小可运行示例1. 安装pip install jieba如果网络有问题可以加镜像源例如以清华为例pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jieba2. 最小示例10 行搞定分词import jiebaif __name__ __main__:text 我爱自然语言处理也喜欢用Python做文本挖掘。words jieba.lcut(text) # 默认为精确模式print(words)运行后你会看到类似输出[我, 爱, 自然语言, 处理, , 也, 喜欢, 用, Python, 做, 文本, 挖掘, 。]这就是你第一个中文分词程序 虽然你不让我用 emoji我口头庆祝一下。四、三种分词模式精确、全模式、搜索引擎模式详解我们用统一的例子来说明差异import jiebatext 小明硕士毕业于中国科学院计算所后来在日本京都大学深造。1. 精确模式最常用words jieba.lcut(text, cut_allFalse)print(精确模式, /.join(words))可能结果精确模式 小明/硕士/毕业/于/中国科学院/计算所//后来/在/日本京都大学/深造/。特点对每一处歧义尽量给出最合理的切分适合文本分析、分类、聚类、主题建模、特征提取2. 全模式适合做索引words_full jieba.lcut(text, cut_allTrue)print(全模式, /.join(words_full))可能结果全模式 小明/硕士/毕业/于/中国/中国科学院/科学/学院/科学院/计算/计算所//后来/在/日本/日本京都大学/京都/京都大学/大学/深造/。特点把所有可能成为“词”的片段都切出来好处召回率高检索时更不容易漏掉匹配坏处冗余较多需要后续算法进一步筛选3. 搜索引擎模式精确 细粒度words_search jieba.lcut_for_search(text)print(搜索引擎模式, /.join(words_search))输出类似搜索引擎模式 小明/硕士/毕业/于/中国/中国科学院/科学院/计算/计算所//后来/在/日本/日本京都大学/京都/京都大学/大学/深造/。理解在精确模式基础上对长词再做细切分比如中国科学院会被切成中国 / 科学院这样搜索“中国”或“科学院”都能命中非常适合在构建倒排索引时使用五、工程实战一从文本文件到分词结果实际项目中我们经常会有一堆.txt文件想批量分词。下面我们写一个可直接使用的小脚本。1. 单文件分词脚本import jiebafrom pathlib import Pathdef cut_file(input_path, output_path, modeaccurate):对单个文本文件进行分词并将结果写入新文件。- mode: accurate / full / searchinput_path Path(input_path)output_path Path(output_path)if not input_path.exists():raise FileNotFoundError(f输入文件不存在{input_path})text input_path.read_text(encodingutf-8, errorsignore)if mode accurate:words jieba.lcut(text)elif mode full:words jieba.lcut(text, cut_allTrue)elif mode search:words jieba.lcut_for_search(text)else:raise ValueError(mode must be: accurate | full | search)# 这里使用空格连接便于后续处理result .join(words)output_path.write_text(result, encodingutf-8)print(f[OK] 分词完成{input_path} - {output_path}模式{mode})if __name__ __main__:cut_file(input.txt, input_cut.txt, modeaccurate)使用方式把你要分词的文本保存为input.txt把脚本保存为cut_text.py终端执行python cut_text.py在同目录下会生成input_cut.txt其中就是用空格分隔的分词结果。2. 批量处理目录下的所有.txt文件import jiebafrom pathlib import Pathdef batch_cut(input_dir, output_dir, modeaccurate):input_dir Path(input_dir)output_dir Path(output_dir)output_dir.mkdir(parentsTrue, exist_okTrue)for txt_file in input_dir.glob(*.txt):output_file output_dir / f{txt_file.stem}_cut.txttext txt_file.read_text(encodingutf-8, errorsignore)if mode accurate:words jieba.lcut(text)elif mode full:words jieba.lcut(text, cut_allTrue)elif mode search:words jieba.lcut_for_search(text)else:raise ValueError(mode must be: accurate | full | search)output_file.write_text( .join(words), encodingutf-8)print(f[OK] {txt_file.name} - {output_file.name})if __name__ __main__:batch_cut(raw_texts, cut_texts, modeaccurate)raw_texts原始文本目录cut_texts分词后保存的目录这个脚本经常可以直接用在文本预处理阶段非常实用。六、工程实战二自定义词典与新词识别1. 动态添加词语适合小项目import jieba# 动态增加几个词jieba.add_word(知识蒸馏, freq10, tagn)jieba.add_word(大模型, freq20, tagn)jieba.add_word(自然语言处理, freq30, tagn)text 我最近在研究自然语言处理和大模型相关的知识蒸馏技术。print(默认分词, /.join(jieba.lcut(text)))你可以试试有无 add_word 的效果对比直观感受差别。2. 外部用户词典更推荐的方式创建user_dict.txt自然语言处理 50 n大模型 40 n知识蒸馏 30 n知识图谱 30 n文本挖掘 20 n代码中加载import jiebajieba.load_userdict(user_dict.txt)text 自然语言处理和大模型是当前人工智能中非常热门的方向例如知识图谱和知识蒸馏等技术都依赖大量文本数据。print(/.join(jieba.lcut(text)))你会发现像自然语言处理、大模型、知识图谱、知识蒸馏等词都被正确识别了。3. 新词发现简单示意jieba 内部用到了 HMM 对一些新词进行识别你可以通过观察词频统计和左右熵进一步做新词挖掘不过这已经超出基础教程范畴这里只给一个简单的统计脚本示例帮助你从语料中找高频词。import jiebafrom collections import Counterfrom pathlib import Pathdef find_top_words(path, top_k50):text Path(path).read_text(encodingutf-8, errorsignore)words jieba.lcut(text)counter Counter(words)# 简单过滤掉太短的“词”for w in list(counter):if len(w.strip()) 1:del counter[w]for word, freq in counter.most_common(top_k):print(word, freq)if __name__ __main__:find_top_words(large_corpus.txt, top_k100)把高频词人工筛一遍就能发现不少需要加入词典的领域专有词。七、工程实战三停用词、词频统计与可视化做 NLP 时如果你直接使用所有分词结果会遇到一个问题“的、了、是、在、和、一个、我们、你们……” 这些功能词频率特别高但几乎没什么语义贡献。因此我们常常需要一个停用词表。1. 准备停用词表网上有很多开源的停用词表你可以搜中文停用词表下载一个stopwords.txt大致形式如下的了在是和一个我们你们他们……2. 分词 去停用词 词频统计import jiebafrom collections import Counterfrom pathlib import Pathdef load_stopwords(path):stopwords set()with open(path, r, encodingutf-8) as f:for line in f:w line.strip()if not w:continuestopwords.add(w)return stopwordsdef word_frequency(text_path, stopwords_pathNone, top_k50):text Path(text_path).read_text(encodingutf-8, errorsignore)words jieba.lcut(text)if stopwords_path:stopwords load_stopwords(stopwords_path)words [w for w in words if w not in stopwords and w.strip()]counter Counter(words)for word, freq in counter.most_common(top_k):print(word, freq)if __name__ __main__:word_frequency(large_corpus.txt, stopwords_pathstopwords.txt, top_k50)这样你就可以快速看到文本中真正重要的词。3. 可视化简单词云图可选如果你愿意用一个第三方库wordcloud还可以把词频显示成词云图。pip install wordcloud matplotlibimport jiebafrom wordcloud import WordCloudimport matplotlib.pyplot as pltfrom pathlib import Pathdef generate_wordcloud(text_path, font_path, outputwordcloud.png):text Path(text_path).read_text(encodingutf-8, errorsignore)words jieba.lcut(text)content .join(words)wc WordCloud(font_pathfont_path, # 例如 C:\Windows\Fonts\simhei.ttfwidth800,height600,background_colorwhite,max_words200)wc.generate(content)wc.to_file(output)plt.imshow(wc, interpolationbilinear)plt.axis(off)plt.show()if __name__ __main__:generate_wordcloud(large_corpus.txt, font_pathrC:\Windows\Fonts\simhei.ttf)这在写博客、做 PPT 时非常有视觉冲击力。八、关键词提取TF-IDF 与 TextRank 在 jieba 中的用法jieba 内置了两种关键词提取算法TF-IDF基于词频和逆文档频率TextRank基于图排序类似 PageRank1. TF-IDF 关键词提取import jieba.analysetext 自然语言处理NLP是人工智能和语言学领域的一个重要分支。它研究如何处理和理解由人类使用的自然语言。近年来随着大模型和深度学习的发展NLP 在搜索、对话系统、机器翻译等领域得到了广泛应用。# 提取前 10 个关键词keywords jieba.analyse.extract_tags(text, topK10, withWeightTrue, allowPOS())print(TF-IDF 关键词)for word, weight in keywords:print(f{word}\t{weight:.4f})topK返回前 K 个关键词withWeight是否返回权重allowPOS允许的词性不填就不过滤2. TextRank 关键词提取import jieba.analysekeywords jieba.analyse.textrank(text, topK10, withWeightTrue, allowPOS(ns, n, vn, v))print(TextRank 关键词)for word, weight in keywords:print(f{word}\t{weight:.4f})TextRank 更依赖词之间的共现关系对长文更友好allowPOS常用于过滤只保留名词、动词等你可以把这两种方法的结果放在一起对比感受差异。九、微型搜索引擎从分词到简单“搜索结果排序”在前面的小例子里我们只是用“出现次数”的简单和来打分。下面我们稍微升级一下评分方式引入一个简化的 TF-IDF 思路。1. 准备文档import jiebafrom collections import Counter, defaultdictimport mathdocs [我爱自然语言处理和文本挖掘。,Python 是一门非常适合做数据分析的语言。,最近大模型在 NLP 领域非常火。,很多公司开始招聘有自然语言处理经验的工程师。,搜索引擎会用到分词、倒排索引和相关性排序。,]# 对每篇文档分词cut_docs [jieba.lcut(doc) for doc in docs]2. 计算 IDF逆文档频率def compute_idf(cut_docs):根据分词后的文档列表计算每个词的 IDFN len(cut_docs)df defaultdict(int)for words in cut_docs:unique_words set(words)for w in unique_words:df[w] 1idf {}for w, df_w in df.items():idf[w] math.log(N / (1 df_w)) 1 # 1 防止除零return idfidf_dict compute_idf(cut_docs)3. 用简化版 TF-IDF 打分def search(query, top_k3):query_words jieba.lcut(query)scores []for idx, words in enumerate(cut_docs):tf Counter(words)score 0.0for qw in query_words:score tf[qw] * idf_dict.get(qw, 0.0)scores.append((score, idx))scores.sort(reverseTrue)results []for score, idx in scores[:top_k]:if score 0:continueresults.append((score, docs[idx]))return resultsif __name__ __main__:q 自然语言处理for s, d in search(q):print(f得分: {s:.4f}\t文档: {d})虽然这个“搜索引擎”非常简化但完整体现了一个典型流程分词 → 统计 TF → 计算 IDF → 计算 TF-IDF → 排序这是很多经典信息检索课程中最核心的一套思路。十、jieba 词性标注POS Tagging简介分词之后我们可以进一步对每个词打上词性标记例如名词、动词、形容词等。jieba 提供了posseg模块来完成这件事。import jieba.posseg as psegtext 小明硕士毕业于中国科学院计算所。words pseg.cut(text)for w, flag in words:print(w, flag)你会看到类似输出小明 nr硕士 n毕业 v于 p中国科学院 nt计算所 n。 xnr人名n名词v动词p介词nt机构团体名x其它符号词性标注在很多任务中很有用比如抽取名词短语作为候选关键词过滤掉大量虚词只保留名词、动词做特征做**实体识别NER**的前置特征十一、实践中的常见坑与经验总结1. 编码问题统一使用utf-8编码是最省心的方案读文件时encodingutf-8, errorsignore可以避免程序直接崩溃Windows 路径要注意\和转义问题建议用rC:\path\to\file或Path对象2. 性能与内存对大文本比如几百 MB做分词时不要一次性读入内存可以按行/按块处理多次调用分词时不要在循环里频繁jieba.initialize()直接在顶部导入一次在整个进程中复用即可若需要并行处理可以使用multiprocessing每个进程独立加载 jieba3. 分词粒度控制如果你感觉“词太细了”试试使用精确模式而不是全模式适当增加停用词过滤掉一些你不关心的短词如果你感觉“词太粗了”可以使用lcut_for_search的搜索模式降低某些词在用户词典中的频次或者干脆删除4. 词典更新策略对固定领域项目比如电商、医疗、金融建议先基于一定规模的语料做词频统计人工挑选高频新词加入用户词典对快速变化的文本比如微博、公众号、新闻热点可定期重新统计词频迭代用户词典十二、写在最后从“用会 jieba”到“理解中文 NLP 的第一步”通过这一篇文章你应该已经掌握概念层面为什么中文必须进行分词中文分词相对英文分词困难在哪里词典、统计、HMM、大模型在分词中的角色工具层面如何安装与快速使用 jieba精确模式 / 全模式 / 搜索模式 的适用场景如何对文件/目录进行批量分词如何使用用户词典和停用词表优化效果如何用 jieba 做关键词提取TF-IDF / TextRank如何做初级词频统计、绘制词云如何基于分词结果实现一个“迷你搜索功能”工程实践层面如何处理编码与性能问题如何利用统计信息不断迭代用户词典如何把分词结果用于后续的分类、聚类、推荐、搜索等任务从实践的角度来说会用好 jieba基本就已经具备了处理中文文本数据的“入门资格”你可以把任何一段中文文本变成可计算、可学习的结构化数据。

相关新闻