介绍一种基于角色标注+字词体位法的人名识别方式-Ansj中文分词

28 篇文章 0 订阅
11 篇文章 0 订阅
大家好.最近在做分词.在分词中遇到了各种各样的问题.在这里选择一个比较有意思的与大家分享.
在这里说分词有点老生常谈了.的确.中文分词已经非常成熟了.但是在实体名识别上一直是中文分词的软肋.最近通过对ictclas的学习,和自己的总结.得出了一个还算不错的人名识别系统.

目前这种方式已经开源.大家可以参看:[url]https://github.com/ansjsun/ansj_seg[/url] , 在线测试:[url]http://www.ansj.org/demo/seg.jsp[/url]


主要思路是..先粗分,粗分的办法很多.但是在粗分的时候要尽量减少歧异.
比如

祝海林在孙健的右面!
进过第一步粗分的结果应当为
祝/ 海/ 林/ 在/ 孙/ 健/ 的/ 右面/

在得到以上的粗分序列我们就可以进行进一步分析了
首先我们得准备一些语料库.对其进行训练.
比如语料库里面有如下词

孙强
朱海林
孙海林
祝健
....

因为一般这种语料库在几十万级别.不能一一例举.所以我们拿具有针对这段文本的是个词做分析
利用字体位方式,我们得到如下统计结果

孙 2:1:1 \\戴表 孙 这个字在 2个词中的第1个位置出现了1次
孙 3:1:1
强 2:2:1
朱 3:1:1
海 3:2:2
,,,


得到如上频率后.我们就可以进行人名识别了

下面我尽量用伪代码的方式来进行一次分解

public void recogntion(Term[] terms) {

for (int i = 0; i < terms.length; i++) {
//已名识别从前向后进行识别,4个字,3个字2字人名分别识别
for (int j = 4; j > 1; j--) {
freq = term.getTermNatures().personAttr.getFreq(j, 0);\\取得词位频率
if ((freq > 0) ) {//进行初始化校验.当此字在识别位置出现时
tempTerm = nameFind(i, beginFreq, j);//以序列结构进行人名识别
}
}
}
}

public Term nameFnd(int i , int beginFreq , j){

StringBuilder sb = new StringBuilder();
int undefinite = 0;
skip = false;
PersonNatureAttr pna = null;
int index = 0;
int freq = 0;
double allFreq = 0;
Term term = null;
int i = offe;
for (; i < terms.length; i++) {
// 走到结尾处识别出来一个名字.
term = terms[i] ;
pna = term.getTermNatures().personAttr;
// 在这个长度的这个位置的词频,如果没有可能就干掉,跳出循环
if ((freq = pna.getFreq(size, index)) == 0) {
return null;
}

//增加人名
sb.append(term.getName());
//这个人名的概率计算
allFreq += Math.log(term.getTermNatures().allFreq+1) ;
allFreq += -Math.log((double) (freq));
index++;


if (index == size + 2) {//当达到制定长度后跳出循环
break;
}
}

double score = -Math.log(factory[size]);
score += allFreq ;
double endFreq = 0;
// 开始寻找结尾词,
endFreq = terms[i].getTermNatures().personAttr.end + 1;

//根据上下文.概率进行公司计算
score -= Math.log(endFreq);
score -= Math.log(beginFreq);



term = new Term(sb.toString(), offe, TermNatures.NR);
term.selfScore = score;

//识别出来的人名进行返回
return term;
}

进行如上步骤之后.我么得到了一个二维数组的序列:
如下:

-------->祝
祝海林--->海林

孙建

右面

下一个步骤就是比较 祝海林 和 祝+海林 哪个更像人名的过程了
其实在这里我们已经构成了隐马尔科夫链.通过贝叶斯定理公式:P(A|B)=P(B|A)*P(A)/P(B)
加上频率完全可以正确识别出来我们要找的实体名.
好了大概介绍到这里.有兴趣的朋友可以通过:[url]http://www.ansj.org/[/url] 获取代码.也希望能在这里认识一些志同道合的朋友共同勉励交流
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值