基于凝固度和自由度的新词发现算法

背景

英语的单词是以空格分隔,所以分词的时候较为简单。但是汉语的词语之间没有空格,存在分词歧义问题。如句子"已结婚的和尚未结婚的青年都要实行计划生育"可能是说"已/结婚/的/和/尚未/结婚/的/青年",也可能是说"已/结婚/的/和尚/未/结婚/的/青年"。幸运的是,现在已经有很多分词工具可以解决这类问题。

但是,每隔一段时间,都会出现一些不包含在基本词汇里面的新形式、新语义的词语,称之为新词(new word)或者未登录词。例如,一些网络热门用语、人名、地名、品牌名等等。准确的识别出新词对于分词的效果有着重要的影响,没有识别出新词可能会导致将新词切分成两个词语,语义发生变化。目前,自动发现新词成为解决这一问题的重要环节之一。

要想从一段文本中准确的提取出一个词,首先要考虑的问题就是,什么样的文本片段可以被视为一个词语,可以通过以下几种衡量方式:

概率统计

一种很自然简单的方法就是,看这个文本片段出现的频率是否足够高。如果一个文本片段在语料中出现的次数越多,那么它是一个词语的可能性越高。但是,缺点在于,这不能成为唯一的判断标准,存在例外情况。例如,"的电影"相比于"电影院"出现的概率高,但是我们更倾向于认为"电影院"是一个词。

计算凝固度

凝固度,主要用来衡量词语内部各个组成部分之间的紧密程度。例如,"的电影"和"电影院"相比,后者的凝固度更高。在计算方法上,使用PMI来衡量词搭配和关联性,计算方式如下:

设有文本片段x和文本片段y,则文本片段xy的PMI为

若PMI较高,则意味着两个文本片段一起出现的概率远大于两个文本片段自由组合的概率,说明这两个文本片段关联性很高。例如,凝合程度最高的文本片段就是诸如"蝙蝠"、"蜘蛛"、"彷徨"、"忐忑"、"玫瑰"之类的词了,这些词里的每一个字几乎总是会和另一个字同时出现,从不在其他场合中使用。如果PMI较小,则这两个文本片段可能只是随机组合在一起,并不是很相关。

为了避免错误的切分方法导致过高地估计该片段的凝合程度,我们需要枚举它的凝合方式并计算PMI,取其中的最小值作为该文本片段的PMI。

表示从位置i到位置j的文本片段

例如,令 p(电影院) 为文本片段"电影院"在整个语料中出现的概率,那么我们定义"电影院"的凝合程度就是

计算自由度

光看文本片段内部的凝合程度还不够,我们还需要从整体来看它在外部的表现。举例,有"被子"和"辈子"两个片段。文本"被子"的用法比较多,比如"买被子"、"盖被子"、"进被子"、"好被子"、"这被子"等等。但是文本"辈子"的用法却非常固定,除了"一辈子"、"这辈子"、"上辈子"、"下辈子",基本上没有其他的用法。和"被子"相比,"辈子"左边可能出现的字比较有限,因此可以认为片段"辈子"并不单独成词,片段"被子"成词的可能性更高。

由此可见,文本片段的自由运用程度也是判断它是否成词的重要标准。如果一个文本片段能够算作一个词,那么它应该能够灵活地出现在各种不同的环境中,具有非常丰富的左邻字集合和右邻字集合。

这种"丰富性"在计算上采用"信息熵"来度量,计算方法如下图所示。系统x内部有一些事件,如果事件出现的概率越大,则发生时带来的信息量越小,如果出现的概率越小,则发生时带来的信息量越大。

计算词语的左右邻字的信息熵时,表示左(或右)邻字出现某字符的事件概率。举例,考虑语料"吃葡萄不吐葡萄皮不吃葡萄倒吐葡萄皮"中"葡萄"一词左邻字分别为 {吃, 吐, 吃, 吐} ,右邻字分别为 {不, 皮, 倒, 皮} 。根据公式,"葡萄"一词的左邻字的信息熵为

当左右邻字的信息熵越大,则说明不确定性越大,信息量越丰富,越有可能是一个新词。举例:同样是在语料中出现6000+次的片段"副总裁"和片段"人工智",它们的左邻字信息熵都在6左右,但"副总裁 "的右邻字包括 { "张","王","说", ...... } 等147个词,而"人工智 "的右邻字只有 { "能","障" } 两种,"副总裁 "的右邻字信息熵远大于"人工智"。显然"副总裁 "相对于"人工智"更有可能成为一个词。

Matrix67取一个文本片段的左邻字信息熵和右邻字信息熵中的较小值的为它的自由度。

总结

最终,把文本中出现过的所有长度不超过 d 的子串都当作潜在的词,再为出现频数、凝固程度和自由程度各设定一个阈值,然后只需要提取出所有满足阈值要求的候选词作为新词即可。

参考

相关推荐
炒空心菜菜34 分钟前
MapReduce 实现 WordCount
java·开发语言·ide·后端·spark·eclipse·mapreduce
wowocpp3 小时前
spring boot Controller 和 RestController 的区别
java·spring boot·后端
后青春期的诗go3 小时前
基于Rust语言的Rocket框架和Sqlx库开发WebAPI项目记录(二)
开发语言·后端·rust·rocket框架
freellf3 小时前
go语言学习进阶
后端·学习·golang
全栈派森5 小时前
云存储最佳实践
后端·python·程序人生·flask
CircleMouse5 小时前
基于 RedisTemplate 的分页缓存设计
java·开发语言·后端·spring·缓存
獨枭6 小时前
使用 163 邮箱实现 Spring Boot 邮箱验证码登录
java·spring boot·后端
维基框架6 小时前
Spring Boot 封装 MinIO 工具
java·spring boot·后端
秋野酱6 小时前
基于javaweb的SpringBoot酒店管理系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
☞无能盖世♛逞何英雄☜7 小时前
Flask框架搭建
后端·python·flask