|
上一篇文章说到经过NShortPath计算后,我们得到了数个候选分词方案,那么这么多个候选分词方案是如何最终成为一个分词结果的呢?其实这个过程是靠OptimumSegment完成的。SharpICTCLAS与ICTCLAS的OptimumSegment过程基本一样没有太大的变化。 1、OptimumSegment的运算过程经过NShortPath处理后的多个结果首先会经过日期合并策略的处理,这就是前文说的GenerateWord方法完成的功能。在GenerateWord方法中可以看到如下命令:
它的功能就是将所有得到的多个分词方案合并归入一个
经过NShortPath处理后的初步分词结果
//==== 原始句子:
王晓平在1月份滦南大会上说的确实在理 //==== NShortPath 初步切分的到的 N 个结果: 始##始, 王, 晓, 平, 在, 1, 月份, 滦, 南, 大, 会上, 说, 的, 确实, 在, 理, 末##末, 始##始, 王, 晓, 平, 在, 1, 月份, 滦, 南, 大会, 上, 说, 的, 确实, 在, 理, 末##末, 始##始, 王, 晓, 平, 在, 1, 月份, 滦, 南, 大, 会上, 说, 的, 确实, 在理, 末##末, 始##始, 王, 晓, 平, 在, 1, 月份, 滦, 南, 大会, 上, 说, 的, 确实, 在理, 末##末, 始##始, 王, 晓, 平, 在, 1, 月, 份, 滦, 南, 大, 会上, 说, 的, 确实, 在, 理, 末##末, //==== 经过数字、日期合并等策略处理后的 N 个结果: 始##始, 王, 晓, 平, 在, 1月份, 滦, 南, 大, 会上, 说, 的, 确实, 在, 理, 末##末, 始##始, 王, 晓, 平, 在, 1月份, 滦, 南, 大会, 上, 说, 的, 确实, 在, 理, 末##末, 始##始, 王, 晓, 平, 在, 1月份, 滦, 南, 大, 会上, 说, 的, 确实, 在理, 末##末, 始##始, 王, 晓, 平, 在, 1月份, 滦, 南, 大会, 上, 说, 的, 确实, 在理, 末##末, 始##始, 王, 晓, 平, 在, 1月, 份, 滦, 南, 大, 会上, 说, 的, 确实, 在, 理, 末##末, 紧接着对归并后的
加入人名、地名识别
//==== 加入对姓名、翻译人名以及地名的识别:
row: 0, col: 1, eWeight: 329805.00, nPOS: 1, sWord:始##始 row: 1, col: 2, eWeight: 218.00, nPOS: 0, sWord:王 row: 1, col: 4, eWeight: 10.86, nPOS: -28274, sWord:未##人 row: 2, col: 3, eWeight: 9.00, nPOS: 0, sWord:晓 row: 2, col: 4, eWeight: 13.27, nPOS: -28274, sWord:未##人 row: 3, col: 4, eWeight: 271.00, nPOS: 0, sWord:平 row: 4, col: 5, eWeight: 78484.00, nPOS: 0, sWord:在 row: 5, col: 7, eWeight: 0.00, nPOS: -29696, sWord:未##时 row: 5, col: 8, eWeight: 0.00, nPOS: -29696, sWord:未##时 row: 7, col: 8, eWeight: 1234.00, nPOS: 0, sWord:份 row: 8, col: 9, eWeight: 1.00, nPOS: 27136, sWord:滦 row: 8, col: 10, eWeight: 20.37, nPOS: -28275, sWord:未##地 row: 9, col: 10, eWeight: 813.00, nPOS: 0, sWord:南 row: 10, col: 11, eWeight: 14536.00, nPOS: 0, sWord:大 row: 10, col: 12, eWeight: 1333.00, nPOS: 28160, sWord:大会 row: 11, col: 13, eWeight: 469.00, nPOS: 0, sWord:会上 row: 12, col: 13, eWeight: 23706.00, nPOS: -27904, sWord:未##数 row: 13, col: 14, eWeight: 17649.00, nPOS: 0, sWord:说 row: 14, col: 15, eWeight: 358156.00, nPOS: 0, sWord:的 row: 15, col: 17, eWeight: 361.00, nPOS: 0, sWord:确实 row: 17, col: 18, eWeight: 78484.00, nPOS: 0, sWord:在 row: 17, col: 19, eWeight: 3.00, nPOS: 24832, sWord:在理 row: 18, col: 19, eWeight: 129.00, nPOS: 0, sWord:理 row: 19, col: 20, eWeight:2079997.00, nPOS: 4, sWord:末##末 到此为止, 整个过程可从WordSegment类的Segment方法看出,SharpICTCLAS中该方法定义如下(经过简化):
分词主程序
public List<WordResult[]> Segment(string
sentence, int nKind)
{ m_pNewSentence = Predefine.SENTENCE_BEGIN + sentence + Predefine.SENTENCE_END; //---初步分词 int nResultCount = m_Seg.BiSegment(m_pNewSentence, m_dSmoothingPara, nKind); //---人名、地名识别 for (int i = 0; i < nResultCount; i++) { m_uPerson.Recognition(m_Seg.m_pWordSeg[i], m_Seg.m_graphOptimum, ......); m_uTransPerson.Recognition(m_Seg.m_pWordSeg[i], m_Seg.m_graphOptimum, ......); m_uPlace.Recognition(m_Seg.m_pWordSeg[i], m_Seg.m_graphOptimum, ......); } //---最终优化 m_Seg.BiOptimumSegment(1, m_dSmoothingPara); //---词性标注 for (int i = 0; i < m_Seg.m_pWordSeg.Count; i++) m_POSTagger.POSTagging(m_Seg.m_pWordSeg[i], m_dictCore, m_dictCore); return m_Seg.m_pWordSeg; } 2、人名与地名的识别ICTCLAS中人名的识别采用的是模板匹配的方法,首先对初步分词得到的多的结果计算词性,然后根据词性串对人名信息进行匹配。整个运算过程如下: 首先定义了人名匹配模板:
人名识别模板
string[] sPatterns = {
"BBCD",
"BBC",
"BBE",
"BBZ",
"BCD",
"BEE", "BE", "BG", "BXD", "BZ", "CDCD", "CD", "EE", "FB", "Y", "XD", "" }; /*------------------------------------ The person recognition patterns set BBCD:姓+姓+名1+名2; BBE: 姓+姓+单名; BBZ: 姓+姓+双名成词; BCD: 姓+名1+名2; BE: 姓+单名; BEE: 姓+单名+单名;韩磊磊 BG: 姓+后缀 BXD: 姓+姓双名首字成词+双名末字 BZ: 姓+双名成词; B: 姓 CD: 名1+名2; EE: 单名+单名; FB: 前缀+姓 XD: 姓双名首字成词+双名末字 Y: 姓单名成词 ------------------------------------*/ 然后将初步分词得到的结果进行词性标注,清理掉其它不必要的信息后进行模板匹配得到人名:
人名识别过程
//==== 经过初步分词后的一个结果集
始##始, 王, 晓, 平, 在, 1月份, 滦, 南, 大, 会上, 说, 的, 确实, 在, 理, 末##末, //==== 经过计算得到的m_nBestTag 始##始, 王, 晓, 平, 在, 1月份, 滦, 南, 大, 会上, 说, 的, 确实, 在, 理, 末##末, B C D M A A A A A A A A A A //==== 经过模板匹配后识别出来的人名 王晓平 地名的识别与此类似,就不再多说。有关人名、地名识别的进一步内容可以参考:http://qxred.yculblog.com/post.1204714.html;《ICTCLAS 中科院分词系统 代码 注释 中文分词 词性标注》作者:风暴红QxRed 。
经过NShortPath得到的多个初步分词结果被归并入
|