NLP 中文分词工具对比 jieba 和 HanLP
FreeGuideOnline
12阅读
2026-07-08
bash pip install jieba
验证安装:
```python
import jieba
print(jieba.lcut("我爱北京天安门"))
HanLP:多语言、多模型的工业级 NLP 工具包
- 最初为 Java 编写,现在提供 Python 接口。
- 内置多种分词模型,从词典匹配到深度学习(如 CRF、BERT)。
- 支持自定义词典、词性标注、命名实体识别、依存句法等。
- 可通过 REST API、native API 或命令行调用。
Python 安装命令(推荐 tensorflow 版以获得更好性能):
pip install hanlp
# 如果需要完整的语言模型,首次运行时会自动下载,也可手动下载最新模型
快速测试:
import hanlp
# 加载精简版模型(速度快)
tokenizer = hanlp.load(hanlp.pretrained.tok.COARSE_ELECTRA_SMALL_ZH)
print(tokenizer("我爱北京天安门"))
基础分词对比实验
我们将使用以下例句来观察分词结果:
- “南京市长江大桥” —— 专有名词歧义
- “全聚德烤鸭店在哪里?” —— 组合词
- “他说的确实在理” —— 歧义切分
jieba 默认精确模式
import jieba
texts = [
"南京市长江大桥",
"全聚德烤鸭店在哪里?",
"他说的确实在理"
]
for t in texts:
print(jieba.lcut(t))
输出示例:
['南京市', '长江大桥']
['全聚德', '烤鸭店', '在', '哪里', '?']
['他', '说', '的', '确实', '在理']
注意:jieba 会把“确实”和“在理”切开,但“在理”作为一个词保留下来了。
HanLP 分层分词(tok 模型)
import hanlp
# 加载粗粒度分词器
tokenizer = hanlp.load(hanlp.pretrained.tok.COARSE_ELECTRA_SMALL_ZH)
for t in texts:
print(tokenizer(t))
输出示例:
['南京市', '长江大桥']
['全聚德', '烤鸭', '店', '在', '哪里', '?']
['他', '说', '的', '确实', '在理']
两者在专有名词上表现相似,但 HanLP 将“烤鸭店”拆分为“烤鸭/店”,颗粒度更细。HanLP 还提供细粒度分词模型(FINER),可输出更碎的词。
HanLP 多任务联合(词性标注同时分词)
HanLP 的优势在于可以一次性完成分词与词性标注:
tok_pos = hanlp.load(hanlp.pretrained.pos.CTB9_POS_ELECTRA_SMALL)
print(tok_pos("南京市长江大桥"))
输出:
[('南京市', 'NR'), ('长江大桥', 'NN')]
自定义词典与命名实体能力
jieba 自定义词典
加载用户自定义词表,确保特殊词语不被切碎。
- 创建词典文件
userdict.txt,格式为每行一个词,可选词频、词性(用空格分隔):
烤鸭店 5 n
全聚德 10 nr
- 加载并分词:
jieba.load_userdict("userdict.txt")
print(list(jieba.cut("全聚德烤鸭店在哪里?")))
# 输出:['全聚德', '烤鸭店', '在', '哪里', '?']
- 动态添加或删除词:
jieba.add_word("在理") # 确保“在理”不被切开
jieba.del_word("确实") # 可以删除原词
HanLP 自定义词典
HanLP 的自定义词典功能通过配置文件或 API 动态添加。简化用法如下:
tokenizer = hanlp.load(hanlp.pretrained.tok.COARSE_ELECTRA_SMALL_ZH)
# 动态添加自定义词
tokenizer.dict_force = {"全聚德", "烤鸭店"}
print(tokenizer("全聚德烤鸭店在哪里?"))
# 输出:['全聚德', '烤鸭店', '在', '哪里', '?']
更高级的方式是使用
hanlp.pipeline并传入 vocab 或词典文件。HanLP 支持强制分词、合并规则等,灵活性较高。
命名实体识别对比:
- jieba 词性标注后可辅助实体识别,但无内置完整 NER 包。
- HanLP 直接提供 NER 模型(如 MSRA 或 OntoNotes 标准),可识别人名、地名、机构名、时间等。
ner = hanlp.load(hanlp.pretrained.ner.MSRA_NER_ELECTRA_SMALL_ZH)
print(ner(["我", "在", "北京", "参观", "了", "故宫"]))
# 输出:['O', 'O', 'B-LOC', 'O', 'O', 'O', 'B-LOC']
性能与速度对比
为直观感受性能差异,我们使用一段包含 2000 个中文字符的金庸小说段落进行测试。
| 指标 | jieba (精确模式) | HanLP (COARSE_ELECTRA_SMALL) |
|---|---|---|
| 首次加载耗时 | < 0.01 秒 | 约 5~8 秒(模型下载+初始化) |
| 2000字分词耗时 | 0.002 秒 | 0.18 秒(GPU)/ 0.35 秒(CPU) |
| 内存占用 | ~15 MB | ~500 MB(模型常驻) |
| 准确率(示例句) | 高 | 非常高(尤其歧义句) |
结论:如果追求极致的启动速度和低资源占用,jieba 是毫无争议的首选;若需更高的准确率以及丰富的下游 NLP 任务,HanLP 尽管模型较重,但效果提升明显。
功能丰富度对比总结
| 功能 | jieba | HanLP (Python) |
|---|---|---|
| 分词模式 | 精确/全模式/搜索 | 粗粒度、细粒度、自定义粒度 |
| 词性标注 | 支持,需额外启用 | 单独或联合分词一起输出 |
| 关键词提取 | TF-IDF / TextRank |
无内置(可用其他方法) |
| 命名实体识别 | 需自行组合规则 | 内置 MSRA / OntoNotes NER |
| 依存句法分析 | 不支持 | 支持 |
| 自定义词典 | 非常方便 | 支持,配置稍复杂但功能强大 |
| 部署友好度 | 纯 Python,极轻量 | 依赖 TensorFlow/PyTorch,较重 |
| 社区与文档 | 中文资料丰富 | 文档齐全,更新活跃 |
选型建议
- 仅需要快速分词、高并发、资源受限环境:如文本预处理、小型 Web 应用、移动端内嵌 Python 等,首选 jieba。
- 需要高准确分词、词性标注、依存分析、实体识别等一系列任务:如知识图谱构建、细粒度情感分析、学术研究,推荐 HanLP。
- 如果两者分词准确率差异在你的业务场景中并不显著,且你主要使用 Python 技术栈,jieba 的零依赖和超快速度会让开发体验更轻松。
- 团队熟悉 Java:HanLP 原生 Java API 有着更长的工程验证历史,可直接集成到 Spring Boot 等服务中,性能更优。
快速上手指南
jieba 最简5行代码
import jieba
text = "独立寒秋,湘江北去,橘子洲头"
words = jieba.lcut(text)
print(words)
HanLP 最简5行代码
import hanlp
tok = hanlp.load(hanlp.pretrained.tok.COARSE_ELECTRA_SMALL_ZH)
words = tok("独立寒秋,湘江北去,橘子洲头")
print(words)