中科院分词系统源码解读

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

中科院分词系统源码解读
1分词
分词时,首先添加“始##始”为句子的开始,循环判断输入字符串每个字节(汉字取两个字节)构成的字符是否是特殊字符(中断符号(,、等),整句符号(。

?!等)),如果找到了中断符号,就开始进行分析,如果找到了整句符号,添加“末##末”为句子结束。

具体分词:
1.1生成网络图
方法:GenerateWordNet()
第一步:原子切词,初始化网络图
首先对输入字符串进行原子切词,记录每个原子的内容,长度,词性
然后对特殊词性做覆盖处理(字符串中的数词替换成“未##数”,字符串中的字母用未##串替换)
第二步:生成网络图
以陈宏刚7月份毕业于交通那个大学,他学习成绩优异。

为例
先找始##始,先分成始##始,在GB2312表中查找始的索引index,再根据索引查找是否存在##始,如果存在,添加始##始到网络图节点,然后查找始的词性,频度,如果词性个数>1,计算总频度,设置词性为0.此时存储的频度,词性,内容(50610,1,始##始)内层循环,然后添加下一个原子陈,此时查找始##始陈,重复上面查找的步骤,此时不存在始##始陈,退出内层循环,进入外层循环。

找陈,分成陈,在GB2312中查找陈的索引,同样根据索引查找是否存在(此时是判断陈是否是单子词),存在,查找词性,词性个数为5,存储(16,0,陈)
内层循环,添加下一个原子宏,没有找到陈宏,退出进入外层循环
找宏,分成宏,在GB2312中查找宏的索引,同样查找是否存在,存在,查找词性,词性个数为3,存储(1,0,宏)
内层循环,添加刚,没有找到宏刚,退出进入外层循环。

找到的网络图如下:
row记录该词的头位置,
col记录该词的末位置
value记录该词的频度,出现的频度指所有该词的所有词性下出现的频度的总和。

nPos记录该词的词性
sWord记录该词
nWordLen记录该词的长度
{row:0,col:1,value:50610.0,nPOS:1,nWordLen:6,sWord:始##始} {row:1,col:2,value:16.0,nPOS:0,nWordLen:2,sWord:陈}
{row:2,col:3,value:1.0,nPOS:0,nWordLen:2,sWord:宏}
{row:3,col:4,value:106.0,nPOS:0,nWordLen:2,sWord:刚}
{row:4,col:5,value:0.0,nPOS:-27904,nWordLen:6,sWord:未##数}
{row:5,col:6,value:0.0,nPOS:0,nWordLen:2,sWord:月}
{row:5,col:7,value:295.0,nPOS:0,nWordLen:2,sWord:月}
{row:6,col:7,value:158.0,nPOS:0,nWordLen:2,sWord:份}
{row:7,col:8,value:7.0,nPOS:0,nWordLen:2,sWord:毕}
{row:7,col:9,value:82.0,nPOS:0,nWordLen:4,sWord:毕业}
{row:8,col:9,value:11.0,nPOS:0,nWordLen:2,sWord:业}
{row:9,col:10,value:1135.0,nPOS:0,nWordLen:2,sWord:于}
{row:10,col:11,value:57.0,nPOS:0,nWordLen:2,sWord:西}
{row:10,col:12,value:40.0,nPOS:0,nWordLen:4,sWord:西安}
{row:11,col:12,value:18.0,nPOS:0,nWordLen:2,sWord:安}
{row:12,col:13,value:134.0,nPOS:0,nWordLen:2,sWord:交}
{row:12,col:14,value:261.0,nPOS:0,nWordLen:4,sWord:交通}
{row:13,col:14,value:56.0,nPOS:0,nWordLen:2,sWord:通}
{row:14,col:15,value:2244.0,nPOS:0,nWordLen:2,sWord:大}
{row:14,col:16,value:273.0,nPOS:0,nWordLen:4,sWord:大学}
{row:15,col:16,value:167.0,nPOS:0,nWordLen:2,sWord:学}
{row:16,col:17,value:74920.0,nPOS:30464,nWordLen:2,sWord :,}
}
1.2生成二叉树
方法:biGraphGenerate()
第一步:利用输入的网络图初始化位置数组(用一个int值记录词所在的行,列)
第二步:设置当前节点的频度,如果是已知词性,直接使用频度,如果是未知词性,从分词词典中检索词组汉字对应句柄为2的频度,第三步:循环添加下一个节点(按照当前节点的列等于下一个节点的行),可能不止一个节点,如果找到了下一个节点,就将当前词与下一个节点的词进行拼接,例如(始##始@陈)在连接词词典里查找频度,然后根据公式计算权重值
公式为:dValue = -Math.log(dSmoothingPara* (1 + dCurFreqency)/ (MAX_FREQUENCE + 80000)+ (1 - dSmoothingPara)
* ((1 - dTemp) * nTwoWordsFreq
/ (1 + dCurFreqency) + dTemp));
其中dSmoothingPara=0.1,dCurFreqency表示当前节点词的频度,MAX_FREQUENCE= 2079997,dTemp=1/2079997,nTwoWordsFreq表示连接词的频度
// -log{a*P(Ci-1)+(1-a)P(Ci|Ci-1)} Note 0<a<1,ci表示当前词,ci-1表示上一个词< p="">
根据当前节点的行,列反向计算出当前节点,下一个节点在位置数组中的位置curIndex,nextIndex,并存储(curIndex,nextIndex,dvalue,当前节点的词性),
得到的二叉树如下图:
{row:0,col:1,value:6.048534288452389,nPOS:1,nWordLen:0,s Word:null}
{row:1,col:2,value:13.616880164573741,nPOS:0,nWordLen:0, sWord:null}
{row:2,col:3,value:14.459323621443533,nPOS:0,nWordLen:0, sWord:null}
{row:3,col:4,value:4.084722509661841,nPOS:0,nWordLen:0,s Word:null}
{row:4,col:5,value:7.00637101347341,nPOS:-
27904,nWordLen:0,sWord:null}
{row:4,col:6,value:7.00637101347341,nPOS:-
27904,nWordLen:0,sWord:null}
{row:5,col:7,value:14.551587593928467,nPOS:0,nWordLen:0, sWord:null}
{row:6,col:8,value:11.166756418425843,nPOS:0,nWordLen:0, sWord:null}
{row:7,col:8,value:11.762180181629445,nPOS:0,nWordLen:0, sWord:null}
{row:6,col:9,value:11.166756418425843,nPOS:0,nWordLen:0,sWo rd:null}
{row:7,col:9,value:11.762180181629445,nPOS:0,nWordLen:0,sWo rd:null}
{row:8,col:10,value:14.03483165350111,nPOS:0,nWordLen:0,sWo rd:null}
{row:9,col:11,value:2.126270488703594,nPOS:0,nWordLen:0,sWo rd:null}
{row:10,col:11,value:13.827330884650781,nPOS:0,nWordLen:0,s Word:null}
{row:11,col:12,value:9.844740295259538,nPOS:0,nWordLen:0,sW ord:null}
{row:11,col:13,value:7.075844400523694,nPOS:0,nWordLen:0,sW ord:null}
{row:12,col:14,value:12.678356682086813,nPOS:0,nWordLen:0,s Word:null}
{row:13,col:15,value:12.969280245959554,nPOS:0,nWordLen:0,s Word:null}
{row:14,col:15,value:13.543711111983676,nPOS:0,nWordLen:0,s Word:null}
{row:13,col:16,value:12.969280245959554,nPOS:0,nWordLen:0,s Word:null}
{row:14,col:16,value:13.543711111983676,nPOS:0,nWordLen:0,s Word:null}
{row:15,col:17,value:11.915988219192224,nPOS:0,nWordLen:0,s Word:null}
{row:16,col:18,value:11.284807155659166,nPOS:0,nWordLen:0,s Word:null}
{row:17,col:18,value:12.693316684795468,nPOS:0,nWordLen:0,s Word:null}
{row:16,col:19,value:4.286497297164445,nPOS:0,nWordLen:0,sW ord:null}
{row:17,col:19,value:12.693316684795468,nPOS:0,nWordLen:0,s Word:null}
{row:18,col:20,value:9.16758722759956,nPOS:0,nWordLen:0,sWo rd:null}
{row:19,col:21,value:2.5828212640296964,nPOS:0,nWordLen:0,s Word:null}
{row:20,col:21,value:3.2831959044621333,nPOS:0,nWordLen:0,s Word:null} }
1.3最短路径
利用vertbi算法计算最短路径(还没仔细看具体计算方法)
计算得到最短路径如下图:
{row:0,col:1,value:50610.0,nPOS:1,nWordLen:6,sWord:始##始}
{row:1,col:2,value:16.0,nPOS:0,nWordLen:2,sWord:陈}
{row:2,col:3,value:1.0,nPOS:0,nWordLen:2,sWord:宏}
{row:3,col:4,value:106.0,nPOS:0,nWordLen:2,sWord:刚}
{row:4,col:7,value:0.0,nPOS:-29696,nWordLen:6,sWord:未##时}
{row:7,col:9,value:82.0,nPOS:0,nWordLen:4,sWord:毕业}
{row:9,col:10,value:1135.0,nPOS:0,nWordLen:2,sWord:于}
{row:10,col:12,value:40.0,nPOS:0,nWordLen:4,sWord:西安}
{row:12,col:14,value:261.0,nPOS:0,nWordLen:4,sWord:交通} {row:14,col:16,value:273.0,nPOS:0,nWordLen:4,sWord:大学} {row:16,col:17,value:74920.0,nPOS:30464,nWordLen:2,sWord :,}
2词性标注
对分好的词进行词性标注
方法:POSTagging()
3人名识别
方法:Recognition()是人名识别的核心方法,其中POSTagging()是角色标注的方法
方法POSTagging()
输入:分好的词,分词词典,未登录词词典
其中最主要的方法是GetFrom(pWordItems, nStartPos, dictCore, dictUnknown); PersonRecognize(dictUnknown);
GetFrom方法是返回的是下一个词的开始位置(下一个词在这指只有一个词性的词)
其中根据GetHandle方法得到词的词性数组,频度数组,然后得到m_nTags;m_dFrequency 数组,这两个数组是为了计算最佳词性GetBestPOS()方法做准备的
GetBestPOS()首先计算出每个节点之前的最佳前驱,然后得到最佳词性数组m_nBestTag,这个过程用到的是Vertibi算法(在计算当前词的最佳词性时,上一个词的词性也是最佳的),有了
m_nBestTag,接下来就可以进行人名识别了。

PersonRecognize()方法定义了几种人名识别模式,将前一步得到的m_nBestTag转化成角色sPOS(与’A’相加得到新的角色),然后对sPOS与识别模式进行最大长度匹配,将匹配成功的开始位置,结束位置存储到m_nUnknownWords中
角色标注结束,对m_nUnknownWords在原分词语句中进行合并处理(名字进行合并)
</a<1,ci表示当前词,ci-1表示上一个词<>。

相关文档
最新文档