用CRF++開源工具做文本序列標註教程

用CRF++開源工具做文本序列標註教程

來自專欄自然語言處理

本文只介紹如何快速的使用CRF++做序列標註,對其中的原理和訓練測試參數不做介紹。

官網地址:CRF++: Yet Another CRF toolkit

主要完成如下功能:

輸入 -> "周杰倫是誰"輸出 -> "[周杰倫:artist]是誰"

一、資源準備

下載鏈接中的內容:

鏈接:https://pan.baidu.com/s/16iw3WBSHI1U5U1G_xbikDA 密碼:cfqi

該文件夾裡面包含了以下內容:

1、CRF++-0.58.tar.gz,CRF++開源工具,這個是從CRF++官網上下載的。

2、data文件夾,訓練和測試需要的數據,這個是我自己寫的,其中:

  • input文件夾,存放所需要的數據:

    train_data.txt,訓練數據,這裡只有幾條作為示例,實際工程中,需要上萬條數據;

    test_data.txt,測試數據;

    crf.template,特徵模板。
  • output文件夾 -> 輸出的模型和測試結果。

3、code文件夾,C++調用CRF++介面的代碼示例,這個是我自己寫的。

二、CRF++的編譯

按照如下命令進行:

tar zxvf CRF++-0.58.tar.gzcd CRF++-0.58./configuremakesudo make install

這時候就編譯安裝成功了。

cd /usr/local/bin cd /usr/local/lib

切換到上面這兩個目錄,bin目錄下可以看到crf_learncrf_test兩個可執行程序,分別用於模型的訓練和測試; lib目錄下是生成的CRF++庫。

//備註1:CRF++-0.58/.libs,這個目錄下也有生成上述可執行程序和庫。//備註2:如果不想安裝到上述目錄,或者沒有root許可權,在configure的時候指定安裝目錄即可。

三、模型訓練

按照如下命令進行:

cd CRF++_tutorial/data./train.sh

這樣,我們就得到了模型,即output/crf.mdl文件,這個文件是二進位的沒辦法查看。

train.sh腳本內容如下:

#/usr/local/bin/crf_learn: 前面編譯生成的crf++的訓練工具#input/crf.template: 特徵模板#input/train_data.txt: 訓練數據#output/crf.mdl: 訓練輸出的模型export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/usr/local/bin/crf_learn input/crf.template input/train_data.txt output/crf.mdl

訓練數據格式如下:

四、測試

按照如下命令進行:

cd CRF++_tutorial/data ./test.sh

這樣,我們就得到了預測的結果,即output/test_result.txt文件,可以打開看下預測結果。

test.sh腳本內容如下:

#/usr/local/bin/crf_test: 前面編譯生成的crf++的測試工具#-m output/crf.mdl: train.sh腳本訓練輸出的crf模型#input/test_data.txt: 測試數據#-o output/test_result.txt: 輸出測試結果 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/usr/local/bin/crf_test -m output/crf.mdl input/test_data.txt -o output/test_result.txt

測試數據格式如下(testdata和traindata需要用相同的編碼格式,不然沒法解析):

測試結果如下,雖然訓練數據只有幾條,但測試結果還是挺準的哈:

五、C++介面調用示例

按照如下命令進行:

cd CRF++_tutorial/codecmake .make./crf_test

程序輸出結果如下:

具體調用流程請參考CRF++_tutorial/code/main.cpp

代碼如下:

#include <iostream>#include <string>#include <vector>#include "crfpp.h"using namespace std;int main(){ //> 0.測試輸入 vector<string> query; query.push_back("周"); query.push_back("傑"); query.push_back("倫"); query.push_back("是"); query.push_back("誰"); //> 1.模型載入 cout << ">>>>>> Begin to load crf++ model……" << endl; CRFPP::Model* crf_model_ = CRFPP::createModel("-m ../data/output/crf.mdl -v 3"); cout << ">>>>>> Success to load crf++ model !" << endl; //> 2.創建CRF++對象 CRFPP::Tagger* tagger = crf_model_->createTagger(); //> 3.add query vector<string>::iterator it = query.begin(); for ( ; it != query.end(); it++){ tagger->add((*it).c_str()); } //< 4.對query進行標註 if (!tagger->parse()){ cout << ">>>>>> Fail to parse !" << endl; return -1; } //> 5.列印標註結果 cout << "標註結果: " << endl; for (size_t i = 0; i < tagger->size(); i++){ cout << query[i] << " " << tagger->y2(i) << endl; } return 0;}

推薦閱讀:

分詞 | jiebaR 常用函數
百萬級中文人名語料庫
數學之美第四章談談分詞

TAG:機器學習 | 自然語言處理 | 中文分詞 |