上一篇文章说到经过NShortPath计算后,我们得到了数个候选分词方案,那么这么多个候选分词方案是如何最终成为一个分词结果的呢?其实这个过程是靠OptimumSegment完成的。SharpICTCLAS与ICTCLAS的OptimumSegment过程基本一样没有太大的变化。
1、OptimumSegment的运算过程
经过NShortPath处理后的多个结果首先会经过日期合并策略的处理,这就是前文说的GenerateWord方法完成的功能。在GenerateWord方法中可以看到如下命令:
m_graphOptimum.SetElement(pCur.row, pCur.col, ......);
它的功能就是将所有得到的多个分词方案合并归入一个 m_graphOptimum
属性,如下面的NShortPath运算结果,经过归并后,在 m_graphOptimum
属性中将包含所有红色词。
//==== 原始句子:
王晓平在1月份滦南大会上说的确实在理
//==== NShortPath 初步切分的到的 N 个结果:
始##始, 王, 晓, 平, 在, 1, 月份, 滦, 南, 大, 会上, 说, 的, 确实, 在, 理, 末##末,
始##始, 王, 晓, 平, 在, 1, 月份, 滦, 南, 大会, 上, 说, 的, 确实, 在, 理, 末##末,
始##始, 王, 晓, 平, 在, 1, 月份, 滦, 南, 大, 会上, 说, 的, 确实, 在理, 末##末,
始##始, 王, 晓, 平, 在, 1, 月份, 滦, 南, 大会, 上, 说, 的, 确实, 在理, 末##末,
始##始, 王, 晓, 平, 在, 1, 月, 份, 滦, 南, 大, 会上, 说, 的, 确实, 在, 理, 末##末,
//==== 经过数字、日期合并等策略处理后的 N 个结果:
始##始, 王, 晓, 平, 在, 1月份, 滦, 南, 大, 会上, 说, 的, 确实, 在, 理, 末##末,
始##始, 王, 晓, 平, 在, 1月份, 滦, 南, 大会, 上, 说, 的, 确实, 在, 理, 末##末,
始##始, 王, 晓, 平, 在, 1月份, 滦, 南, 大, 会上, 说, 的, 确实, 在理, 末##末,
始##始, 王, 晓, 平, 在, 1月份, 滦, 南, 大会, 上, 说, 的, 确实, 在理, 末##末,
始##始, 王, 晓, 平, 在, 1月, 份, 滦, 南, 大, 会上, 说, 的, 确实, 在, 理, 末##末,
紧接着对归并后的 m_graphOptimum
进行人名与地名的识别,找出所有可能的人名、地名方案,经过人名、地名识别后的 m_graphOptimum
如下:
//==== 加入对姓名、翻译人名以及地名的识别:
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:末##末
到此为止, m_graphOptimum
包含了所有最终分词结果中可能包含的元素(人名、地名以及NShortPath筛选后所有可能组词方案),Segment类对这个 m_graphOptimum
再次使用NShortPath,并计算出最优结果作为最终的分词方案。
整个过程可从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得到的多个初步分词结果被归并入 m_graphOptimum
,然后经过人名与地名识别过程将所有可能的人名、地名也放入其中,最后通过OptimumSegment方法最终得到分词结果。
来源:http://www.cnblogs.com/zhenyulu/category/85598.html