古詩詞大全網 - 成語故事 - 如何使用ictclas分詞系統進行分詞

如何使用ictclas分詞系統進行分詞

ICTCLAS分詞系統是個NB的系統,這幾天找到了仔細試了試,效率奇高,比自己搞字典,分詞算法效率不知高了很多倍,用起來也是非常簡單的,BOSS需要導出自定義詞庫,然後用文章訓練詞庫,不管了,反正可以使用了。DT地用hash做了兩個星期,進度很慢,分析壹本《天龍八部》,統計出現的詞語頻率(詞語只是僅僅基於頻率,在並沒有字典的情況下無法實現智能分詞!)大概要花費十幾分鐘,可見效率底下,而且內存200M左右。使用ICTCLAS分詞系統可以高效地實現分詞。下面把過程貼出來。

使用方法,首先到網上下載ICTCLAS,因為我是windows下的C++實現, 下載ICTCLAS2011_Windows_32_c,解壓,裏面有很好的Demo,Doc,copy API目錄下的所有文件(夾)到妳所在的工程,在妳的源文件加上

#include "ICTCLAS50.h"

#pragma comment(lib, "ICTCLAS50.lib") //ICTCLAS50.lib庫加入到工程中

//

//your code here,可參考Demo裏面的代碼

//

即可。

大概的函數C++函數接口都在Doc文件下的文檔中:

bool ICTCLAS_Init(const char* pszInitDir=NULL);初始化函數

返回值

如果初始化成功返回true, 否則返回false. 如初始化不成功,請查看ictclas.log文件了解詳細錯誤原因.

參數

pszInitDir:初始化路徑,應包含配置文件(Configure.xml)和詞典目錄(Data目錄)以及授權文件(user.lic). 如果這些文件及目錄在系統運行當前目錄下,此參數可以為null。

bool ICTCLAS_Exit( );退出,釋放內存

返回值

成功返回true;否則返回false。

unsigned int ICTCLAS_ImportUserDict(const char *sFilename,eCodeType eCT)

//導入用戶自定義詞典

返回值

導入成功的詞的個數

參數

sFilename: 用戶定義詞典文件

eCT:編碼格式

int ICTCLAS_ParagraphProcess(const char *sParagraph,int nPaLen,eCodeType eCt,int bPOStagged,char* sResult);//對壹段文字進行分詞

返回值

返回結果緩沖區的指針(sResult)以及結果的長度R

參數

sParagraph: 原始文字段

nPaLen: 文字段的長度

eCodeType: 文字段的編碼格式

bPOStagged: 需不需要根據標註集做標記 0 = 做標記 ; 1 = 不標記; 默認為1.

sResult: 輸出結果

t_pstRstVec ICTCLAS_ParagraphProcessA(const char *sParagraph,int PaLen,eCodeType eCodeType,int bPOStagged,int &nRstCnt);

//處理文字段

返回值

結果vector的指針,系統調用,用戶無法分配以及釋放

struct stResult{

int start; //start position

int length; //length

#ifdef POS_TAGGER

int iPOS; //POS

char sPOS[POS_SIZE];//word type

#endif

int word_ID; //word_ID

int word_type; //Is the word of the user's dictionary?(0-no,1-yes)

int weight;// word weight

};

參數

sParagraph: 原始文字段

nPaLen: 文字段長度

eCodeType: 編碼格式

bPOStagged:

需不需要根據標註集做標記 0 = 做標記 ; 1 = 不標記; 默認為1.

nRstcnt: 處理結果的長度值。

詳細用法參見Doc文件。

bool ICTCLAS_FileProcess(const char *sSrcFilename,eCodeType eCt,const char *sDsnFilename,int bPOStagged);//處理txt文件

返回值

處理文本文件成功返回true, 否則返回false

參數

sSourceFilename: 原始處理文件

eCodeType: 原始文件編碼格式

sDsnFilename: 存儲結果的文件名T

bPOStagged: 需不需要根據標註集做標記 0 = 做標記 ; 1 = 不標記; 默認為1.

註意事項

調用此函數之前需要調用init函數成功,輸出格式可以通過ICTCLAS 配置來更改,這個需要研究下配置文件。

int ICTCLAS_SetPOSmap(int nPOSmap);//設置標註集

返回值

成功為1,其他為0

參數

nPOSmap :

ICT_POS_MAP_FIRST 計算所壹級標註集

ICT_POS_MAP_SECOND 計算所二級標註集 PKU_POS_MAP_SECOND 北大二級標註集 PKU_POS_MAP_FIRST 北大壹級標註集

int ICTCLAS_GetWordId(const char *sWord,int nWrdLen,eCodeType eCT);

返回值

單詞的ID(我覺得是詞典裏面的存儲位置,不清楚詞典的具體結構)

參數

sWord: 目標單詞

nWrdLen: 單詞長度

eCodeType: 編碼格式

bool ICTCLAS_ResultFree ( t_pstRstVec pRetVec)

//釋放調用ICTCLAS_ParagraphProcessAW得到的vector指針

返回值

成功為1,失敗為0

參數

t_pstRstVec: ICTCLAS_ParagraphProcessAW得到的vector指針

總結:這些函數都很好用,我需要使用處理文件函數ICTCLAS_FileProcess我出現的問題是:單獨調用這個函數沒有問題,但是在MFC界面調用兩個選擇打開文件路徑和保存結果文件路徑的CFileDialog以後就會出現ICTCLAS_Init初始化失敗!郁悶了半天,查看ICTCLAS.log文件,

Default Path : E:\test_ICTCLAS\test_ICTCLAS\test_ICTCLAS

start lic check.

License succeed!Cannot open user dictionary

E:\test_ICTCLAS\test_ICTCLAS\test_ICTCLAS\Data\UserDict.pdat.

Cannot open file E:\test_ICTCLAS\test_ICTCLAS\test_ICTCLAS\Data\UserDict.map.

Cannot open user dictionary E:\test_ICTCLAS\test_ICTCLAS\test_ICTCLAS\Data\UserDict.pos.

Load dictionary down!

並沒有異常,加載失敗是因為並沒有自定義詞典。

仔細排查,發現bool ICTCLAS_Init(const char* pszInitDir=NULL)有壹個默認的工作路徑,在沒有打開CFileDialog的時候默認的路徑是exe文件執行路徑,但是打開以後若不進行設置,會改變工作路徑!這就是為什麽點擊CFileDialog路徑更改,找不到路徑下的文件,當然無法初始化了!( pszInitDir:初始化路徑,應包含配置文件(Configure.xml)和詞典目錄(Data目錄)以及授權文件(user.lic). 如果這些文件及目錄在系統運行當前目錄下,此參數可以為null)

解決方案:

方案1. 在每次調用CFileDialog打開文件後重新設置工作路徑

方案2. 在程序中使用絕對路徑

方案3. CFileDialog的構造函數有8個參數,平時為了省事壹般只是指定第壹個。其實解決這個問題,只要在第四個參數dwFlags中加上OFN_NOCHANGEDIR即可

我使用第三個方法解決了^_^!後面我會貼出最終分詞的代碼。還有中間碰見的壹些東西(關於cstring LPSCSTR char* const char * UNICODE 和 multibyte我已經被微軟折磨得不行了,無力吐槽,有時間在說吧)!

MOVE ON!