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("我爱北京天安门"))

基础分词对比实验

我们将使用以下例句来观察分词结果:

  1. “南京市长江大桥” —— 专有名词歧义
  2. “全聚德烤鸭店在哪里?” —— 组合词
  3. “他说的确实在理” —— 歧义切分

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 自定义词典

加载用户自定义词表,确保特殊词语不被切碎。

  1. 创建词典文件 userdict.txt,格式为每行一个词,可选词频、词性(用空格分隔):
烤鸭店 5 n
全聚德 10 nr
  1. 加载并分词:
jieba.load_userdict("userdict.txt")
print(list(jieba.cut("全聚德烤鸭店在哪里?")))
# 输出:['全聚德', '烤鸭店', '在', '哪里', '?']
  1. 动态添加或删除词:
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)