新词发现

新词发现是 NLP 的基础任务之一,通过对已有语料进行挖掘,从中识别出新词。新词发现也可称为未登录词识别,严格来讲,新词是指随时代发展而新出现或旧词新用的词语。同时,我认为特定领域的专有名词也可归属于新词的范畴。何出此言呢?通常我们会很容易找到通用领域的词表,但要找到某个具体领域的专有名词则非常困难,因此特定领域的专有名词相对于通用领域的词语即为新词。换言之,“新”并非只是时间上的概念,同样可以迁移到领域或空间上。因此,新词发现不仅可以挖掘随时间变化而产生的新词,也可以挖掘不同领域的专有名词。

接下来,让我们开始一场新词发现的探索之旅吧。首先,对于“新词发现”这个标题,我们可将其拆分为“发现”和“新词”两个步骤:

  • “发现”:依据某种手段或方法,从文本中挖掘词语,组成新词表;
  • “新词”:借助挖掘得到的新词表,和之前已有的旧词表进行比对,不在旧词表中的词语即可认为是新词。

“新词发现”的难点主要在于“发现”的过程——如何从文本中挖掘到词语?那么有办法回避这个问题吗?让我们思索一下“新词”的过程:比对挖掘得到的新词表和旧词表,从代码的角度来说。

for 新词 in 新词表:
    if 新词 not in 旧词表:
        print("这是新词")

简单地讲,只要不是旧词就是新词呗,那么我们在对文本进行分词时,假设分词工具可以得到旧词,那么分词工具不能切分、切分有误或切分后不在旧词表中的词语不就是新词了吗?这就是“新词发现”的传统做法——基于分词的方法。

基于分词的方法

先对文本进行分词,余下未能成功匹配的片段(分词后的中文、连续的数字、连续的英文)就是新词。下面将以这篇文章为例:

汽车文章

使用经过汽车语料训练后的 pkuseg 分词器效果太好了,不利于后续的演示与说明,所以最终选择使用 jieba 分词(捂脸哭.jpg)。

【问题 1】:怎么去判断片段是否成功匹配了呢?

示例 1:内饰方面,两款新车配色上采用了全新的赭黑内饰,
分词 1:['内饰', '两款', '新车', '配色', '采用', '全新', '赭', '黑', '内饰']

示例 2:动力方面,两款新车继续搭载1.5L自然吸气发动机
分词 2:['动力', '两款', '新车', '搭载', '1.5', 'L', '自然', '吸气', '发动机']

对于问题 1,我们可以将分词后的单个字作为未成功匹配片段,例如示例 1 中的“赭黑”,jieba 分词后得到 [“赭”, “黑”],将这连续的两个单字整合到一块,即可获得新词“赭黑”。同理,我们可以将示例 2 中的 “1.5” 视为一个单独的片段,“L” 也为一个单独的匹配,将其整合为“1.5L”。但如果仅仅只将单个字作为未成功匹配片段,则会漏掉较多的新词,见下方问题 2。

【问题 2】:对于一些较长的新词,例如“人艰不拆”,使用 jieba 分词得到 [“人艰”, “不”, “拆”],此时的未成功匹配片段就不全是单字。换言之,新词中包含词语。

对于问题 2,我们可以找一份常用词表(该词表要尽可能齐全),然后借助这份词表去过滤分词后得到的常用词,最后余下的就是新词。假设“人艰”不在常用词表中,那么过滤后仍会留下 [“人艰”, “不”, “拆”],此时我们就可以将这些连续的片段进行整合,得到“人艰不拆”。但这样就完美了吗?没有,还有不少遗漏的新词,见下方问题 3。

【问题 3】:如果新词中包含的词语在常用词表中该怎么办?该问题相当于在问题 3 的基础上提出了——新词中包含常用词语。例如“一带一路”,使用 jieba 分词可得到 [“一带”, “一路”]。而对于问题 3 则比较难处理,需要更多繁复的规则去做后处理。

此外,新词发现的目标是挖掘文本中的新词,或者说未登录词,来帮助后续的分词等工作。而基于分词的方法则相当于从目标反推过程,这种方法未尝不可行,但分词的准确性本身依赖于词库的完整性,如果词库中根本没有新词,又怎么能信任分词的结果呢?自然,最终得到的效果也不会特别好。

通过上述的分析,可以知道传统的方法存在许多的掣肘,那么有什么新的方法吗?通过查阅资料以及一些思考,在新词发现方面,目前主要有基于规则和基于统计两种方法。接下来,让我们具体谈谈这两种方法。

基于规则的方法

根据新词的构词特征或外型特征建立规则库、专业词库或模式库,然后通过规则匹配发现新词。因此,我们需要对已有的语料有着足够的了解,继而从语料中抽取固定的模式来匹配和发现新词。例如,在一份汽车领域的语料中抽取所需的汽车新词。

汽车文章

从上面的汽车文章中可以发现,顿号(、)前后的词语通常会是汽车领域的专有名词,这正是我们需要的新词。故而,我们可以通过编写正则表达式的方式,从文章中将这些内容抽取出来,并依据相应的规则作清洗和过滤。

【优点】:新词挖掘的效果非常好,像“支持CarPlay+CarLife双机互联”这一类夹杂中文、英文和标点符号的词语(短语)也能抽取出来。

【缺点】:与领域耦合过深,无法将建立的规则库、专业词库以及模式库迁移到其他领域中,需要根据领域内容重新搭建。甚至与特定类型、出版社、渠道的文章耦合过深,例如汽车之家的汽车文章和易车的汽车文章的格式就不同,需要为不同的数据源搭建相应的规则库。一旦数据源的文章格式变动,规则库也需要作相应的修改。无论是搭建还是后续的维护,都需要大量的人工成本。

基于统计的方法

基于统计的方法根据有无标注数据可分为有监督方法和无监督方法。

有监督方法

有监督方法利用标注语料,将新词发现看作分类或者序列标注问题:

  • 基于文本片段的某些统计量,以此作为特征训练二分类模型;
  • 基于序列信息进行序列标注直接得到新词,或对得到的新词再进行判定。

通常可以用 HMM、CRF、SVM 等机器学习算法实现。但是在实际应用中,获取大量的标注语料数据是非常困难的一件事情,并且既然已经有了手工标注的数据,那么直接把标注得到的新词加入到新词词库就好了,又何必建模来解决呢?所以,探索无监督的挖掘方法在新词发现领域中更有价值。

无监督方法

不依赖于任何已有的词库、分词工具和标注语料,仅仅根据词的共同特征,利用统计策略将一段大规模语料中可能成词的文本片段全部提取出来,然后再利用语言知识排除不是新词语的“无用片段”或者计算相关度,寻找相关度最大的字与字的组合。最后,把所有抽取得到的词和已有的词库进行比较,就能得到新词。

实际上,利用统计策略对语料进行切分,形成若干块文本片段,这相当于一次粗浅的分词。接下来,再对这些文本片段作一次清洗与过滤,余下的文本片段即可作为新词词库。因此,上述过程可简化为两个步骤:

  1. 构建词库
  2. 新词比对

目前已有的大多数基于统计的新词发现方案和博客,其根本思想都是源于 matrix67 纂写的《互联网时代的社会语言学:基于SNS的文本数据挖掘》。下文所讲的内容也未能跳离这个框架,只是在前人的基础上增加了些许自身的理解与尝试,以及努力尝试将实现步骤呈现给读者。

构建词库

怎么样的文本片段才能作为一个词语?或者说作为一个词语的文本片段需要满足什么条件

  • 词频
  • 凝聚程度
  • 自由程度

接下来,让我们依次探讨这三个条件对判断成词的作用与意义。

词频

首先,被选中的文本片段要在语料中出现多次,目的是为了排除偶然情况,例如笔误的情况。因此,我们可以通过设置一个阈值,将频数超过该阈值的文本片段提取出来,作为当前语料的词汇输出。

但光凭词频不足以判断,一个经常出现的文本片段有可能不是一个词,而是多个词构成的词组,例如“的电影”、“在北京”等词组。这些词组并不是我们想要的词语,我们想要的是“电影院”之类的词语。此时就需要凝聚程度来帮助我们作进一步的判断。

凝聚程度

凝聚程度用以衡量相邻字组合成词语的程度,如果两个人经常待在一起,我们往往会认为他们的关系很亲密,而字与字之间的“亲密关系”则通过凝聚程度(其他文献中称为“凝合程度”)来表示。

凝聚程度要如何进行计算呢?词组的出现概率除以构成词组的各个词语的出现概率的乘积,最后对结果做一次对数处理(可以理解为对计算得到的概率值组了一次映射)。
P M I ( x , y ) = log ⁡ 2 p ( x , y ) p ( x ) p ( y ) P M I(x, y)=\log _{2} \frac{p(x, y)}{p(x) p(y)} PMI(x,y)=log2p(x)p(y)p(x,y)

p(x, y) <= p(x)、p(x, y) <= p(y),且 p(x) < 0、p(y) < 0,因此:
p ( x , y ) p ( x ) p ( y ) ≥ 1 \frac{p(x, y)}{p(x)p(y)} \geq 1 p(x)p(y)p(x,y)1

对于 log 函数而言,真数 >= 1,函数值 >= 0,加上 log 函数相当于将原本的函数值映射到 [0, +∞] 区间,且增速放缓。

log函数

仍然以“的电影”和“电影院”为例。

  • 的电影 = 的 + 电影
  • 电影院 = 电影 + 院
电影:0.01,院:0.01,电影院:0.001
P(电影院)/P(电影)P(院):0.001 / (0.01 * 0.01) = 10

电影:0.01,的:0.2,的电影:0.002
P(的电影)/P(的)P(电影):0.002 / (0.01 * 0.2) = 1

上面的结果表明“电影院”更可能是一个有意义的搭配,而“的电影”则更像是“的”和“电影”这两个成分偶然拼到一块。

凝聚程度的计算方式很大程度上受到文本切分的影响,因此我将这部分的内容移到了文本切分部分。

自由程度

词语作为汉语中的一个基本语义单元,具备一个显著的特征——可以灵活地应用到不同的场景中。例如“机器学习”,上下文可以搭配很多动词和名词“学习人工智能知识”、“从事人工智能行业”。但对于“人工智”这个词语来说,上文依然可以搭配很多词语,下文却基本上只能搭配“能”。那么,我们可以认为“人工智”不是一个完整的词语。

换个角度来看,词语的自由程度可以理解为词语之间的相关性弱,换言之,词语的独立性高。苏剑林大佬纂写的《无监督构建词库:更快更好的新词发现算法》 一文中提到:

为什么要分词?人本来就是按照字来书写和理解的呀?

当模型的记忆和拟合能力足够强(或者简单点,足够智能)的时候,我们完全可以不用分词的,直接基于字的模型就可以做,比如基于字的文本分类、问答系统等,早已有人在研究。但是,即便这些模型能够成功,也会因为模型复杂而导致效率下降,因此,很多时候(尤其是生产环境中),我们会寻求更简单、更高效的方案。

什么方案最高效?以文本分类为例,估计最简单高效的方案就是“朴素贝叶斯分类器”了,类似的,比较现代的是 FastText,它可以看作是“朴素贝叶斯”的“神经网络版”。要注意,朴素贝叶斯基于一个朴素的假设:特征之间相互独立。这个假设越成立,朴素贝叶斯的效果就越好。然而,对于文本来说,显然上下文紧密联系,这个假设还成立吗?

注意到,当特征之间明显不独立的时候,可以考虑将特征组合之后,使得特征之间的相关性减弱,再用朴素贝叶斯。比如,对于文本,如果以字为特征,则朴素假设显然不成立,如“我喜欢数学”中的“喜”和“欢”、“数”和“学”都明显相关,这时候我们考虑将特征进行组合,得到“我/喜欢/数学”,这样三个片段之间的相关性就没有那么强了,因此可以考虑用上述结果。

可以发现,这个过程很像分词,或者反过来说,分词的主要目的之一,就是将句子分为若干个相关性比较弱的部分,便于进一步处理。

知道了什么是自由程度,以及为什么自由程度可以作为新词的评估指标,那么我们该如何计算当前文本片段的自由程度呢?简单地讲,如何衡量当前文本片段的上下文可搭配词语的丰富程度呢?

matrix67 提出可以使用信息熵来进行度量,令当前文本片段为 x,其上文的词语为 y l y_l yl,下文的词语为 y r y_r yr
H ( y ∣ x ) = − ∑ y p ( y ∣ x ) l o g p ( y ∣ x ) H(y|x) = -\sum_y p(y|x)log p(y|x) H(yx)=yp(yx)logp(yx)

当前文本片段的上文和下文可搭配词语越丰富,则其上文信息熵(左信息熵)和下文信息熵(右信息熵)越大。一般,我们取左右信息熵中的最小值。

当然我们也可以自行设计一个合理的统计量去度量自由程度。例如,综合考虑文本片段左右信息熵(LE、RE)的大小、LE 与 RE 差的绝对值 (|LE - RE|)。
L ( W ) = log ⁡ L E ⋅ e R E + R E ⋅ e L E ∣ L E − R E ∣ L(W)=\log \frac{L E \cdot e^{R E}+R E \cdot e^{L E}}{|L E-R E|} L(W)=logLERELEeRE+REeLE

从执行流程上来看,自由程度的阈值计算相当于对上一步凝聚程度所得的词表进行了一次过滤,从中剔除不满足自由程度要求的词语。

语义完整

语义完整是我在阅读《Automated Phrase Mining from Massive Text Corpora》这篇论文时得到的灵感。一个词语的语义应该是完整的,例如“电影院”。而不应该像“的电影”,语义是欠缺的。

那么如何去判断一个文本片段的语义是否完整呢?初步的想法:依据词性标注,判断构成文本片段的各子文本片段的词性,例如“前麦弗逊式独立悬架”,经过词性标注后的结果 [('前', 'f'), ('麦弗逊式', 'n'), ('独立', 'v'), ('悬架', 'n')],构成偏正结构,因此我们可认为具有完整的语义信息。

再举个反例,例如“前麦弗逊式独立悬架驱”,其词性标注结果 [('前', 'f'), ('麦弗逊式', 'n'), ('独立', 'ad'), ('悬架', 'v'), ('驱', 'v')],最后一个“驱”字为动词 v,那么这个词语不具备完整的语义,因此我们可以认为“前麦弗逊式独立悬架驱”不应该作为一个词语。

然而语义完整很难在实际中进行运用,例如“人艰不拆”,其词性标注 [('人', 'n'), ('艰', 'a'), ('不', 'd'), ('拆', 'v')],如果按照“前麦弗逊式独立悬架驱”的判断标准,那么“人艰不拆”不应该作为一个词语。因此,语义完整的判断标准该如何设置,以及在评判标准中的定位都是一个值得商榷的问题。

缺点:限于查找较短的新词语,但不便于描述词语的内部和外部结构特征,同时对于出现频率很低的新词识别效果不好。

文本切分

文本切分主要有两种处理方式:合词与切分。接下来我会详细地介绍这两种处理方式的执行过程。

合词

从左到右依次计算相邻文本片段的凝聚程度,若达到设定的阈值,则将这两段文本片段整合为一块新的文本片段,然后继续去计算该整合后的文本片段与下一段相邻文本片段的凝聚程度。不断循环,直到无文本片段。

【处理过程】:以“巧克力”为例。

  1. 首先,计算“巧克”的凝聚程度,若超过阈值,则将其合并;
  2. 然后计算“巧克”与“力”的凝聚程度,若超过阈值,则将其合并,得到“巧克力”。

【问题 1】:当两段相邻文本片段整合为一块新的文本片段时,我们该如何去获取这块新文本片段的频数呢?同样,三段、四段乃至 n 段文本片段整合后,该如何计算这些文本片段的频数呢?

【解决方案】:以“巧克力”为例,我们需要统计 2-gram 的频数,对于较长的词语,则需要统计 n-gram 的频数。

上述解决方案仍然不是一个明智之举,n-gram 的 n 值越大,需要统计的词语也越多,对性能的开销也逐渐增大。此外,如何设置 n 值也是一个值得商榷的问题,一般 n ≤ 5。但这对于一些特殊领域的新词发现并不能起到良好的效果,例如汽车领域中的“前麦弗逊式独立悬架”,存在较长的新词。

【问题 2】:令合词操作得到的文本片段为 A,下一段相邻文本片段为 B。随着合词操作的进行,P(A) 和 P(A, B) 一般会越来越小且越来越接近。此时,P(B) 对 PMI(A, B) 起主要影响作用。那么只要文本片段 B 是一些低频字,PMI(A, B) 的值仍然可以超过设定的阈值,从而将文本片段 A 和 B 整合得到 C,但 C 很有可能不是我们想要的新词,例如“前麦弗逊式独立悬架驱”,由于“驱”字在语料中出现的频率很低,因此极容易将“前麦弗逊式独立悬架”和“驱”进行整合,得到不期待的结果。

【解决方案】:使用平均互信息(AMI)作为凝聚程度的计算公式(参考自"新词发现"算法探讨与优化-SmoothNLP)。
A M I ( X , y ) = 1 n l o g 2 p ( X , y ) p ( x 1 ) ⋯ p ( x n ) p ( y ) AMI(X, y) = \frac{1}{n} log_2 \frac{p(X, y)}{p(x_1) \cdots p(x_n)p(y)} AMI(X,y)=n1log2p(x1)p(xn)p(y)p(X,y)
其中 n 表示文本片段的个数,例如“巧克力”和“的”,其中“巧克力”由三个文本片段组成,因此 n = 4。
A M I ( 巧克力 , 的 ) = 1 4 l o g 2 p ( 巧克力的 ) p ( 巧 ) p ( 克 ) p ( 力 ) p ( 的 ) AMI(\text{巧克力}, \text{的}) = \frac{1}{4} log_2 \frac{p(\text{巧克力的})}{p(\text{巧})p(\text{克})p(\text{力})p(\text{的})} AMI(巧克力,)=41log2p()p()p()p()p(巧克力的)

实际上 1 n \frac{1}{n} n1 可视为对文本片段长度的一个惩罚系数,而这惩罚系数我们可以视情况自行设定。

切词

从左到右依次计算相邻文本片段的凝聚程度(与合词不同,每次只计算相邻两个文本片段的凝聚程度),若未达到设定的阈值,则将这两段文本片段进行切分。不断循环,直到无文本片段。

【处理过程】:以“巧克力真好吃”为例。

  1. 首先,计算“巧克”的凝聚程度,若超过阈值,则继续计算“克力”的凝聚程度,若仍然超过阈值,则继续计算下一对文本片段“力真”的凝聚程度;
  2. 若“力真”的凝聚程度小于阈值,则进行切分“力|真”,继续计算下一对文本片段;
  3. 最终可得“巧克力|真|好吃”。

合词、切词与凝聚程度

【合词与切词的比较】:

  • 合词需要更多的统计信息,而切词仅需要 2-gram 的统计信息(计算相邻两个文本片段的凝聚程度)即可,因此切词的执行开销要远小于合词;
  • 合词的过程中会遇到合词中提到的问题2,而切词不会出现该问题;

切词的缺陷

切词忽略了更多的上下文信息,因为切词仅考虑相邻两个文本片段,例如对于“电影院”,切词只会计算“电”和“影”、“影”和“院”之间的凝聚程度。我们都知道 P(影) >= P(电影),P(影院) ≈ P(电影院),那么计算得到的凝聚程度,PMI(电影,院) > PMI(影,院)。对于一些三字以上且包含常用字的词语,通过切词的方式往往会被“一刀两断”。

电影院手拉手

“电”、“影”、“院”三位好朋友手拉手,“电”小朋友是一位交际花,她有许多的朋友,而人的精力总是有限的,因此“电”小朋友和“影”小朋友的玩耍时间远没有“影”小朋友和“院”小朋友来得多。但我们没有因为“电”的朋友多且和“影”一起玩耍的时间少,而认为他们俩不是朋友。因此,仅考虑相邻文本片段的切词过程计算得到的是“封闭程度”,而非凝聚程度。例如,“饕餮”、“沆瀣”等词,他们只拥有彼此。

针对这个问题,苏剑林大佬提出了改进,在文章《无监督构建词库:更快更好的新词发现算法》中提出了多字的凝聚程度计算方式。以下是文章中的原文:

文章《【中文分词系列】 2. 基于切分的新词发现》其实就是这个意思,只是那里认为,文本的相关性仅由相邻两字(2grams)来决定,这在很多时候都是不合理的,比如“林心如”中的“心如”、“共和国”中的“和国”,凝固度(相关性)都不是很强,容易错切。

因此,本文就是在前文的基础上改进,那里只考虑了相邻字的凝固度,这里同时考虑多字的内部的凝固度(ngrams),比如,定义三字的字符串内部凝固度为:

min ⁡ { P ( a b c ) P ( a b ) P ( c ) , P ( a b c ) P ( a ) P ( b c ) } \min \left\{\frac{P(a b c)}{P(a b) P(c)}, \frac{P(a b c)}{P(a) P(b c)}\right\} min{P(ab)P(c)P(abc),P(a)P(bc)P(abc)}

如果按照这一种思路来做的话,切词方式所带来的实现与执行上的优势(不需要获取更多的统计信息 n-gram)将荡然无存。苏剑林大佬之所以选用这种方式,是因为他只采用了凝聚程度和词频作为新词的判断依据。为什么不加上自由程度呢?因为自由程度的计算时间要远大于凝聚程度。在上文的自由程度中也提到,自由程度在流程上的主要贡献在于对凝聚程度所得到的词表进行过滤,至于需不需要耗费大量的时间去做这一层过滤,则需要视情况而定,这大概也是苏剑林大佬放弃使用自有程度的原因之一吧。

并且按照上述方法来做,仍然不能解决两字词语存在的切分问题,对于一些频数较高的字,例如“在”、“利”等,我们在计算其组合(“现在”、“利益”)的凝聚程度时,所得到的凝聚程度往往较低,容易被切分成单字。

【示例】:以“利率”为例,在所有语料中“利率”出现的次数不会太多,同时“率”的出现次数略高于“利率”,那么在凝聚程度的计算公式中,“利”的出现次数对最终凝聚程度起到关键作用。但像“利”这一类高频字,会使得计算得到的凝聚程度较小,低于设定的阈值,从而使得“利率”这一类的词被切分。

那么如何去解决这一类的切分问题呢?

切分问题的一些方案

针对上一小节提到的切分问题,我针对目前已有的工作提出了两个思路:

  • 调整凝聚程度计算公式;
  • 依据自由程度进行扩展。

调整凝聚程度计算公式

切分问题的实质在于高频字对成词的影响,那么我们适当调低高频字对成词的影响,或提高共现频率在计算公式中的比重。

【简单的实现方式】:
P M I ( A , B ) = l o g 2 α P ( A B ) β 1 P ( A ) ∗ β 2 P ( B ) PMI(A, B) = log_2\frac{\alpha P(AB)}{\beta_1 P(A) * \beta_2 P(B)} PMI(A,B)=log2β1P(A)β2P(B)αP(AB)
α \alpha α 用以提高 A、B 共现频率的权重,而 β 1 \beta_1 β1 β 2 \beta_2 β2 则可视为对高频字的惩罚系数。

如果 α \alpha α β \beta β 是一个固定的数值,且 β 1 \beta_1 β1 = β 2 \beta_2 β2,相当于在原式上乘上了一个固定的系数 γ \gamma γ,起到的作用并不大,完全可有通过调整凝聚程度的阈值(除以 γ \gamma γ)来起到相应的作用。因此,我认为线性地改变原式并不能起到改进作用。但它提供了两种可行的改进方向:

  • 非线性地增大共现频率的权重;
  • 非线性地降低高频字的权重。

非线性地增大共现频率的权重

为了加大共现频率的权重,我们可以在原式的基础上再乘上共现频率:
P M I ( A , B ) ′ = P ( A , B ) l o g 2 P ( A , B ) P ( A ) P ( B ) PMI(A, B)' = P(A, B) log_2 \frac{P(A, B)}{P(A) P(B)} PMI(A,B)=P(A,B)log2P(A)P(B)P(A,B)

上式实际上就是互信息的计算公式,此时 P(A)、P(B) 和 P(AB) 都是固定的值,我们可以通过给 P(AB) 加上未知的系数,使其转变为变量。
A B = α P ( A B ) AB = \alpha P(AB) AB=αP(AB)

这样我们就可以将原式视作共现频率 P(AB) 的一个函数。
f ( A B ) = l o g 2 α P ( A , B ) P ( A ) P ( B ) f(AB) = log_2 \frac{\alpha P(A, B)}{P(A) P(B)} f(AB)=log2P(A)P(B)αP(A,B)

最终转变为:
P M I ( A , B ) ′ = A B f ( A B ) PMI(A, B)' = AB f(AB) PMI(A,B)=ABf(AB)

f(AB) 可理解为共现频率的非线性权重系数,上述式子对实际的计算没有作用,提供了另一种角度的解释。

【互信息计算公式效果】:

互信息效果图

【原式效果】:

原式效果

可以看到乘上共现频率的效果并不如原始的效果,这有两方面的原因:

  1. 乘上共现频率后的凝聚程度阈值需要相应地调低,但共现频率的波动较大,如何设置凝聚程度阈值是一个问题;
  2. 马太效应:较大的共现频率可以得到更高的凝聚程度,而较低的共现频率则得到更低的凝聚程度,这显然不是我们想看到的。

此时,我们亦然陷入一个误区:单纯地提高共现频率对结果不一定能起到正向作用,或者说依靠固定值或共现频率去提高共现频率的权重不是一个好办法。

单纯提高共现频率的权重,这可能会帮助我们解决“利|益”的切分问题,但同时也会导致“美丽”和“的”组合成“美丽的”。当然,并非说这条路走不通,而是需要借助更多的信息,在共现频率权重的计算过程中引入其他的统计信息。

非线性地降低高频字的权重

一种简单的实现方式:比较 P(A) 和 P(B) 的大小,若 P(A) > P(B),那么 β 1 \beta_1 β1 < β 2 \beta_2 β2。目的在于非线性地降低高频字在式子中的权重。通过这种方式,我们可以适当提高“现在”、“利益”等词的凝聚程度,但同时也会提高“漂亮的”、“美丽的”这些词语的凝聚程度。简单地说,我们不想降低“的”、“了”、“呢”这些高频字的权重,为了方便后续的说明,特将这些字命名为“停用字”。

对于这种情况,我们可以按字的频数取 topK,然后对这些字的频率加大惩罚。

下面是从汽车领域的 80w 文章中统计的 top 100 字频率。取语料中统计得到的 topk 能够更准确地反映领域的特点,但很显然“车”、“型”这些字是我们需要的。

语料中获取的 topK

在实际处理过程中,通用领域的“停用字”也往往是特定领域的“停用字”,因此我们直接使用通用领域的“停用字”即可,例如找一份停用词表,从中将单字抽取出来。

'嗬', '嗯', '嗳', '嘎', '嘘', '嘛', '嘻', '嘿', ......

依据自由程度进行扩展

思路:依据凝聚程度得到的“候选词”的自由程度来将相邻的“候选词”重新进行组合。

【具体步骤】:

  1. 若切分后的文本片段自由程度小于设定阈值,则尝试将当前文本片段与相邻文本片段进行组合;
  2. 计算组合后的文本片段的自由程度,若自由程度提高则继续组合相邻的文本片段;
  3. 若连续组合之后的文本片段的自由程度高于设定阈值,则将这段文本片段作为新的词语,否则出局。

【问题 1】:连续组合相邻文本片段会导致最终得到一个超长的词语吗?

【回答 1】:不会,当超过某个临界点时(n = 4),字数越长的文本片段其自由程度越低。因为 n-gram 中的 n 越大,得到的文本的频数越低,因此其相邻词语的数量也越少,信息熵越来越低,低于设定的阈值。

自由程度曲线图

【注意】:“利”的左信息熵不能作为“利率”的左信息熵,换言之,“利”的左邻词语不能作为“利率”的左邻词语,必须要“利”和“率”共有的左邻才能作为“利率”的左邻词语。右信息熵同理。

执行过程

  1. 首先将文本拆分为文本片段(字符、英文单词等);
  2. 基于凝聚程度和切词方式对文本进行切分,获得一个粗的词库,同时也对文本做了一次粗的分词;
  3. 基于自由程度从上一步的到得词库中筛选出词语;

告一段落

新词发现还有许多的工作可以去尝试:

  • 尝试从文本中挖掘更多的统计量,而非仅仅局限于频数和频率;
  • 如何去设计一套无监督的评估指标也是非常有挑战的工作;
  • 全文主要讲述切词的工作,关于合词也有不少可探索的工作。

参考

  • 新词发现:中文新词识别技术简介:https://blog.csdn.net/sinat_33741547/article/details/81704798
  • 互联网时代的社会语言学:基于 SNS 的文本数据挖掘:http://www.matrix67.com/blog/archives/5044
  • "新词发现"算法探讨与优化-SmoothNLP:https://zhuanlan.zhihu.com/p/80385615
  • 无监督构建词库:更快更好的新词发现算法:https://zhuanlan.zhihu=
©️2020 CSDN 皮肤主题: 成长之路 设计师:Amelia_0503 返回首页