一、前言:从“我爱自然语言处理”说起

在学习 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 jieba

2. 最小示例(10 行搞定分词)

import jieba

if __name__ == "__main__":

text = "我爱自然语言处理,也喜欢用Python做文本挖掘。"

words = jieba.lcut(text) # 默认为精确模式

print(words)

运行后你会看到类似输出:

['我', '爱', '自然语言', '处理', ',', '也', '喜欢', '用', 'Python', '做', '文本', '挖掘', '。']

这就是你第一个中文分词程序 🎉(虽然你不让我用 emoji,我口头庆祝一下)。


四、三种分词模式:精确、全模式、搜索引擎模式详解

我们用统一的例子来说明差异:

import jieba

text = "小明硕士毕业于中国科学院计算所,后来在日本京都大学深造。"

1. 精确模式(最常用)

words = jieba.lcut(text, cut_all=False)

print("精确模式:", "/".join(words))

可能结果:

精确模式: 小明/硕士/毕业/于/中国科学院/计算所/,/后来/在/日本京都大学/深造/。

特点:

  • 对每一处歧义尽量给出最合理的切分
  • 适合:文本分析、分类、聚类、主题建模、特征提取
2. 全模式(适合做索引)

words_full = jieba.lcut(text, cut_all=True)

print("全模式:", "/".join(words_full))

可能结果:

全模式: 小明/硕士/毕业/于/中国/中国科学院/科学/学院/科学院/计算/计算所/,/后来/在/日本/日本京都大学/京都/京都大学/大学/深造/。

特点:

  • 把所有可能成为“词”的片段都切出来
  • 好处:召回率高,检索时更不容易漏掉匹配
  • 坏处:冗余较多,需要后续算法进一步筛选
3. 搜索引擎模式(精确 + 细粒度)

words_search = jieba.lcut_for_search(text)

print("搜索引擎模式:", "/".join(words_search))

输出类似:

搜索引擎模式: 小明/硕士/毕业/于/中国/中国科学院/科学院/计算/计算所/,/后来/在/日本/日本京都大学/京都/京都大学/大学/深造/。

理解:

  • 在精确模式基础上,对长词再做细切分
  • 比如 "中国科学院" 会被切成 "中国" / "科学院",这样搜索“中国”或“科学院”都能命中
  • 非常适合在构建倒排索引时使用

五、工程实战(一):从文本文件到分词结果

实际项目中,我们经常会有一堆 .txt 文件,想批量分词。下面我们写一个可直接使用的小脚本。

1. 单文件分词脚本

import jieba

from pathlib import Path

def cut_file(input_path, output_path, mode="accurate"):

"""

对单个文本文件进行分词,并将结果写入新文件。

- mode: accurate / full / search

"""

input_path = Path(input_path)

output_path = Path(output_path)

if not input_path.exists():

raise FileNotFoundError(f"输入文件不存在:{input_path}")

text = input_path.read_text(encoding="utf-8", errors="ignore")

if mode == "accurate":

words = jieba.lcut(text)

elif mode == "full":

words = jieba.lcut(text, cut_all=True)

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, encoding="utf-8")

print(f"[OK] 分词完成:{input_path} -> {output_path}(模式:{mode})")

if __name__ == "__main__":

cut_file("input.txt", "input_cut.txt", mode="accurate")

使用方式:

  1. 把你要分词的文本保存为 input.txt

  2. 把脚本保存为 cut_text.py

  3. 终端执行:

    python cut_text.py

  4. 在同目录下会生成 input_cut.txt,其中就是用空格分隔的分词结果。

2. 批量处理目录下的所有 .txt 文件

import jieba

from pathlib import Path

def batch_cut(input_dir, output_dir, mode="accurate"):

input_dir = Path(input_dir)

output_dir = Path(output_dir)

output_dir.mkdir(parents=True, exist_ok=True)

for txt_file in input_dir.glob("*.txt"):

output_file = output_dir / f"{txt_file.stem}_cut.txt"

text = txt_file.read_text(encoding="utf-8", errors="ignore")

if mode == "accurate":

words = jieba.lcut(text)

elif mode == "full":

words = jieba.lcut(text, cut_all=True)

elif mode == "search":

words = jieba.lcut_for_search(text)

else:

raise ValueError("mode must be: 'accurate' | 'full' | 'search'")

output_file.write_text(" ".join(words), encoding="utf-8")

print(f"[OK] {txt_file.name} -> {output_file.name}")

if __name__ == "__main__":

batch_cut("raw_texts", "cut_texts", mode="accurate")

  • raw_texts:原始文本目录
  • cut_texts:分词后保存的目录

这个脚本经常可以直接用在文本预处理阶段,非常实用。


六、工程实战(二):自定义词典与新词识别

1. 动态添加词语(适合小项目)

import jieba

# 动态增加几个词

jieba.add_word("知识蒸馏", freq=10, tag="n")

jieba.add_word("大模型", freq=20, tag="n")

jieba.add_word("自然语言处理", freq=30, tag="n")

text = "我最近在研究自然语言处理和大模型相关的知识蒸馏技术。"

print("默认分词:", "/".join(jieba.lcut(text)))

你可以试试有无 add_word 的效果对比,直观感受差别。

2. 外部用户词典(更推荐的方式)

创建 user_dict.txt

自然语言处理 50 n

大模型 40 n

知识蒸馏 30 n

知识图谱 30 n

文本挖掘 20 n

代码中加载:

import jieba

jieba.load_userdict("user_dict.txt")

text = "自然语言处理和大模型是当前人工智能中非常热门的方向,例如知识图谱和知识蒸馏等技术都依赖大量文本数据。"

print("/".join(jieba.lcut(text)))

你会发现像 "自然语言处理""大模型""知识图谱""知识蒸馏" 等词都被正确识别了。

3. 新词发现(简单示意)

jieba 内部用到了 HMM 对一些新词进行识别,你可以通过观察词频统计和左右熵进一步做新词挖掘,不过这已经超出基础教程范畴,这里只给一个简单的统计脚本示例,帮助你从语料中找高频词。

import jieba

from collections import Counter

from pathlib import Path

def find_top_words(path, top_k=50):

text = Path(path).read_text(encoding="utf-8", errors="ignore")

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_k=100)

把高频词人工筛一遍,就能发现不少需要加入词典的领域专有词。


七、工程实战(三):停用词、词频统计与可视化

做 NLP 时,如果你直接使用所有分词结果,会遇到一个问题:
“的、了、是、在、和、一个、我们、你们……” 这些功能词频率特别高,但几乎没什么语义贡献。

因此我们常常需要一个停用词表。

1. 准备停用词表

网上有很多开源的停用词表,你可以搜 中文停用词表,下载一个 stopwords.txt,大致形式如下:

一个

我们

你们

他们

……

2. 分词 + 去停用词 + 词频统计

import jieba

from collections import Counter

from pathlib import Path

def load_stopwords(path):

stopwords = set()

with open(path, "r", encoding="utf-8") as f:

for line in f:

w = line.strip()

if not w:

continue

stopwords.add(w)

return stopwords

def word_frequency(text_path, stopwords_path=None, top_k=50):

text = Path(text_path).read_text(encoding="utf-8", errors="ignore")

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_path="stopwords.txt", top_k=50)

这样你就可以快速看到文本中真正重要的词。

3. 可视化:简单词云图(可选)

如果你愿意用一个第三方库 wordcloud,还可以把词频显示成词云图。

pip install wordcloud matplotlib

import jieba

from wordcloud import WordCloud

import matplotlib.pyplot as plt

from pathlib import Path

def generate_wordcloud(text_path, font_path, output="wordcloud.png"):

text = Path(text_path).read_text(encoding="utf-8", errors="ignore")

words = jieba.lcut(text)

content = " ".join(words)

wc = WordCloud(

font_path=font_path, # 例如 C:\Windows\Fonts\simhei.ttf

width=800,

height=600,

background_color="white",

max_words=200

)

wc.generate(content)

wc.to_file(output)

plt.imshow(wc, interpolation="bilinear")

plt.axis("off")

plt.show()

if __name__ == "__main__":

generate_wordcloud("large_corpus.txt", font_path=r"C:\Windows\Fonts\simhei.ttf")

这在写博客、做 PPT 时非常有视觉冲击力。


八、关键词提取:TF-IDF 与 TextRank 在 jieba 中的用法

jieba 内置了两种关键词提取算法:

  • TF-IDF:基于词频和逆文档频率
  • TextRank:基于图排序,类似 PageRank
1. TF-IDF 关键词提取

import jieba.analyse

text = """

自然语言处理(NLP)是人工智能和语言学领域的一个重要分支。

它研究如何处理和理解由人类使用的自然语言。

近年来,随着大模型和深度学习的发展,NLP 在搜索、对话系统、机器翻译等领域得到了广泛应用。

# 提取前 10 个关键词

keywords = jieba.analyse.extract_tags(text, topK=10, withWeight=True, allowPOS=())

print("TF-IDF 关键词:")

for word, weight in keywords:

print(f"{word}\t{weight:.4f}")

  • topK:返回前 K 个关键词
  • withWeight:是否返回权重
  • allowPOS:允许的词性,不填就不过滤
2. TextRank 关键词提取

import jieba.analyse

keywords = jieba.analyse.textrank(text, topK=10, withWeight=True, allowPOS=('ns', 'n', 'vn', 'v'))

print("TextRank 关键词:")

for word, weight in keywords:

print(f"{word}\t{weight:.4f}")

  • TextRank 更依赖词之间的共现关系,对长文更友好
  • allowPOS 常用于过滤,只保留名词、动词等

你可以把这两种方法的结果放在一起对比,感受差异。


九、微型搜索引擎:从分词到简单“搜索结果排序”

在前面的小例子里,我们只是用“出现次数”的简单和来打分。下面我们稍微升级一下评分方式,引入一个简化的 TF-IDF 思路。

1. 准备文档

import jieba

from collections import Counter, defaultdict

import math

docs = [

"我爱自然语言处理和文本挖掘。",

"Python 是一门非常适合做数据分析的语言。",

"最近大模型在 NLP 领域非常火。",

"很多公司开始招聘有自然语言处理经验的工程师。",

"搜索引擎会用到分词、倒排索引和相关性排序。",

]

# 对每篇文档分词

cut_docs = [jieba.lcut(doc) for doc in docs]

2. 计算 IDF(逆文档频率)

def compute_idf(cut_docs):

根据分词后的文档列表计算每个词的 IDF

N = len(cut_docs)

df = defaultdict(int)

for words in cut_docs:

unique_words = set(words)

for w in unique_words:

df[w] += 1

idf = {}

for w, df_w in df.items():

idf[w] = math.log(N / (1 + df_w)) + 1 # +1 防止除零

return idf

idf_dict = compute_idf(cut_docs)

3. 用简化版 TF-IDF 打分

def search(query, top_k=3):

query_words = jieba.lcut(query)

scores = []

for idx, words in enumerate(cut_docs):

tf = Counter(words)

score = 0.0

for qw in query_words:

score += tf[qw] * idf_dict.get(qw, 0.0)

scores.append((score, idx))

scores.sort(reverse=True)

results = []

for score, idx in scores[:top_k]:

if score <= 0:

continue

results.append((score, docs[idx]))

return results

if __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 pseg

text = "小明硕士毕业于中国科学院计算所。"

words = pseg.cut(text)

for w, flag in words:

print(w, flag)

你会看到类似输出:

小明 nr

硕士 n

毕业 v

于 p

中国科学院 nt

计算所 n

。 x

  • nr:人名
  • n:名词
  • v:动词
  • p:介词
  • nt:机构团体名
  • x:其它符号

词性标注在很多任务中很有用,比如:

  • 抽取名词短语作为候选关键词
  • 过滤掉大量虚词,只保留名词、动词做特征
  • 做**实体识别(NER)**的前置特征

十一、实践中的常见坑与经验总结

1. 编码问题
  • 统一使用 utf-8 编码是最省心的方案
  • 读文件时:encoding="utf-8", errors="ignore" 可以避免程序直接崩溃
  • Windows 路径要注意 \ 和转义问题,建议用 r"C:\path\to\file" 或 Path 对象
2. 性能与内存
  • 对大文本(比如几百 MB)做分词时,不要一次性读入内存,可以按行/按块处理
  • 多次调用分词时,不要在循环里频繁 jieba.initialize(),直接在顶部导入一次,在整个进程中复用即可
  • 若需要并行处理,可以使用 multiprocessing,每个进程独立加载 jieba
3. 分词粒度控制
  • 如果你感觉“词太细了”,试试:
    • 使用精确模式而不是全模式
    • 适当增加停用词(过滤掉一些你不关心的短词)
  • 如果你感觉“词太粗了”,可以:
    • 使用 lcut_for_search 的搜索模式
    • 降低某些词在用户词典中的频次,或者干脆删除
4. 词典更新策略
  • 对固定领域项目(比如电商、医疗、金融),建议:
    • 先基于一定规模的语料做词频统计
    • 人工挑选高频新词加入用户词典
  • 对快速变化的文本(比如微博、公众号、新闻热点),可定期重新统计词频,迭代用户词典

十二、写在最后:从“用会 jieba”到“理解中文 NLP 的第一步”

通过这一篇文章,你应该已经掌握:

  • 概念层面

    • 为什么中文必须进行分词
    • 中文分词相对英文分词困难在哪里
    • 词典、统计、HMM、大模型在分词中的角色
  • 工具层面

    • 如何安装与快速使用 jieba
    • 精确模式 / 全模式 / 搜索模式 的适用场景
    • 如何对文件/目录进行批量分词
    • 如何使用用户词典和停用词表优化效果
    • 如何用 jieba 做关键词提取(TF-IDF / TextRank)
    • 如何做初级词频统计、绘制词云
    • 如何基于分词结果实现一个“迷你搜索功能”
  • 工程实践层面

    • 如何处理编码与性能问题
    • 如何利用统计信息不断迭代用户词典
    • 如何把分词结果用于后续的分类、聚类、推荐、搜索等任务

从实践的角度来说,会用好 jieba,基本就已经具备了处理中文文本数据的“入门资格”:
你可以把任何一段中文文本,变成可计算、可学习的结构化数据。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐