中文分词工具全景:从 jieba 到 LTP 的选型与对比

📌 关键要点

中文没有天然的空格分隔词语,分词是中文 NLP 的基础第一步。


为什么中文需要分词?

英文有天然的空格分隔单词:

英文:I like eating apples
      → 天然分词:["I", "like", "eating", "apples"]

中文:我喜欢吃苹果
      → 没有空格!需要工具来切分

中文分词的结果取决于粒度:

"我喜欢吃苹果"

粗粒度(词级):  ["我", "喜欢", "吃", "苹果"]
细粒度(字级):  ["我", "喜", "欢", "吃", "苹", "果"]

BERT 的 WordPiece 分词器 → 细粒度(字级)
传统分词工具(jieba/LTP)→ 粗粒度(词级)

中文分词 vs WordPiece:两种不同的"分词"

维度 中文分词(jieba/LTP) WordPiece(BERT 分词器)
切分粒度 词级("苹果"是一个词) 字级("苹""果"各是一个 token)
目的 理解文本结构 把文本转成模型能处理的 token 序列
输出 词语列表 token ID 序列
是否需要训练 部分工具需要(pkuseg) 已预训练好
典型用途 WWM 全词遮盖、文本分析 模型输入预处理

关键区别:WordPiece 不知道"苹果"是一个词,它只知道"苹"和"果"各是一个 token。而 WWM 需要知道词边界,所以必须借助传统分词工具。


五大主流中文分词工具

1. jieba(结巴分词)

属性 内容
开发者 fxjwind(社区维护)
算法 基于前缀词典 + 动态规划(HMM 用于新词发现)
模式 精确模式 / 全模式 / 搜索引擎模式
安装 pip install jieba
体积 约 50MB(含词典)
速度 快(约 1.5MB/s)
精度 中等
import jieba

text = "我喜欢吃苹果"
result = jieba.lcut(text)
print(result)  # ['我', '喜欢', '吃', '苹果']

# 三种模式
jieba.cut(text, cut_all=False)   # 精确模式(默认)
jieba.cut(text, cut_all=True)    # 全模式(所有可能的词)
jieba.cut_for_search(text)       # 搜索引擎模式(细粒度)

优点:安装简单、速度快、社区活跃、文档丰富 缺点:精度一般、不支持自定义领域模型、新词识别能力弱

jieba 分词算法详解

jieba 采用两套算法配合的方式:

第一套:前缀词典 + 动态规划 → 处理已知词(词典里有的词)
第二套:HMM 隐马尔可夫模型 → 处理新词(词典里没有的词)

第一套:前缀词典 + 动态规划

jieba 内置词典 dict.txt,每行格式为:词语<TAB>词频<TAB>词性

# 词典文件位置(以 CondaBYP 环境为例)
D:/B/software/anaconda/envs/CondaBYP/Lib/site-packages/jieba/dict.txt

# 词典规模:349,046 行(约 35 万个词)

# 词典内容示例:
我       328841  r      ← 词频最高,常用代词
吃       36799   v      ← 动词
喜欢     9783    v      ← 动词
苹果     1334    n      ← 名词
南京市   2046    ns     ← 地名
长江大桥 3858    ns     ← 地名
研究     35029   vn     ← 名动词
生命     6986    vn     ← 名动词

分词时,对一句话找出所有可能的切分方式,用动态规划选出词频乘积最大的路径:

"南京市长江大桥"

所有可能的切法:
  切法1: 南京 / 市长 / 长江 / 大桥    → 4个词
  切法2: 南京市 / 长江大桥            → 2个词,词频乘积更大
  切法3: 南 / 京市 / 长江 / 大桥      → ...

动态规划选出最优路径:南京市(2046) × 长江大桥(3858) → 概率最大

第二套:HMM 隐马尔可夫模型

用于识别词典里没有的新词。HMM 给每个字标注 4 种状态之一:

B = Begin(词开头)
M = Middle(词中间)
E = End(词结尾)
S = Single(单字词)

例:"海启星公司"
  词典里没有"海启星",但 HMM 标注:
  海(B) 启(M) 星(E) → 识别为一个新的三字词
  公(B) 司(E)       → 词典里的已知词

HMM 通过大量已分词文本训练,学会了哪些字经常组合成词。

jieba 两套算法的分工比例

jieba ≈ 90% 查词典 + 10% HMM 猜新词

查词典(主力):
  → 速度快、结果稳定
  → 处理日常文本中 90% 以上的字

HMM(补充):
  → 处理词典里没有的新词
  → 人名、地名、新造词等

大部分日常文本都是靠查词典完成的。HMM 只在词典搞不定时才介入。

jieba 词典扩充方法

如果觉得 jieba 的默认词典不够用,有三种方式扩充:

方法 1:运行时添加(临时)

import jieba

# 添加单个词
jieba.add_word("海启星")
jieba.add_word("多源数据处理平台")

# 删除词
jieba.del_word("海启星")

# 注意:程序退出后就失效了

方法 2:加载自定义词典文件(推荐)

import jieba

# 准备一个自定义词典文件 user_dict.txt
# 格式:每行一个词(可选加词频和词性)
# 海启星
# 多源数据处理平台 100 n
# 广东海启星 50 nt

jieba.load_userdict("user_dict.txt")

方法 3:直接修改 dict.txt(不推荐)

# 直接编辑 jieba 安装目录下的 dict.txt
# D:/B/software/anaconda/envs/CondaBYP/Lib/site-packages/jieba/dict.txt

# ⚠️ 不推荐的原因:
# 1. pip 更新 jieba 时会被覆盖
# 2. 直接修改第三方库文件不优雅
# 3. 不同环境需要重复修改
方法 持久性 推荐度 适用场景
add_word() 临时(程序运行期间) ★★★ 快速测试
load_userdict() 持久(文件形式) ★★★★★ 生产环境
修改 dict.txt 持久(但不优雅) ★ 不推荐

jieba 实测结果

以下是对不同场景的实测结果(jieba 4.x 版本):

场景 输入 分词结果 评价
基础句 我喜欢吃苹果 ['我', '喜欢', '吃', '苹果'] ✅ 完美
歧义句1 南京市长江大桥 ['南京市', '长江大桥'] ✅ 正确
歧义句2 研究生命的起源 ['研究', '生命', '的', '起源'] ✅ 正确
歧义句3 乒乓球拍卖完了 ['乒乓球', '拍卖', '完', '了'] ✅ 正确
专业术语 BERT模型使用Masked Language Model ['BERT', '模型', '使用', 'Masked', ' ', 'Language', ' ', 'Model', ...] ⚠️ 中英文混合可处理
新词 海启星公司 ['海启星', '公司', ...] ✅ HMM 识别出新词
繁体简单 我喜歡吃蘋果 ['我', '喜歡', '吃', '蘋果'] ✅ 可以
繁体复杂 語言技術平臺 ['語言', '技術平', '臺'] ❌ 切错了
文言文 学而时习之不亦说乎 ['学而', '时习', '之', '不', '亦', '说乎'] ❌ 基本不行

结论:jieba 对现代汉语(简体)表现良好,经典歧义句全部正确;繁体简单句可以,复杂词会出错;文言文无法处理。对中文维基百科语料的 WWM 实验完全够用。


2. pkuseg(北大分词)

属性 内容
开发者 北京大学自然语言处理实验室
算法 基于 BiLSTM-CRF(序列标注模型)
特色 支持多领域模型(新闻、网页、医药等)
安装 pip install pkuseg
体积 约 200MB(含预训练模型)
速度 中等(比 jieba 慢)
精度 高
import pkuseg

# 使用默认模型(新闻领域)
seg = pkuseg.pkuseg()
result = seg.cut("我喜欢吃苹果")
print(result)  # ['我', '喜欢', '吃', '苹果']

# 使用特定领域模型
seg_web = pkuseg.pkuseg(model_name="web")    # 网页领域
seg_med = pkuseg.pkuseg(model_name="medicine")  # 医药领域

优点:精度高、支持领域自适应、可训练自定义模型 缺点:速度较慢、体积较大、需要较多依赖

pkuseg 分词算法详解

pkuseg 采用 BiLSTM-CRF 序列标注模型(深度学习):

输入:"我喜欢吃苹果"

Step 1: 字符嵌入(Embedding)
  每个字 → 一个向量(如"我" → [0.23, -0.15, 0.87, ...])

Step 2: BiLSTM 提取上下文特征
  正向 LSTM:从左到右读 → 捕捉"前面的字"
  反向 LSTM:从右到左读 → 捕捉"后面的字"
  双向拼接 → 每个字同时看到前后文

Step 3: CRF 层输出标签序列
  CRF 保证标签序列合法(如 B 后面不能跟 E)
  输出:我(S) 喜欢(B-E) 吃(S) 苹果(B-E)

Step 4: 根据标签切词
  S=单字词, B=词首, M=词中, E=词尾
  → ['我', '喜欢', '吃', '苹果']

pkuseg 的独特之处是多领域模型:针对不同领域(新闻/网页/医药)训练不同的模型,因为不同领域的用词习惯不同。


3. LTP(语言技术平台)

属性 内容
开发者 哈尔滨工业大学 SCIR(社会计算与信息检索研究中心)
算法 基于深度学习(BiLSTM-CRF / Transformer)
特色 功能全面:分词 + 词性标注 + 命名实体识别 + 依存句法分析
安装 pip install ltp
体积 约 1GB+(含预训练模型)
速度 较慢
精度 高
from ltp import LTP

ltp = LTP("LTP/small")  # 加载小模型

# 分词
output = ltp.pipeline(["我喜欢吃苹果"], tasks=["cws"])
print(output.cws)  # [['我', '喜欢', '吃', '苹果']]

# 同时做分词 + 词性标注 + 命名实体识别
output = ltp.pipeline(["我喜欢吃苹果"], tasks=["cws", "pos", "ner"])
print(output.cws)  # [['我', '喜欢', '吃', '苹果']]
print(output.pos)  # [['r', 'v', 'v', 'n']]  (代词/动词/动词/名词)

优点:功能全面、精度高、哈工大出品(与 WWM 论文一致) 缺点:体积大、依赖多、速度较慢、学习曲线陡

📌 与哈工大论文的关系:哈工大讯飞联合实验室的 WWM 论文(arXiv:1906.08101)使用的就是 LTP 做中文分词,以识别词边界供全词遮盖使用。

LTP 分词算法详解

LTP 采用深度学习全栈管线,分词只是其中一环:

LTP 的处理流程(以分词为例):

输入:"我喜欢吃苹果"

Step 1: 字符嵌入(Embedding)
  每个字 → 向量表示

Step 2: 编码器(Transformer / BiLSTM)
  多层 Transformer 或 BiLSTM 提取深层语义特征
  比 pkuseg 的 BiLSTM 更强,因为 Transformer 能捕捉更长距离的依赖

Step 3: 解码器(CRF)
  输出 BMES 标签序列
  → 我(S) 喜欢(B-E) 吃(S) 苹果(B-E)

Step 4: 多任务联合
  分词、词性标注、NER 共享编码器,各自有解码器
  → 一次推理,同时输出分词+词性+实体

LTP 与 pkuseg 的核心差异:

维度 pkuseg LTP
编码器 BiLSTM Transformer / BiLSTM
功能 仅分词 分词+词性+NER+句法
模型大小 ~200MB ~500MB-1GB+
上下文理解 中等 更强(Transformer 长距离依赖)

4. HanLP

属性 内容
开发者 hankcs(何晗)
算法 多版本:HanLP 1.x(传统)/ HanLP 2.x(深度学习)
特色 功能全面、支持多语言
安装 pip install hanlp
体积 约 500MB+
速度 中等
精度 高
import hanlp

# HanLP 2.x(深度学习版)
hanlp.load(hanlp.pretrained.tok.COARSE_ELECTRA_SMALL_ZH)

# 分词
tok = hanlp.load(hanlp.pretrained.tok.COARSE_ELECTRA_SMALL_ZH)
result = tok("我喜欢吃苹果")
print(result)  # ['我', '喜欢', '吃', '苹果']

优点:功能全面、文档优秀、社区活跃、支持多语言 缺点:体积较大、部分功能需要额外配置

HanLP 分词算法详解

HanLP 有两个大版本,算法完全不同:

HanLP 1.x(传统版,Java 实现):
  → 基于词典 + CRF + 规则
  → 类似 jieba 的思路,但加了 CRF 和规则后处理
  → 速度快,精度高

HanLP 2.x(深度学习版,Python 实现):
  → 基于预训练语言模型(如 ELECTRA)+ 任务特定解码器
  → 先用大规模语料预训练一个语言模型
  → 再在分词任务上微调
  → 精度最高,但体积大、速度慢

HanLP 2.x 的核心优势是预训练+微调范式:

Step 1: 预训练语言模型(ELECTRA / BERT)
  → 在大规模中文语料上学习语言的通用知识
  → 模型"理解"了中文的基本规律

Step 2: 在分词任务上微调
  → 用标注好的分词数据微调模型
  → 模型学会把"理解"应用到分词任务上

Step 3: 推理
  → 输入新文本 → 模型直接输出分词结果

5. THULAC(清华分词)

属性 内容
开发者 清华大学自然语言处理实验室
算法 基于 CWS(Chinese Word Segmentation)标准
特色 轻量、速度快
安装 pip install thulac
体积 约 100MB
速度 快
精度 中等偏上
import thulac

thu = thulac.thulac()
result = thu.cut("我喜欢吃苹果", text=True)
print(result)  # "我/r 喜欢/v 吃/v 苹果/n"

优点:轻量、速度快、清华出品 缺点:功能相对单一、社区活跃度下降

THULAC 分词算法详解

THULAC 采用 SSVM(结构化感知机) + 字符序列标注:

输入:"我喜欢吃苹果"

Step 1: 字符特征提取
  每个字提取一组特征:
  - 当前字是什么
  - 前一个字是什么
  - 后一个字是什么
  - 当前字的 n-gram

Step 2: 结构化感知机打分
  对每种可能的 BMES 标签序列打分
  → 选择得分最高的标签序列

Step 3: 根据标签切词
  → 我(S) 喜欢(B-E) 吃(S) 苹果(B-E)
  → ['我', '喜欢', '吃', '苹果']

THULAC 的特点: - 不用深度学习(无神经网络),用的是传统机器学习 - 模型小(~100MB)、推理快 - 同时输出分词 + 词性标注(一体化设计) - 精度介于 jieba 和深度学习工具之间


五大工具算法总览

工具 算法类型 核心技术 是否需要训练 时代
jieba 传统 前缀词典 + 动态规划 + HMM 不需要(词典内置) 2012
pkuseg 深度学习 BiLSTM-CRF 需要下载模型 2018
LTP 深度学习 Transformer/BiLSTM + CRF 需要下载模型 2020+
HanLP 2.x 深度学习 预训练语言模型 + 微调 需要下载模型 2020+
THULAC 传统 结构化感知机 + 序列标注 不需要(模型内置) 2015

可以看到中文分词工具经历了两代技术演进: 1. 第一代(传统):jieba(词典+HMM)、THULAC(感知机)——模型小、速度快、精度一般 2. 第二代(深度学习):pkuseg(BiLSTM-CRF)、LTP(Transformer)、HanLP(预训练+微调)——模型大、速度慢、精度高


工具对比总表

工具 开发者 算法 精度 速度 体积 功能 适合场景
jieba 社区 词典+HMM ★★★ ★★★★★ 50MB 分词 快速原型、资源受限
pkuseg 北大 BiLSTM-CRF ★★★★ ★★★ 200MB 分词+训练 需要领域自适应
LTP 哈工大 深度学习 ★★★★★ ★★ 1GB+ 全栈 NLP 需要完整 NLP 管线
HanLP hankcs 深度学习 ★★★★★ ★★★ 500MB+ 全栈+多语言 功能全面需求
THULAC 清华 传统 ★★★★ ★★★★ 100MB 分词 轻量快速

中文分词与 BERT WWM 的关系

WWM(Whole Word Masking,全词遮盖)要求以"词"为单位进行遮盖,而不是以"子词"为单位。这就需要先知道哪些字属于同一个词。

原始句子:我喜欢吃苹果

Step 1: 中文分词(用 jieba/LTP 等)
  → ["我", "喜欢", "吃", "苹果"]

Step 2: BERT WordPiece 分词
  → ["我", "喜", "欢", "吃", "苹", "果"]

Step 3: WWM 遮盖决策
  如果要遮盖"苹果"→ 必须同时遮盖"苹"和"果"
  因为 Step 1 告诉我们"苹果"是一个词

Step 4: 生成训练样本
  input_ids:  [我, 喜, 欢, 吃, [MASK], [MASK]]
  labels:     [-, -, -, -, 苹, 果]

没有中文分词 → 不知道词边界 → 无法做 WWM


选型建议

场景 推荐工具 理由
快速实验 / 资源受限 jieba 安装简单、速度最快
需要高精度 + 领域自适应 pkuseg 支持多领域模型
需要完整 NLP 管线(分词+词性+NER) LTP 功能最全面
与哈工大 WWM 论文保持一致 LTP 论文使用的就是 LTP
轻量 + 快速 THULAC 体积小、速度快

待办:实测对比计划

后续计划对以上工具进行实测对比,评估维度:

  1. 分词精度:在相同中文语料上的分词结果对比
  2. 处理速度:相同数据量下的处理时间
  3. 资源占用:内存与磁盘占用
  4. WWM 适用性:分词结果用于全词遮盖的效果

测试数据:BYP-RC-03 课题的 processed/corpus.txt(137MB,110 万句)


📖 资料来源: - jieba 官方仓库 - pkuseg 官方仓库 - LTP 官方仓库 - HanLP 官方仓库 - THULAC 官方仓库 - 哈工大 WWM 论文(使用 LTP 做分词)


🔗 相关笔记: - WordPiece算法:BERT的分词之道 - bert-base-chinese词表解剖 - 中文BERT三变体

相关笔记