用双向最大匹配法进行中文分词

来源:互联网 发布:linux网页编程工具 编辑:程序博客网 时间:2024/05/21 17:07

用双向最大匹配法进行中文分词


问题情况

中文分词任务,采用的是Sighan2004(backoff2005微软数据)数据。给出训练集和测试集,对测试集进行中文分词,要求给出的分词结果F-score尽量大。


常见解法

1.正向(逆向)最大匹配

以选出匹配的单词尽可能长为目标分词,具体操作是从一个方向不断尝试匹配出最长单词,再进行下一次匹配,直到匹配完成为止。

2.双向最大匹配

同样以选出匹配的单词尽可能长为目标分词,具体操作可以给分词结果打分,找一个合适的打分函数下,匹配单词较长则比较合算,同时希望求解打分函数最大值的复杂度比较低。

3.最大熵模型

4.CFR方法


常见优化

1.数字和百分号小数点

因为希望从12米学习出2米,所以应该把12米和2米都弄成米,是一个占位符。
需要注意全角半角问题,本组数据所有的字符全部是全角的。

2.人名地名

这个优化我做不太会做。感觉要识别出人名地名涉及到命名实体识别,这就很困难。


我的解法

我尝试了正向最大匹配法(V1)和双向最大匹配法(V2),都加了数字和百分号小数点的优化。

1.正向最大匹配法(V1)

用训练集训练出一个字典。
对于测试集句子,从一个方向不断尝试匹配出最长单词,再进行下一次匹配,直到匹配完成为止。

2.双向最大匹配(V2)

用训练集训练出一个字典并统计词频率。

对于测试集句子
设某一个分词结果 x(sentence) = (word_1, word_2, …, word_n)
得分 score(x) = LENGTH_VALUE × score1(x) + score2(x)

其中score1(x)考虑匹配单词长度的得分,需要满足匹配越大分词结果得分越高。
我取score1(x) = sum{len(word_i)^2} (i = 1, 2, …, n )

其中score2(x)考虑匹配单词常见程度的得分,需要满足词频率越大的分词结果得分越高。
我取score2(x) = sum{log(times(word_i))} (i = 1, 2, …, n )

对于不在词典里的单词,可以score()给一个惩罚性分数,也可以根据剩下的单词长短给一个比较低的score1(x),我不太清楚怎么设置分数比较合理,所以直接给了0分。LENGTH_VALUE是一个系数,用于控制两部分得分的权重,取一个合适的值,我通过调参决定它的取值。

然后求解分词方案θ令 score(θ) = max{score(x(sentence))}

求解score(sentence)最大值可以使用动态规划方法,可以设f(l,r)是sentence(l,r)这个子句的得分最大值,那么可以用动态规划求解f(l,r),求解同时记下局部最优解转移时候分词位置即可求解出θ。

本来修改一下不同的score函数和比重调一调参数应该可以得到一个相对比较好的结果,

但是由于动态规划时间复杂度是O(len^2)的,对于长句子开销还是不小的,加上log()计算耗时也比较久,所以算法耗时比较久。所以我没怎么调参,根据我的理解给了一个我觉得合适的参数并微调了一下。


测试结果

模型 F-score 正向最大匹配 0.945 双向最大匹配 0.951 最大熵模型(来自网络) 0.839 4-tag+CFR(来自网络,目前最好版本) 0.964
0 0
原创粉丝点击