文档章节

一种利用ngram模型来消除歧义的中文分词方法

杨尚川
 杨尚川
发布于 2015/05/06 04:43
字数 998
阅读 5808
收藏 20

这里的歧义是指:同样的一句话,可能有两种或者更多的切分方法,这些切分结果,有的正确,有的不正确。

消除歧义的目的就是从切分结果中挑选切分正确的。

假设我们要切分句子:结婚的和尚未结婚的,使用逆向最大匹配正向最大匹配算法的结果如下:

逆向最大匹配:[结婚, 的, 和, 尚未, 结婚, 的]
正向最大匹配:[结婚, 的, 和尚, 未结, 婚, 的]

再比如,这几块地面积还真不小

逆向最大匹配:[这, 几块, 地, 面积, 还真, 不小]
正向最大匹配:[这, 几块, 地面, 积, 还真, 不小]

这里就出现了歧义现象,这种歧义现象称为交集型歧义。

交集型歧义的特点是,其中的一个字既可以和前面的字结合成词,也可以和后面的字结合成词,如上面所说的和尚未"中就是这样的字,既可以和前面的字结合成“和尚”也可以和后面的字结合成“尚未”。还有“地面积”中的,既可以是地面,也可以是面积

那么我们该选择哪一个分词结果呢?

我们可以利用ngram模型来消除歧义,我们看第一个例子的分词过程:

初始化bigram
bigram初始化完毕,bigram数据条数:1519443

利用bigram为逆向最大匹配算法的分词结果进行评分:

二元模型 结婚:的 获得分值:16.970562
二元模型 和:尚未 获得分值:2.0
二元模型 尚未:结婚 获得分值:1.4142135
二元模型 结婚:的 获得分值:16.970562

逆向最大匹配:[结婚, 的, 和, 尚未, 结婚, 的] : ngram分值=37.35534

利用bigram为正向最大匹配算法的分词结果进行评分:

二元模型 结婚:的 获得分值:16.970562
二元模型 的:和尚 获得分值:3.0

正向最大匹配:[结婚, 的, 和尚, 未结, 婚, 的] : ngram分值=19.970562

最大分值:37.35534, 消歧结果:[结婚, 的, 和, 尚未, 结婚, 的]

接着看第二个例子:

利用bigram为逆向最大匹配算法的分词结果进行评分:

二元模型 地:面积 获得分值:1.7320508

逆向最大匹配:[这, 几块, 地, 面积, 还真, 不小] : ngram分值=1.7320508

利用bigram为正向最大匹配算法的分词结果进行评分:

正向最大匹配:[这, 几块, 地面, 积, 还真, 不小] : ngram分值=0.0

最大分值:1.7320508, 消歧结果:[这, 几块, 地, 面积, 还真, 不小]

这里要解释的是,ngram中的n>1,我们这里取2(bi),我们看到bigram中数据的条数有1519443,bigram需要从人工标注的语料库中提取,提取方法参考word分词项目,bigram中的数据格式如下:

结婚:登记 91
结婚:的 288
地:面积 3
和:尚未 4
尚未:结婚 2
的:和尚 9

表示的含义是在人工标注的语料库中,结婚这个词后面跟着登记这个词的出现次数是91次,结婚这个词后面跟着这个词的出现次数是288次。

如果ngram中的n为3,则数据格式如下:

结婚:的:事情 3
结婚:的:人 4
结婚:的:信念 2
结婚:的:决定 13

表示的含义和bigram一致。

通过分析bigram和trigram,我们知道,在ngram中,n越大,消歧的效果就越好,但是数据也越大,耗费的内存就更多了。

利用ngram模型来消除歧义,依赖人工标注的语料库,利用了统计学的大数定律,这种方法的缺点在于无法处理少见的语言现象,以及无法处理样本覆盖不到的情况。


© 著作权归作者所有

杨尚川

杨尚川

粉丝 1101
博文 220
码字总数 1624053
作品 12
东城
架构师
私信 提问
加载中

评论(14)

杨尚川
杨尚川 博主

引用来自“清风-蓝魔泪”的评论

南京市/长江大桥 or 南京市长/江大桥
以哪种方式来分词,取决于语料库。比如“南京市”后面出现“长江大桥”概率是多少,“南京市长”后面出现“江大桥”概率是多少。
但问题是,语料库如果来统计的话,这2个概率统计出来其实是一样的。前者发生了多少次,后者就发生了多少次。
那这种情况,Ngram是怎么知道应该怎么分词的呢?

引用来自“杨尚川”的评论

这2个概率统计出来是不一样的。语料库中的词是人工分好的。

引用来自“清风-蓝魔泪”的评论

人工统计,比如出现“南京市”的时候,有50次出现了“长江大桥”。很明显,前者出现且后者出现的情况,就是“南京市长江大桥”这个短句出现了50次。而这个短句出现50次的情况下,也代表着“南京市长”出现的时候,“江大桥”出现了50次。这在Ngram里面得到的概率是一样的吧,为什么会不一样呢?

引用来自“杨尚川”的评论

不一样,因为ngram的语料是人工标注的,所以,只有"南京市 长江大桥",而不会有"南京市长 江大桥"。

引用来自“清风-蓝魔泪”的评论

但语料库这种,XX词后面出现YY词出现了多少次,这种最终还是应该靠机器来训练的吧。如果用ML来做,会出现这种情况吗?ML咋弄的哩😆
需要人来做,机器做不了。
清风-蓝魔泪
清风-蓝魔泪

引用来自“清风-蓝魔泪”的评论

南京市/长江大桥 or 南京市长/江大桥
以哪种方式来分词,取决于语料库。比如“南京市”后面出现“长江大桥”概率是多少,“南京市长”后面出现“江大桥”概率是多少。
但问题是,语料库如果来统计的话,这2个概率统计出来其实是一样的。前者发生了多少次,后者就发生了多少次。
那这种情况,Ngram是怎么知道应该怎么分词的呢?

引用来自“杨尚川”的评论

这2个概率统计出来是不一样的。语料库中的词是人工分好的。

引用来自“清风-蓝魔泪”的评论

人工统计,比如出现“南京市”的时候,有50次出现了“长江大桥”。很明显,前者出现且后者出现的情况,就是“南京市长江大桥”这个短句出现了50次。而这个短句出现50次的情况下,也代表着“南京市长”出现的时候,“江大桥”出现了50次。这在Ngram里面得到的概率是一样的吧,为什么会不一样呢?

引用来自“杨尚川”的评论

不一样,因为ngram的语料是人工标注的,所以,只有"南京市 长江大桥",而不会有"南京市长 江大桥"。
但语料库这种,XX词后面出现YY词出现了多少次,这种最终还是应该靠机器来训练的吧。如果用ML来做,会出现这种情况吗?ML咋弄的哩😆
杨尚川
杨尚川 博主

引用来自“清风-蓝魔泪”的评论

南京市/长江大桥 or 南京市长/江大桥
以哪种方式来分词,取决于语料库。比如“南京市”后面出现“长江大桥”概率是多少,“南京市长”后面出现“江大桥”概率是多少。
但问题是,语料库如果来统计的话,这2个概率统计出来其实是一样的。前者发生了多少次,后者就发生了多少次。
那这种情况,Ngram是怎么知道应该怎么分词的呢?

引用来自“杨尚川”的评论

这2个概率统计出来是不一样的。语料库中的词是人工分好的。

引用来自“清风-蓝魔泪”的评论

人工统计,比如出现“南京市”的时候,有50次出现了“长江大桥”。很明显,前者出现且后者出现的情况,就是“南京市长江大桥”这个短句出现了50次。而这个短句出现50次的情况下,也代表着“南京市长”出现的时候,“江大桥”出现了50次。这在Ngram里面得到的概率是一样的吧,为什么会不一样呢?
不一样,因为ngram的语料是人工标注的,所以,只有"南京市 长江大桥",而不会有"南京市长 江大桥"。
清风-蓝魔泪
清风-蓝魔泪

引用来自“清风-蓝魔泪”的评论

南京市/长江大桥 or 南京市长/江大桥
以哪种方式来分词,取决于语料库。比如“南京市”后面出现“长江大桥”概率是多少,“南京市长”后面出现“江大桥”概率是多少。
但问题是,语料库如果来统计的话,这2个概率统计出来其实是一样的。前者发生了多少次,后者就发生了多少次。
那这种情况,Ngram是怎么知道应该怎么分词的呢?

引用来自“杨尚川”的评论

这2个概率统计出来是不一样的。语料库中的词是人工分好的。
人工统计,比如出现“南京市”的时候,有50次出现了“长江大桥”。很明显,前者出现且后者出现的情况,就是“南京市长江大桥”这个短句出现了50次。而这个短句出现50次的情况下,也代表着“南京市长”出现的时候,“江大桥”出现了50次。这在Ngram里面得到的概率是一样的吧,为什么会不一样呢?
杨尚川
杨尚川 博主

引用来自“清风-蓝魔泪”的评论

南京市/长江大桥 or 南京市长/江大桥
以哪种方式来分词,取决于语料库。比如“南京市”后面出现“长江大桥”概率是多少,“南京市长”后面出现“江大桥”概率是多少。
但问题是,语料库如果来统计的话,这2个概率统计出来其实是一样的。前者发生了多少次,后者就发生了多少次。
那这种情况,Ngram是怎么知道应该怎么分词的呢?
这2个概率统计出来是不一样的。语料库中的词是人工分好的。
清风-蓝魔泪
清风-蓝魔泪
南京市/长江大桥 or 南京市长/江大桥
以哪种方式来分词,取决于语料库。比如“南京市”后面出现“长江大桥”概率是多少,“南京市长”后面出现“江大桥”概率是多少。
但问题是,语料库如果来统计的话,这2个概率统计出来其实是一样的。前者发生了多少次,后者就发生了多少次。
那这种情况,Ngram是怎么知道应该怎么分词的呢?
清风-蓝魔泪
清风-蓝魔泪
南京市/长江大桥 or 南京市长/江大桥
以哪种方式来分词,取决于语料库。比如“南京市”后面出现“长江大桥”概率是多少,“南京市长”后面出现“江大桥”概率是多少。
但问题是,语料库如果来统计的话,这2个概率统计出来其实是一样的。前者发生了多少次,后者就发生了多少次。
那这种情况,Ngram是怎么知道应该怎么分词的呢?
杨尚川
杨尚川 博主

引用来自“清风-蓝魔泪”的评论

有几点不明白,还望川哥指点(最近在钻研川哥的分词,感觉受益匪浅)

逆向最大匹配:[结婚, 的, 和, 尚未, 结婚, 的] : ngram分值=37.35534
1.算对应关系的时候,“结婚:的”算了一次,“和:尚未”算了一次,是这样按顺序2个2个算吗,需不需要“的:和”也算一次?如果是bigram,而分出来了3个词,[A,B,C],那算分数的时候,是按照“A:B”来算,还是“B:C”来算?
2.二元模型 结婚:的 获得分值:16.970562,这个分值是怎么算出来的,词典中,只有一个出现次数,是再比上一个什么数字吗?
3.汉字有几个千个字,其中单字,二字,三字,四字都可成词,如果要算某个词之后接哪个词更合适,那这个数据岂不是非常庞大?我看bigram.txt有几千万行,我觉得也只是一部分。那这里的数据是不是不应该存文件?(因为一段时间也需要做更新),这么大的数据,怎么拿来用的,全部放到内存里面,然后搜索吗?
1、需要,AB、BC都算。
2、将日志级别调为DEBUG,运行如下代码,在日志中就能看到计算过程:
代码:
public static void main(String[] args){
String text = "结婚的和尚未结婚的";
ReverseMaximumMatching m = new ReverseMaximumMatching();
List words = m.seg(text);
float score = Bigram.bigram(words);
System.out.println("逆向最大匹配:"+words+" : ngram分值="+score);
}
日志:
二元模型 结婚:的 获得分值:0.024159048
二元模型 和:尚未 获得分值:3.355423E-4
二元模型 尚未:结婚 获得分值:1.6777116E-4
二元模型 结婚:的 获得分值:0.024159048
0.024159048+0.0003355423+0.00016777116+0.024159048=0.04882140946
逆向最大匹配:[结婚, 的, 和, 尚未, 结婚, 的] : ngram分值=0.04882141


3、不是所有汉字的可能组合,而是从人工标注的语料库中提取,所以能做到在相对小的规模下有比较好的效果。因为要考虑分词的速度,所以要全部加载到内存。
清风-蓝魔泪
清风-蓝魔泪
有几点不明白,还望川哥指点(最近在钻研川哥的分词,感觉受益匪浅)

逆向最大匹配:[结婚, 的, 和, 尚未, 结婚, 的] : ngram分值=37.35534
1.算对应关系的时候,“结婚:的”算了一次,“和:尚未”算了一次,是这样按顺序2个2个算吗,需不需要“的:和”也算一次?如果是bigram,而分出来了3个词,[A,B,C],那算分数的时候,是按照“A:B”来算,还是“B:C”来算?
2.二元模型 结婚:的 获得分值:16.970562,这个分值是怎么算出来的,词典中,只有一个出现次数,是再比上一个什么数字吗?
3.汉字有几个千个字,其中单字,二字,三字,四字都可成词,如果要算某个词之后接哪个词更合适,那这个数据岂不是非常庞大?我看bigram.txt有几千万行,我觉得也只是一部分。那这里的数据是不是不应该存文件?(因为一段时间也需要做更新),这么大的数据,怎么拿来用的,全部放到内存里面,然后搜索吗?
杨尚川
杨尚川 博主

引用来自“ZHAOXJMAIL”的评论

最近也在学习这方面知识,谢谢!
Not at all.
Java中文分词组件 - word分词

Java分布式中文分词组件 - word分词 word分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。能准确识别英文、数字,以及日期、时间等数...

杨尚川
2014/04/29
24.9K
56
Java 中文分词组件 word 分词 v1.0 发布了

word分词是一个Java实现的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名等未登录...

杨尚川
2014/05/01
2.4K
9
Java分布式中文分词组件--word

word分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名...

杨尚川
2014/04/26
8.3K
1
中文分词算法 之 基于词典的全切分算法

在使用 基于词典 的分词方法的时候,如果我们解决了下面4个问题: 1、如何把一句话中所有的词找出来呢?只要词典中有就一定要找出来。 2、如何利用1中找出来的词组合成完整的句子?组合成的句...

杨尚川
2015/05/09
4.2K
2
Java分布式中文分词组件word分词v1.2发布

word分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名...

杨尚川
2015/04/11
5.9K
5

没有更多内容

加载失败,请刷新页面

加载更多

作为一个(IT)程序员!聊天没有话题?试试这十二种技巧

首先呢?我是一名程序员,经常性和同事没话题。 因为每天都会有自己的任务要做,程序员对于其他行业来说;是相对来说比较忙的。你会经常看到程序员在发呆、调试密密麻麻代码、红色报错发呆;...

小英子wep
54分钟前
10
0
【SpringBoot】产生背景及简介

一、SpringBoot介绍 Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程,该框架使用了特定的方式来进行配置,从而使开发人员不再需要...

zw965
今天
4
0
简述并发编程分为三个核心问题:分工、同步、互斥。

总的来说,并发编程可以总结为三个核心问题:分工、同步、互斥。 所谓分工指的是如何高效地拆解任务并分配给线程,而同步指的是线程之间如何协作,互斥则是保证同一时刻只允许一个线程访问共...

dust8080
今天
6
0
OSChina 周四乱弹 —— 当你简历注水但还是找到了工作

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @花间小酌 :#今日歌曲推荐# 分享成龙的单曲《男儿当自强》。 《男儿当自强》- 成龙 手机党少年们想听歌,请使劲儿戳(这里) @hxg2016 :刚在...

小小编辑
今天
3.2K
22
靠写代码赚钱的一些门路

作者 @mezod 译者 @josephchang10 如今,通过自己的代码去赚钱变得越来越简单,不过对很多人来说依然还是很难,因为他们不知道有哪些门路。 今天给大家分享一个精彩的 GitHub 库,这个库整理...

高级农民工
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部