ICTCLAS分詞系統研究(一)
ICTClAS分詞系統是由中科院計算所的張華平、劉群所開發的一套獲得廣泛好評的分詞系統,難能可貴的是該版的Free版開放了原始碼,為我們很多初學者提供了寶貴的學習材料。
但有一點不完美的是,該原始碼沒有配套的文件,閱讀起來可能有一定的障礙,尤其是對C/C++不熟的人來說.本人就一直用Java/VB作為主要的開發語言,C/C++上大學時倒是學過,不過工作之後一直沒有再使用過,語法什麼的忘的幾乎一乾二淨了.但語言這東西,基本的東西都相通的,況且Java也是在C/C++的基礎上形成的,有一定的相似處.閱讀一遍原始碼,主要的語法都應該不成問題了.
雖然在ICTCLAS的系統中沒有完整的文件說明,但是我們可以通過查閱張華平和劉群發表的一些相關論文資料,還是可以窺探出主要的思路.
該分詞系統的主要是思想是先通過CHMM(層疊形馬爾可夫模型)進行分詞,通過分層,既增加了分詞的準確性,又保證了分詞的效率.共分五層,如下圖一所示:
基本思路:先進行原子切分,然後在此基礎上進行N-最短路徑粗切分,找出前N個最符合的切分結果,生成二元分詞表,然後生成分詞結果,接著進行詞性標註並完成主要分詞步驟.
下面是對原始碼的主要內容的研究:
1.首先,ICTCLAS分詞程式首先呼叫CICTCLAS_WinDlg::OnBtnRun()開始程式的執行.並且可以從看出它的處理方法是把源字串分段處理。並且在分詞前,完成詞典的載入過程,即生成m_ICTCLAS物件時呼叫建構函式完成詞典庫的載入。關於詞典結構的分析,請參加分詞系統研究(二)。
void CICTCLAS_WinDlg::OnBtnRun()
{
......
//在此處進行分詞和詞性標記
if(!m_ICTCLAS.ParagraphProcessing((char *)(LPCTSTR)m_sSource,sResult))
m_sResult.Format("錯誤:程式初始化異常!");
else
m_sResult.Format("%s",sResult);//輸出最終分詞結果
......
}
2.在OnBtnRun()方法裡面呼叫分段分詞處理方法bool CResult::ParagraphProcessing(char *sParagraph,char *sResult)完成分詞的整個處理過程,包括分詞的詞性標註.其中第一個引數為源字串,第二個引數為分詞後的字串.在這兩個方法中即完成了整個分詞處理過程,下面需要了解的是在此方法中,如何呼叫其它方法一步步按照上圖所示的分析框架完成分詞過程.為了簡單起見,我們先不做未登入詞的分析。
//Paragraph Segment and POS Tagging
bool CResult::ParagraphProcessing(char *sParagraph,char *sResult)
{
........
Processing(sSentence,1); //Processing and output the result of current sentence.
Output(m_pResult[0],sSentenceResult,bFirstIgnore); //Output to the imediate result
.......
}
3.主要的分詞處理是在Processing()方法裡面發生的,下面我們對它進行進一步的分析.
bool CResult::Processing(char *sSentence,unsigned int nCount)
{
......
//進行二叉分詞
m_Seg.BiSegment(sSentence, m_dSmoothingPara,m_dictCore,m_dictBigram,nCount);
......
//在此處進行詞性標註
m_POSTagger.POSTagging(m_Seg.m_pWordSeg[nIndex],m_dictCore,m_dictCore);
......
}
4.現在我們先不管詞性標註,把注意力集中在二叉分詞上,因為這個是分詞的兩大關鍵步驟的第一步.
參考文章:
1.<<基於層疊隱馬模型的漢語詞法分析>>,劉群 張華平等
2.<<基於N-最短路徑的中文詞語粗分模型>>,張華平 劉群