中文分词之姓名标注

前言:

谈到中文分词,前些年我可能感觉有点可望而不可即,不过现在倒是有这个自信和大家吹吹水了。不久前根据自己已有的原材料写了一个分词并标注姓名的小程序,因为和ictclas有些不同,故此分享出来。ictclas被研究的很多了,我没有去看源码,看了几个不同版本的分析;因为之前也看过《算法导论》和《数据结构》,倒是没有什么理解上的困难。他大体分为4个主要步骤:原子切分、top-N最优路径粗切分、未登陆此识别(姓名的识别就含在此内了)、二元优化切分,数据结构则是采用的字典hash+二叉树。

ictclas的词性标注

先介绍一篇博文 http://blog.csdn.net/dancefire/article/details/1606603 《中科院中文分词系统ICTCLAS之人名识别词典分析》。这姓名标记方法中,咋一看还是有些复杂:步骤很多,需要考虑情况很多。但是分词中用到的知识是很有限的:某一些词的后面比较容易出现姓名(如:他某某),某一些的前面比较容易出现姓名(如:某某),利用这一转移概率使用HMM对各种切分进行评判,选出最可能切分方法。由于ictclas的版本已经更新了n个版本,前人们指出的问题,可能已经做了不少改进。为了让大家对ictclas有一个简要了解,这里贴一幅图(从http://wenku.baidu.com/view/bbe58e4d2b160b4e767fcfbf.html 上面截的):



我的标记方法:

我的这一方法和上面介绍的略有不同,如果非得说出什么道道来,那就比较接近贝叶斯分类。这个方法中我是用了两本词典:第一本就是普通的词语词典,也就是一般用于top-N最优路径切分的词典;第二本则是姓名的词典:选取了几千万个中文的姓名作为统计样本,得到了每一个字的频率和位置。

姓名切分: 所有名字都统一划分为三个部分,姓氏、中间部分【单名的中间部分为空】、名的末部分。

最优路径查找:以"这一章是我写的"为例句。当看到“章”字是个姓,就有可能“章是”、“章是我”是一个名字。

1、当“章是”为名最优路线:“这一”最优切分的概率*1个人姓“章”的概率*名中间部分为空的概率*以“是”作为名末部分的概率*“的牌”的最优切分概率。

2、以“章是”为名的基准参考路线:“这一”最优切分的概率*单字中“章”字出现的概率*单字中“是”出现的概率*“的牌”的最优切分概率。

3、“章”不做姓的最优路线:"这一张是我的牌"的普通的最优切分概率。

【注释】 单字“章”的概率是指统计文本内“章”的字频数除以统计的汉字个数。因为姓名中的概率都是考虑独立的字,消除不对称姓。

如果2的概率大于1的,则说明一个语句中出现“张”再出现“是”的概率要大于一个人姓“张”同时取名叫“是”的概率,因此不把“张是”当做名字。

如果3的概率大于1的,则说明直接普通切分最合适(一种常见情况是“章”与前面成词)。

当然我们还要考虑“章是我”是名字的情况,这里边不赘述。我们使用到了三部分信息:

1、姓名中的汉字的使用频率

2、汉字的使用频率

3、各个词语的使用频率(这由分词字典给出,当然汉字使用的频率也可从中统计出来)

这一个方法的实现效果我也做了几次测试:从红楼梦中选取了2个章节,把主要人物的名字换成了数据库里的普通姓名(共250处),然后把这些替换过的句子拿来做切分,考察其正确率与召回率。发生了一件有意思的事情。

当我的姓名字典是从百万级别的姓名中统计出来时,召回率只有71%,但是当我把姓名的统计样本增加十倍后,召回率达到了91.6%,正确率接近93%。呵呵,量变引起质变,更多的研究就没有进行了(资源有限)。


原理讲解:

其实上面案例中最核心的问题是“章是”是名字的概率是多少?

第一种求解:

文本中“章”是姓的概率*以单名“是”命名的概率。

第二种求解:

假设文本中名字出现的概率为a;一个名字刚好命名为“章是”的概率是多少?(设为p1)当不是名字的时候出现“章是”的概率是多少?(设为p2)那么文本中“章是”出现的概率为 a*p1+(1-a)*p2,其中名字的概率为a*p1;所以“章是”是名字的概率是a*p1/(a*p1+(1-a)*p2)。

计算方法中使用的便是第二种求解,因为一个文本人名出现的概率并不是很容易统计,而且受到文章性质影响非常大,因而直接忽略了名字出现的概率a(或者说随便取了个1/2),这里当然便是此方法的一个优化点。不过当我们把完整的不同词性之间的转移概率考虑进来时,a应当表示“一”这个数字后面接上一个名字的概率了。而我在实际中也把“章是”不是名字的情况简化为“章”字与“是”字偶然碰在一起的概率(而且假定了这两个字没有关系)以减少复杂性。

为什么不用第一种方法求解呢?因为文本中这个“章”姓的概率可是非常不好统计的。本来文本出现的名字就少,还要出现“章”字就更少了,(想来想去也就想到一个“章子怡”,再说还有更偏僻的“姓”),几乎不可能实现。


结语:

一直想搞一个不依赖字典的分词算法,有一些想法,但是没什么好的语料。写到这儿头也有点儿晕了,如果有什么错误,请指正。


©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页