端侧智能初窥:使用HMM进行文本分词

Posted: May 22, 2024

1. 问题导入

分词是中文自然语言处理中一个非常基础的需求,这是因为中文与英文存在一个非常重要的区分:中文里没有天然的分隔符。以「南京市长江大桥」为例,它对应的英文是「Nanjing Yangtze River Bridge」,每一个单词之间会存在空格区分。但是对于中文而言,我们至少可以以两种方式理解这句话:

  1. 南京市/长江/大桥
  2. 南京/市长/江大桥

作为一个对中文有所了解的我们,会知道第一个分割方式是合理的,然而计算机如何知道这件事呢?这个问题在中文自然语言处理中被称作分词,text segmentation,目的是将中文文本切分为若干最小语义单元(token),在BERT、GPT等语言模型里,tokenization也是训练模型的第一步。

目前浏览器提供了原生的分词接口,以便大家处理在前端里的分词需求。然而,浏览器(以Chrome为例)提供的分词规则是非常初级的,以我的观察,这大概率只是去统计高配词,然后贪心划分高频词。我们可以用一个例子来看到这种方法的不足,「浏览器鼠标双击选中文本就是自动分词的」。

An image from Notion

可以看到,浏览器错误地把「选中」和「文本」拆分为「选」、「中文」、「本」,这是因为「中文」作为一个token出现在语料里的频率大于「选中」和「文本」。

我们可以用浏览器提供的接口看到它进行文本分词的结果:

An image from Notion

可以看到,浏览器提供的接口在这个实例上有诸多的不足:

  1. 「浏览器」应当是一个token,而不应该被区分为「浏览」、「器」
  2. 「鼠标」应当是一个token
  3. 「选」「中文」「本」应当被分割为「选中」、「文本」

这里给出使用隐马尔可夫模型(Hidden Markov Model, HMM)的模型的分词结果:

An image from Notion

可以看到,使用HMM,模型的分词准确率有很显著的提升。

2. HMM分词原理

An image from Notion

分词任务的基本思想是,对于一段文本

λ=λ1λ2...λnλn+1\lambda=\lambda_1\lambda_2...\lambda_n\lambda_{n+1}

我们的目标是预测每个字符的标签

o=o1o2...onon+1o=o_1o_2...o_no_{n+1}

在常见的分词实现里,我们一般会使用四个角色标注字符,

  1. B:Token开始字符
  2. M:Token的中间字符
  3. E:Token的结束字符
  4. S:单个字符作为Token

假设我们的分词模型为概率模型/latex