用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.gz
cd CRF++-0.58
./configure
make
sudo make install

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

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

切換到上面這兩個目錄,bin目錄下可以看到crf_learn和crf_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/code
cmake .
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;
}

from: https://zhuanlan.zhihu.com/p/39695509


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM