Back to Top

语言技术平台使用文档

编译、使用工具包训练模型、在程序中调用语言技术平台


安装CMake

LTP使用编译工具CMake构建项目。在安装LTP之前,你需要首先安装CMake。CMake的网站在这里。如果你是Windows用户,请下载CMake的二进制安装包;如果你是Linux,Mac OS或Cygwin的用户,可以通过编译源码的方式安装CMake,当然,你也可以使用Linux的软件源来安装。

Windows(MSVC)编译

第一步:构建VC Project

在项目文件夹下新建一个名为build的文件夹,使用CMake Gui,在source code中填入项目文件夹,在binaries中填入build文件夹。然后Configure -> Generate。

win-cmake

或者在命令行build 路径下运行

cmake ..

第二步:编译

构建后得到ALL_BUILD、RUN_TESTS、ZERO_CHECK三个VC Project。使用VS打开ALL_BUILD项目,选择Release方式构建项目。

注:由于boost::multi_array与VS2010不兼容,并不能使用Debug方式构建项目。

Linux,Mac OSX和Cygwin编译

Linux、Mac OSX和Cygwin的用户,可以直接在项目根目录下使用命令

./configure
./make

进行编译。

编译结果

编译成功后,会在./bin文件夹下生成如下一些二进制程序:

程序名 说明
ltp_test LTP调用程序
ltp_server* LTP Server程序

在lib文件夹下生成以下一些静态链接库

程序名 说明
splitsnt.lib 分句lib库
segmentor.lib 分词lib库
postagger.lib 词性标注lib库
parser.lib 依存句法分析lib库
ner.lib 命名实体识别lib库
srl.lib 语义角色标注lib库

同时,在tools/train文件夹下会产生如下一些二进制程序:

程序名 说明
otcws 分词的训练和测试套件
otpos 词性标注的训练和测试套件
lgdpj 依存句法分析训练和测试套件
maxent* 最大熵工具包,用于训练命名实体识别和语义角色标注模型
SRLExtract* 语义角色标注训练程序
SRLGetInstance*

在window版本中ltp_server、Maxent、SRLExtract、SRLGetInstance并不被编译。


模型文件

一般来讲,基于统计机器学习方法构建的自然语言处理工具通常包括两部分,即:算法逻辑以及模型。模型从数据中学习而得,通常保存在文件中以持久化;而算法逻辑则与程序对应。

ltp提供一整套算法逻辑以及模型,其中的模型包括:

模型名 说明
cws.model 分词模型,单文件
pos.model 词性标注模型,单文件
ner.model 命名实体识别模型,单文件
parser.model 依存句法分析模型,单文件
srl_data/ 语义角色标注模型,多文件

使用ltp_test

ltp_test是一个整合ltp中各模块的命令行工具。他完成加载模型,依照指定方法执行分析的功能。ltp_test加载的模型通过配置文件指定。配置文件的样例如下:

segmentor-model = new_ltp_data/cws.model
postagger-model = new_ltp_data/pos.model
parser-model = new_ltp_data/parser.model
ner-model = ltp_data/ner.model
srl-data = ltp_data/srl_data

其中,

  • segmentor-model项指定分词模型
  • postagger-model项指定词性标注模型
  • parser-model项指定依存句法分析模型
  • ner-model项指定命名实体识别模型
  • srl-data项指定语言角色标注模型

ltp_test的使用方法如下:

./bin/ltp_test [配置文件] [分析目标] [待分析文件]

分析结果以xml格式显示在stdout中。关于xml如何表示分析结果,请参考理解Web Service Client结果一节。

使用otcws

otcws是ltp分词模型的训练套件,用户可以使用otcws训练获得ltp的分词模型。

编译之后,在tools/train下面会产生名为otcws的二进制程序。调用方法是

./otcws [config_file]

otcws分别支持从人工切分数据中训练分词模型和调用分词模型对句子进行切分。人工切分的句子的样例如下:

对外      , 他们      代表      国家      。

otcws主要通过配置文件指定执行的工作,其中主要有两类配置文件:训练配置和测试配置。

训练配置的配置文件样例如下所示。

[train]
train-file = data/ctb5-train.seg
holdout-file = data/ctb5-holdout.seg
algorithm = pa
model-name = model/ctb5-seg
max-iter = 5

其中,

  • [train] 配置组指定执行训练
    • Ttain-file 配置项指定训练集文件
    • Holdout-file 配置项指定开发集文件
    • Algorithm 指定参数学习方法,现在otcws支持两种参数学习方法,分别是passive aggressive(pa)和average perceptron(ap)。
    • Model-name 指定输出模型文件名
    • Max-iter 指定最大迭代次数

测试配置的配置文件样例如下所示。

[test]
test-file = data/ctb5-test.seg
model-file = model/ctb5-seg.4.model

其中,

  • [test] 配置组指定执行测试
    • Test-file 指定测试文件
    • Model-file 指定模型文件位置

切分结果将输入到标准io中。

[train]与[test]两个配置组不能同时存在。对于otpos, otner, lgdpj三个工具包同样。

使用otpos

otpos是ltp分词模型的训练套件,用户可以使用otpos训练获得ltp的分词模型。

编译之后,在tools/train下面会产生名为otpos的二进制程序。调用方法是

./otpos [config_file]

otpos分别支持从人工切分并标注词性的数据中训练词性标注模型和调用词性标注模型对切分好的句子进行词性标注。人工标注的词性标注句子样例如下:

对外_v    ,_wp  他们_r    代表_v    国家_n    。_wp

otpos主要通过配置文件指定执行的工作,其中主要有两类配置文件:训练配置和测试配置。

训练配置的配置文件样例如下所示。

[train]
train-file = data/ctb5-train.pos
holdout-file = data/ctb5-holdout.pos
algorithm = pa
model-name = model/ctb5-pos
max-iter = 5

其中,

  • [train] 配置组指定执行训练
    • Ttain-file 配置项指定训练集文件
    • Holdout-file 配置项指定开发集文件
    • Algorithm 指定参数学习方法,现在otcws支持两种参数学习方法,分别是passive aggressive(pa)和average perceptron(ap)。
    • Model-name 指定输出模型文件名
    • Max-iter 指定最大迭代次数

测试配置的配置文件样例如下所示。

[test]
test-file = data/ctb5-test.pos
model-file = model/ctb5-pos.3.model

其中,

  • [test] 配置组指定执行测试
    • Test-file 指定测试文件
    • Model-file 指定模型文件位置

词性标注结果将输入到标准io中。

使用otner

otner是ltp命名实体识别模型的训练套件,用户可以使用otner训练获得ltp的命名实体识别模型。

编译之后,在tools/train下面会产生名为otner的二进制程序。调用方法是

./otner [config_file]

otner分别支持从人工标注的数据中训练命名实体识别模型和调用命名实体识别模型对句子进行标注。人工标注的句子的样例如下:

党中央/ni#B-Ni 国务院/ni#E-Ni 要求/v#O ,/wp#O 动员/v#O 全党/n#O 和/c#O 全/a#O社会/n#O 的/u#O 力量/n#O

Otner主要通过配置文件指定执行的工作,其中主要有两类配置文件:训练配置和测试配置。

训练配置的配置文件样例如下所示。

[train]
train-file = data/ctb5-train.ner
holdout-file = data/ctb5-holdout.ner
algorithm = pa
model-name = model/ctb5-ner
max-iter = 5

其中,

  • [train] 配置组指定执行训练
    • Train-file 配置项指定训练集文件
    • Holdout-file 配置项指定开发集文件
    • Algorithm 指定参数学习方法,现在otner支持两种参数学习方法,分别是passive aggressive(pa)和average perceptron(ap)。
    • Model-name 指定输出模型文件名
    • Max-iter 指定最大迭代次数

测试配置的配置文件样例如下所示。

[test]
test-file = data/ctb5-test.ner
model-file = model/ctb5-ner.4.model

其中,

  • [test] 配置组指定执行测试
    • Test-file 指定测试文件
    • Model-file 指定模型文件位置

命名实体识别结果将输入到标准io中。

使用lgdpj

lgdpj是ltp依存句法分析模型的训练套件,用户可以使用lgdpj训练获得ltp的依存句法分析模型。

编译之后,在tools/train下面会产生名为lgdpj的二进制程序。调用方法是

./lgdpj [config_file]。

lgdpj分别支持从人工标注依存句法的数据中训练依存句法分析模型和调用依存句法分析模型对句子进行依存句法分析。人工标注的词性标注依存句法的句子遵从conll格式,其样例如下:

1     对外    _     v     _     _     4     ADV     _     _
2     ,    _     wp    _     _     1     WP    _     _
3     他们    _     r     _     _     4     SBV     _     _
4     代表    _     v     _     _     0     HED     _     _
5     国家    _     n     _     _     4     VOB     _     _
6     。    _     wp    _     _     4     WP    _     _

lgdpj主要通过配置文件指定执行的工作,其中主要有两类配置文件:训练配置和测试配置。

训练配置的配置文件样例如下所示。

[model]
labeled = 1
decoder-name = 2o-carreras

[feature]
use-postag-unigram = 0
use-dependency = 1
use-dependency-unigram = 1
use-dependency-bigram = 1
use-dependency-surrounding = 1
use-dependency-between = 1
use-sibling = 1
use-sibling-basic = 1
use-sibling-linear = 1
use-grand = 1
use-grand-basic = 1
use-grand-linear = 1

[train]
train-file = data/conll/ldc-train.conll
holdout-file = data/conll/ldc-holdout.conll
max-iter = 5
algorithm = pa
model-name = model/parser/ldc-o2carreras

其中,

  • [mode] 配置组中
    • labeled 表示是否使用有label的依存句法分析
    • decoder-name 表示采用的解码算法,现在lgdpj支持三种解码算法,分别是1o,2o-sib,2o-carreras
  • [feature] 配置组指定使用的特征
  • [train] 配置组指定执行训练
    • Train-file 配置项指定训练集文件
    • Holdout-file 配置项指定开发集文件
    • Algorithm 指定参数学习方法,现在otcws支持两种参数学习方法,分别是passive aggressive(pa)和average perceptron(ap)。
    • Model-name 指定输出模型文件名
    • Max-iter 指定最大迭代次数

测试配置的配置文件样例如下所示。

[test]
test-file = data/conll/ldc-test.conll
model-file = model/parser/ldc-o2carreras.2.model

其中,

  • [test] 配置组指定执行测试
    • Test-file 指定测试文件
    • Model-file 指定模型文件位置

依存句法分析结果将输入到标准io中。


分词

分词主要提供三个接口:

void * segmentor_create_segmentor

  • 功能:读取模型文件,初始化分词器。
  • 参数:
    参数名 参数描述
    const char * path 指定模型文件的路径
    const char * lexicon_path 指定外部词典路径。如果lexicon_path为NULL,则不加载外部词典
  • 返回值:返回一个指向分词器的指针。

int segmentor_release_segmentor

  • 功能:释放模型文件,销毁分词器。
  • 参数:
    参数名 参数描述
    void * segmentor 待销毁分词器的指针
  • 返回值:销毁成功时返回0,否则返回-1

int segmentor_segment

  • 功能:调用分词接口。
  • 参数:
    参数名 参数描述
    void * segmentor 分词器的指针
    const std::string & line 待分词句子
    std::vector<std::string> & words 结果分词序列
  • 返回值:返回结果中词的个数。

示例程序

一个简单的实例程序可以说明分词接口的用法:

#include <iostream>
#include <string>
#include "segment_dll.h"

int main(int argc, char * argv[]) {
    if (argc < 2) {
        std::cerr << "cws [model path]" << std::endl;
        return 1;
    }

    void * engine = segmentor_create_segmentor(argv[1]);
    if (!engine) {
        return -1;
    }
    std::vector<std::string> words;
    int len = segmentor_segment(engine,
        "爱上一匹野马,可我的家里没有草原。", words);
    for (int i = 0; i < len; ++ i) {
        std::cout << words[i] << "|";
    }
    std::cout << std::endl;
    segmentor_release_segmentor(engine);
    return 0;
}

实例程序通过命令行参数指定模型文件路径。第11行加载模型文件,并将分词器指针存储在engine中。第16行运行分词逻辑,并将结果存储在名为words的std::vector<std::string>中。第22行释放分词模型。

调用分词接口的程序在编译的时,需要链接segmentor.a(MSVC下需链接segmentor.lib)。

词性标注

词性标注主要提供三个接口

void * postagger_create_postagger

  • 功能:读取模型文件,初始化词性标注器
  • 参数:
    参数名 参数描述
    const char * path 词性标注模型路径
  • 返回值:返回一个指向词性标注器的指针。

int postagger_release_postagger

  • 功能:释放模型文件,销毁分词器。
  • 参数:
    参数名 参数描述
    void * postagger 待销毁的词性标注器的指针
  • 返回值:销毁成功时返回0,否则返回-1

int postagger_postag

  • 功能:调用词性标注接口
  • 参数:
    参数名 参数描述
    void * postagger 词性标注器的指针
    const std::vector< std::string > & words 待标注的词序列
    std::vector< std::string > & tags 词性标注结果,序列中的第i个元素是第i个词的词性
  • 返回值:返回结果中词的个数

示例程序

一个简单的实例程序可以说明词性标注接口的用法:

#include <iostream>
#include <vector>

#include "postag_dll.h"

int main(int argc, char * argv[]) {
    if (argc < 1) {
        return -1;
    }

    void * engine = postagger_create_postagger(argv[1]);
    if (!engine) {
        return -1;
    }

    std::vector words;

    words.push_back("我");
    words.push_back("是");
    words.push_back("中国人");

    std::vector tags;

    postagger_postag(engine, words, tags);

    for (int i = 0; i < tags.size(); ++ i) {
        std::cout << words[i] << "/" << tags[i];
        if (i == tags.size() - 1) std::cout << std::endl;
        else std::cout << " ";

    }

    postagger_release_postagger(engine);
    return 0;
}

实例程序通过命令行参数指定模型文件路径。第11行加载模型文件,并将词性标注器指针存储在engine中。第18至20行构造分词序列,第24行运行词性标注逻辑,并将结果存储在名为tags的std::vector<std::string>中。第33行释放分词模型。

调用词性标注接口的程序在编译的时,需要链接postagger.a(MSVC下需链接postagger.lib)。

命名实体识别

命名实体识别主要提供三个接口

void * ner_create_recognizer

  • 功能:读取模型文件,初始化命名实体识别器
  • 参数:
    参数名 参数描述
    const char * path 命名实体识别模型路径
  • 返回值:返回一个指向词性标注器的指针。

int ner_release_recognizer

  • 功能:释放模型文件,销毁命名实体识别器。
  • 参数:
    参数名 参数描述
    void * recognizer 待销毁的命名实体识别器的指针
  • 返回值:销毁成功时返回0,否则返回-1

int ner_recognize

  • 功能:调用命名实体识别接口
  • 参数:
    参数名 参数描述
    void * recognizer 命名实体识别器的指针
    const std::vector< std::string > & words 待识别的词序列
    const std::vector< std::string > & postags 待识别的词的词性序列
    std::vector<std::string> & tags 命名实体识别结果,命名实体识别的结果为O时表示这个词不是命名实体,否则为{POS}-{TYPE}形式的标记,POS代表这个词在命名实体中的位置,TYPE表示命名实体类型
  • 返回值:返回结果中词的个数

示例程序

#include <iostream>
#include <vector>

#include "ner_dll.h"

int main(int argc, char * argv[]) {
    if (argc < 2) {
        std::cerr << "usage: ./ner [model_path]" << std::endl;
        return -1;
    }

    void * engine = ner_create_recognizer(argv[1]);
    if (!engine) {
        std::cerr << "failed to load model" << std::endl;
        return -1;
    }

    std::vector<std::string> words;
    std::vector<std::string> postags;

    words.push_back("中国");    postags.push_back("ns");
    words.push_back("国际");    postags.push_back("n");
    words.push_back("广播");    postags.push_back("n");
    words.push_back("电台");    postags.push_back("n");
    words.push_back("创办");    postags.push_back("v");
    words.push_back("于");      postags.push_back("p");
    words.push_back("1941年");  postags.push_back("m");
    words.push_back("12月");    postags.push_back("m");
    words.push_back("3日");     postags.push_back("m");
    words.push_back("。");      postags.push_back("wp");

    std::vector<std::string>    tags;

    ner_recognize(engine, words, postags, tags);

    for (int i = 0; i < tags.size(); ++ i) {
        std::cout << words[i] << "\t" << postags[i] << "\t" << tags[i] << std::endl;
    }

    ner_release_recognizer(engine);
    return 0;
}

示例程序通过命令行参数指定模型文件路径。第11行加载模型文件,并将命名实体识别器指针存储在engine中。第21至30行构造分词序列words和词性标注序列postags,第34行运行词性标注逻辑,并将结果存储在名为tags的std::vectorstd::string中。第40行释放分词模型。

调用命名实体识别接口的程序在编译的时,需要链接ner.a(MSVC下需链接ner.lib)。

依存句法分析

依存句法分析主要提供三个接口:

void * parser_create_parser

  • 功能:读取模型文件,初始化依存句法分析器
  • 参数:
    参数名 参数描述
    const char * path 依存句法分析模型路径
  • 返回值:返回一个指向依存句法分析器的指针。

int parser_release_parser

  • 功能:释放模型文件,销毁依存句法分析器。
  • 参数:
    参数名 参数描述
    void * parser 待销毁的依存句法分析器的指针
  • 返回值:销毁成功时返回0,否则返回-1

int parser_parse

  • 功能:调用依存句法分析接口
  • 参数:
    参数名 参数描述
    void * parser 依存句法分析器的指针
    const std::vector< std::string > & words 待分析的词序列
    const std::vector< std::string > & postags 待分析的词的词性序列
    std::vector & heads 结果依存弧,heads[i]代表第i个词的父亲节点的编号
    std::vector<std::string> & deprels 结果依存弧关系类型
  • 返回值:返回结果中词的个数

示例程序

一个简单的实例程序可以说明依存句法分析接口的用法:

#include <iostream>
#include <vector>

#include "parser_dll.h"

int main(int argc, char * argv[]) {
    if (argc < 2) {
        return -1;
    }

    void * engine = parser_create_parser(argv[1]);
    if (!engine) {
        return -1;
    }

    std::vector words;
    std::vector postags;

    words.push_back("一把手");      postags.push_back("n");
    words.push_back("亲自");        postags.push_back("d");
    words.push_back("过问");        postags.push_back("v");
    words.push_back("。");          postags.push_back("wp");

    std::vector            heads;
    std::vector    deprels;

    parser_parse(engine, words, postags, heads, deprels);

    for (int i = 0; i < heads.size(); ++ i) {
        std::cout << words[i] << "\t" << postags[i] << "\t"
            << heads[i] << "\t" << deprels[i] << std::endl;
    }

    parser_release_parser(engine);
    return 0;
}

示例程序通过命令行参数指定模型文件路径。第11行加载模型文件,并将依存句法分析器指针存储在engine中。第19至22行构造分词序列words和词性标注序列postags,第27行运行词性标注逻辑,并将依存弧关系存储在heads中,将依存弧关系类型存储在deprels中。第34行释放依存句法分析模型。

调用依存句法分析接口的程序在编译的时,需要链接parser.a(MSVC下需链接parser.lib)。