中文分词

为什么要分词?

英文: 天然空格分割 + 词根

古文一般不加标点, 读书主要目的是”离经辨志” (“离”及断句), “明句读” (句号, 逗号).

20世纪后, 逐步统一规范了中文标点符号

有了标点符号后, 需进一步分词的意义

消除歧义

业务功能落地场景

分词评价指标

词典分词

字符串匹配算法

文本长度N, 词典大小M, 词最长为D

Trie / 前缀树

最长前缀匹配 O(D)

应用场景: CIDR/路由表, 域名查找 (最长后缀)

全文匹配 (一个朴素的办法): 每个位置做一次前缀匹配 O(N*D). 问题: 不匹配时很多计算路径信息被浪费了

AC算法:

DAT (Double-array Trie) 双数组实现Trie, 优化内存占用

See Code

多种分法的决策

词典无权重信息

词典有权重信息 (词频)

viterbi vs 寻路

都是DP, 保存到当前位置结束的最大权重及前向位置

OOV / 新词发现

不在词典中的片段, 直接当作新词肯定是不合适的, 需要尝试再切一下

HMM

Hidden Markov Model

HMM考虑点

选择后者效果越好, 需要训练数据越多, 计算效率越慢

词典分词 和 HMM交互

两阶段流程:

  1. 词典分出来最大路径
  2. 剩下的片段HMM尝试再切出最大概率

问题:

改进办法 (beam search):

词频及HMM参数学习

大量标注好的文本后直接统计即可得到

TODO

jieba (0.39)

https://github.com/fxsjy/jieba/tree/v0.39

jieba.lcut("我们中出了叛徒", HMM=True)
['我们', '中出', '了', '叛徒']

See Code

可优化点:

分词当作序列标注问题

序列标注: N*S DAG 网格上的最大路径选择

词性:

MEMM & CRF & SP

深度学习模型

  1. 表征层 (独热编码变稀疏表征): Embedding / BERT / …
  2. 记忆层: RNN / Bi-LSTM / Bi-GRU
    • 学输入对每个状态的概率表达
  3. 表达层: HMM / CRF / SP / …
    • 学状态迁移概率

LAC

https://github.com/baidu/lac

https://github.com/PaddlePaddle/models/tree/release/1.8/PaddleNLP/lexical_analysis

https://github.com/PaddlePaddle/PaddleNLP/tree/develop/examples/lexical_analysis

模型结构: Embedding + bi-GRU * 2 + CRF

逆向想法:

  1. 模型参数提取, 构造相同网络结构后导出ONNX
  2. 用于生成文本训练数据, 训练还原

LTP

TODO https://github.com/HIT-SCIR/ltp

HanLP

TODO https://github.com/hankcs/HanLP

文本搜索

搜索基本原理

搜索不同于单文档匹配, 是要高效处理海量文档

  1. 文档分词
    • 进一步结合搜索场景的处理, 正则化, 同义词/别名关联, 等等
  2. 建立词到文档的倒排索引
  3. 搜索文本分词, 文档计算相似度, 排序

精准匹配: 搜索文本必须是返回文本的子序列

不分词办法: 字索引. 缺点: 单字索引文档过多检索效率低, 没有管字的顺序性

最暴力序列匹配办法: 每个文本, 切成最大N片段, 对所有子序列做索引, 搜索时对文本同理处理

稍微优化一些: 剔除有包含关系的分法

基于分词的办法: 把所有字典出来的分词路径做索引

减少检索量, 高频词作为停用词忽略掉

分词粒度之于搜索

切分较细 / 词较短 / 召回优先 切分较粗 / 词较长 / 准确优先

搜索相似度指标

业务上根据其他字段匹配自行再加权计算: 如标题匹配分值要高一些, 命中词间距最好短一些, 等等

ES分词插件

IK分词器: https://github.com/medcl/elasticsearch-analysis-ik

官方插件: https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-smartcn.html

搜索质量严重依赖于分词及相似度计算指标, 很多搜不出来, 可惜现在没有例行评估优化

Zipf Law / Power Law / 幂律 / 长尾理论 / 马太效应 / 二八定律

ref: https://www.nature.com/articles/srep00812

从分词后做词云角度考虑:

编码 / Tokenization / 压缩 / 无监督自学习生成字典

上述分词 (构造词典, 计算HMM经验概率) 需要大量标注好的数据, 如何无监督的方式出分词? 语料 -> 最小编码字典过程

无损压缩 OR 有损压缩 ?

有损压缩: 掐头去尾

合OR分, 是个问题: 分开后需要大精力学会来

业务上分词优化想法

好的领域词典才是王道

Reference

HOME