简介

语言技术平台(Language Technology Platform,LTP)是 哈工大社会计算与信息检索研究中心 历时十年开发的一整套中文语言处理系统。LTP制定了基于XML的语言处理结果表示,并在此基础上提供了一整套自底向上的丰富而且高效的中文语言处理模块(包括词法、句法、语义等6项中文处理核心技术),以及基于动态链接库(Dynamic Link Library, DLL)的应用程序接口,可视化工具,并且能够以网络服务(Web Service)的形式进行使用。

从2006年9月5日开始该平台对外免费共享目标代码,截止目前,已经有国内外400多家研究单位共享了LTP,也有国内外多家商业公司购买了LTP,用于实际的商业项目中。2010年12月获得中国中文信息学会颁发的行业最高奖项:“钱伟长中文信息处理科学技术奖”一等奖。

2011年6月1日,为了与业界同行共同研究和开发中文信息处理核心技术,我中心正式将LTP开源。

2013年9月1日,语言技术平台云端服务” 语言云 “正式上线。

新闻

语言技术平台3.3.1版 发布

  • [修复] 修复了3.3.0版本模型加载的bug
  • [增加] 提供 Windows 下的`ltp_test`和`xxx_cmdline`二进制下载,无需再手工编译

语言技术平台3.3.0版 发布

  • [增加] 词性标注模型加入微博数据,使得在开放域上的词性标注性能更好(+3.3 precision)
  • [增加] 依存句法分析模型加入微博数据,使得在开放域上的句法分析性能更好(+3 UAS)
  • [增加] 依存句法分析算法切换到transition-based neural network parser,速度从40 tokens/s提升到8000 tokens/s。同时通过加入聚类特征以及优化训练算法,(在新闻领域)准确率也得到小幅提升(+0.2 UAS)
  • [增加] `ltp_test`默认支持多线程,线程数可配置。
  • [增加] 新加入子模块命令行程序,cws_cmdlinepos_cmdlinepar_cmdlinener_cmdline,使用户可以很容易替换中间模块,从而实现语言分析的组合。
  • [修改] 优化了训练套件的交互方式
  • [增加] 添加模型验证,单元测试模块。

目录

开始使用LTP

如果你是第一次使用LTP,不妨花一些时间了解LTP能帮你做什么。

LTP提供了一系列中文自然语言处理工具,用户可以使用这些工具对于中文文本进行分词、词性标注、句法分析等等工作。从应用角度来看,LTP为用户提供了下列组件:

  • 针对单一自然语言处理任务,生成统计机器学习模型的工具
  • 针对单一自然语言处理任务,调用模型进行分析的编程接口
  • 使用流水线方式将各个分析工具结合起来,形成一套统一的中文自然语言处理系统
  • 系统可调用的,用于中文语言处理的模型文件
  • 针对单一自然语言处理任务,基于云端的编程接口

如果你的公司需要一套高性能的中文语言分析工具以处理海量的文本,或者你的在研究工作建立在一系列底层中文自然语言处理任务之上,或者你想将自己的科研成果与前沿先进工作进行对比,LTP都可能是你的选择。

LTP 的下载和安装

如果你想要使用LTP,必须拥有两部分内容

  • LTP项目文件
  • LTP模型文件

你可以从以下链接获得最新的LTP项目源码。

如果你是windows用户,你也可以跳过从源代码编译的环节,从以下链接获得编译好的二进制文件

你可以从以下链接获得LTP的模型文件

依赖:CMake

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

在 Windows (MSVC) 下编译

第一步:构建 VC Project

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

http://ir.hit.edu.cn/~yjliu/image/2013-7-12-cmake-win-setup.png

或者在命令行build目录下运行:

cmake ..

第二步:编译

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

载Linux, Mac OSX 和 Cygwin 下编译

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

./configure
make

编译结果说明

编译成功后,会在 bin 目录下生成以下二进制程序:

程序名 说明
ltp_test LTP主程序
ltp_server [2] LTP Server

lib 目录下生成以下静态链接库 [3] :

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

tools/train 目录下生成以下二进制程序:

程序名 说明
otcws 分句训练和测试套件
otpos 词性标注训练和测试套件
otner 命名实体识别训练和测试套件
lgdpj 依存句法分析训练和测试套件
lgsrl 语义角色标注训练和测试套件

[1]boost::multi_array 与VS2010不兼容的bug已经在3.1.0中得到修复,3.1.x及以上版本已经可以使用Debug方式构建,但出于效率考虑,仍旧建议使用Release方式构建。
[2]在window版本中 ltp_serverMaxentSRLExtractSRLGetInstance 并不被编译。
[3]window下产生的静态库的后缀是.lib,linux下产生的静态库的后缀是.a

使用ltp_test和xxx_cmdline

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

LTP模型文件

LTP模型文件可以从以下渠道获取:

LTP提供的模型包括:

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

ltp_test主程序

ltp_test 是一个整合LTP中各模块的命令行工具。它完成加载模型,依照指定方法执行分析的功能。ltp_test 加载的模型通过配置文件指定。编译后运行:

$ ./bin/ltp_test
ltp_test in LTP 3.3.1 - (C) 2012-2015 HIT-SCIR
The console application for Language Technology Platform.

usage: ./ltp_test <options>

options:
  --threads arg           The number of threads [default=1].
  --last-stage arg        The last stage of analysis. This option can be used
                          when the user onlywants to perform early stage
                          analysis, like only segment without postagging.value
                          includes:
                          - ws: Chinese word segmentation
                          - pos: Part of speech tagging
                          - ner: Named entity recognization
                          - dp: Dependency parsing
                          - srl: Semantic role labeling (equals to all)
                          - all: The whole pipeline [default]
  --input arg             The path to the input file.
  --segmentor-model arg   The path to the segment model
                          [default=ltp_data/cws.model].
  --segmentor-lexicon arg The path to the external lexicon in segmentor
                          [optional].
  --postagger-model arg   The path to the postag model
                          [default=ltp_data/pos.model].
  --postagger-lexicon arg The path to the external lexicon in postagger
                          [optional].
  --ner-model arg         The path to the NER model [default=ltp_data/ner.model
                          ].
  --parser-model arg      The path to the parser model
                          [default=ltp_data/parser.model].
  --srl-data arg          The path to the SRL model directory
                          [default=ltp_data/srl_data/].
  --debug-level arg       The debug level.
  -h [ --help ]           Show help information

ltp_test通过命令行参数指定分析任务与模型路径。其中,

  • segmentor-model:指定分词模型
  • segmentor-lexicon:指定分词词典路径
  • postagger-model:指定词性标注模型
  • postagger-lexicon:指定词性标注词典路径
  • parser-model:指定依存句法分析模型
  • ner-model:指定命名实体识别模型
  • srl-data:指定语言角色标注模型
  • threads:指定线程数
  • input:指定输入文件,如果输入文件未指定或打开失败,将使用标准输入
  • last-stage:指定分析的最终步骤。这一参数将在 Pipeline与last-stage参数 中详细说明

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

Pipeline与last-stage参数

分词、词性标注、句法分析一系列任务之间存在依赖关系。举例来讲,对于词性标注,必须在分词结果之上进行才有意。LTP中提供的5种分析之间的依赖关系如下所示:

任务 标记 依赖
分词 ws
词性标注 pos ws
依存句法分析 dp pos
命名实体识别 ner | pos
语义角色标注 srl dp, ner

默认情况下,LTP将进行至语义角色标注的分析。但是,对于一部分用户,某些分析并不必要。举例来讲,如果用户只需进行词性标注,则ltp_test的pipeline分析只需进行到pos,`last-stage`用来指明分析的最后状态。同时,如果`last-stage`指定为pos,句法分析、命名实体识别和语义角色标注的模型将不被加载。

xxx_cmdline

除了 ltp_test 将全部分析器整合起来,LTP也提供拆分各模块单独分析的命令行程序。他们包括:

  • cws_cmdline :分词命令行
  • pos_cmdline :词性标注命令行
  • par_cmdline :句法分析命令行
  • ner_cmdline :命名实体识别命令行

xxx_cmdline的主要目标是提供不同于xml,同时可自由组合的语言分析模块。举在已经切分好的结果上做词性标注为例。:

$ cat input
这 是 测试 文本 。
$ cat input | ./bin/pos_cmdline --postagger-model ./ltp_data/pos.model
TRACE: Model is loaded
TRACE: Running 1 thread(s)
WARN: Cann't open file! use stdin instead.
这_r    是_v    测试_v  文本_n  。_wp
TRACE: consume 0.000832081 seconds.

关于各模块的用法,与ltp_test基本类似。细节请参考 xxx_cmdline -h

细节

长度限制

为了防止输入过长句子对稳定性造成影响。ltp限制用户输入字数少于1024字,分词结果少于256词。

外部词典

分词外部词典样例如下所示。每个制定一个词。例如

苯并芘
亚硝酸盐

词性标注外部词典样例如下所示。每行指定一个词,第一列指定单词,第二列之后指定该词的候选词性(可以有多项,每一项占一列),列与列之间用空格区分。

雷人 v a
】 wp

ltp项目中可以使用外部词典的模块包括

  • ./bin/ltp_test :分词、词性外部词典
  • ./bin/ltp_server :分词、词性外部词典
  • ./bin/examples/cws_cmdline :分词外部词典
  • ./bin/examples/pos_cmdline :词性外部词典
  • ./tools/train/otcws :分词外部词典
  • ./tools/train/otpos :词性外部词典

Window动态链接库

在Window下首次运行LTP会提示找不到动态链接库,这时请将编译产生的lib/*.dll拷贝到bin/Release/下,即可正常运行。

编码以及显示

LTP的所有模型文件均使用UTF8 [1] 编码训练,故请确保待分析文本的编码为UTF8格式。

兼容性测试

当前版本LTP在以下一些平台和编译器环境下通过测试

系统 编译器 版本 ltp_test 训练套件 ltp_server 单元测试 模型加载
Linux (64bit) gnu-c++ 4.4 支持 支持 支持 支持 通过
Linux (64bit) gnu-c++ 4.6 支持 支持 支持 支持 通过
Linux (64bit) gnu-c++ 4.7 支持 支持 支持 支持 通过
Linux (64bit) gnu-c++ 4.8 支持 支持 支持 支持 通过
Linux (64bit) gnu-c++ 4.9 支持 支持 支持 支持 通过
Linux (64bit) gnu-c++ 5.3 支持 支持 支持 不支持 通过
Linux (64bit) clang 3.4 支持 支持 支持 不支持 通过
Linux (64bit) clang 3.5 支持 支持 支持 不支持 通过
Linux (64bit) clang 3.6 支持 支持 支持 不支持 通过
Windows (64bit) MSVC 18/vs13 支持 支持 不支持 不支持 通过
Windows (64bit) MSVC 19/vs15 支持 支持 不支持 不支持 通过
Cygwin (64bit) gnu-c++ 4.8 支持 支持 支持 支持 通过
mingw (64bit) gnu-c++ 4.7 支持 支持 不支持 不支持 通过
mingw (64bit) gnu-c++ 5.1 支持 支持 不支持 不支持 通过

[1]由于Windows终端采用gbk编码显示,运行 ltp_test 后会在终端输出乱码。您可以将标准输出重定向到文件,以UTF8方式查看文件,就可以解决乱码的问题。

使用编程接口

如果要使用编程接口,您需要自己在开发环境中从源代码编译出相关的链接库,编译方法可以参考 LTP 的下载和安装 一节

下面的文档将介绍使用LTP编译产生的静态链接库编写程序的方法。

使用动态库

如果您之前对C++使用动态库并不熟悉,可以 参考这里

下面以一个分词程序 cws.cpp 来说明调用动态库的具体过程。

首先,编写调用动态库的程序,注意需要包含相应的头文件,代码如下:

#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;
}

接下来,编译程序,需要加入头文件和动态库的路径。

下面给出Linux、Windows两个平台下的编译示例。

在 Windows (MSVC) 下使用动态库

  1. 添加头文件路径

    右键工程->Configuration properties->c/c++->general->additional include directories

    http://ir.hit.edu.cn/ltp-2014/images/include.png
  2. 添加动态库路径

    右键工程->Configuration properties->linker->general->additional library directories

    http://ir.hit.edu.cn/ltp-2014/images/lib.png
  3. 导入所需的动态库

    右键工程->properties->linker->input->additional additional dependencies

    http://ir.hit.edu.cn/ltp-2014/images/import.png
  4. 最后,Build工程即可。

在 Linux 下使用动态库

假定您下载并将LTP放置于 /path/to/your/ltp-project 目录下,那么编译命令例如下:

g++ -o cws cws.cpp -I /path/to/your/ltp-project/include/ -I /path/to/your/ltp-project/thirdparty/boost/include -WL,-dn -L /path/to/your/ltp-project/lib/ -lsegmentor -lboost_regex -WL,-dy

分词接口

分词主要提供三个接口:

void *segmentor_create_segmentor(const char *path, const char *lexicon_path)

功能:

读取模型文件,初始化分词器。

参数:

参数名 参数描述
const char * path 指定模型文件的路径
const char * lexicon_path 指定外部词典路径。如果lexicon_path为NULL,则不加载外部词典

返回值:

返回一个指向分词器的指针。

int segmentor_release_segmentor(void *segmentor)

功能:

释放模型文件,销毁分词器。

参数:

参数名 参数描述
void * segmentor 待销毁分词器的指针

返回值:

销毁成功时返回0,否则返回-1

int segmentor_segment(void *segmentor, const std::string &line, std::vector<std::string> &words)

功能:

调用分词接口。

参数:

参数名 参数描述
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, const char *lexicon_file)

功能:

读取模型文件,初始化词性标注器

参数:

参数名 参数描述
const char * path 词性标注模型路径
const char * lexicon_file 指定词性标注外部词典路径。如果lexicon_file为NULL,则不加载外部词典

lexicon_file参数指定的外部词典文件样例如下所示。每行指定一个词,第一列指定单词,第二列之后指定该词的候选词性(可以有多项,每一项占一列),列与列之间用空格区分:

雷人 v a
】 wp

返回值:

返回一个指向词性标注器的指针。

int postagger_release_postagger(void *postagger)

功能:

释放模型文件,销毁分词器。

参数:

参数名 参数描述
void * postagger 待销毁的词性标注器的指针

返回值:

销毁成功时返回0,否则返回-1

int postagger_postag(void *postagger, const std::vector<std::string> &words, std::vector<std::string> &tags)

功能:

调用词性标注接口

参数:

参数名 参数描述
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<std::string> words;

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

    std::vector<std::string> 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)

功能:

读取模型文件,初始化命名实体识别器

参数:

参数名 参数描述
const char * path 命名实体识别模型路径

返回值:

返回一个指向词性标注器的指针。

int ner_release_recognizer(void *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)

功能:

调用命名实体识别接口

参数:

参数名 参数描述
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::vector<std::string>中。第40行释放分词模型。

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

依存句法分析接口

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

void *parser_create_parser(const char *path)

功能:

读取模型文件,初始化依存句法分析器

参数:

参数名 参数描述
const char * path 依存句法分析模型路径

返回值:

返回一个指向依存句法分析器的指针。

int parser_release_parser(void *parser)

功能:

释放模型文件,销毁依存句法分析器。

参数:

参数名 参数描述
void * parser 待销毁的依存句法分析器的指针

返回值:

销毁成功时返回0,否则返回-1

int parser_parse(void *parser, const std::vector<std::string> &words, const std::vector<std::string> &postagger, std::vector<int> &heads, std::vector<std::string> &deprels)

功能:

调用依存句法分析接口

参数:

参数名 参数描述
void * parser 依存句法分析器的指针
const std::vector<std::string> & words 待分析的词序列
const std::vector<std::string> & postags 待分析的词的词性序列
std::vector<int> & 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<std::string> words;
    std::vector<std::string> 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<int>            heads;
    std::vector<std::string>    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)。

语义角色标注接口

语义角色标注主要提供三个接口:

int SRL_loadResource(const std::string &ConfigDir)

功能:

读取模型文件,初始化语义角色标注器

参数:

参数名 参数描述
const std::string& ConfigDir 语义角色标注模型文件夹所在路径

返回值:

返回一个指向词性标注器的指针。

int SRL_ReleaseResource()

功能:

释放模型文件,销毁命名实体识别器。

返回值:

销毁成功时返回0,否则返回-1

int DoSRL(const std::vector<std::string> &words, const std::vector<std::string> &POS, const std::vector<std::string> &NEs, const std::vector<std::pair<int, std::string>> &parse, std::vector<std::pair<int, std::vector<std::pair<std::string, std::pair<int, int>>>>> &SRLResult)

功能:

调用命名实体识别接口

参数:

参数名 参数描述
const std::vector<std::string> & words 输入的词序列
const std::vector<std::string> & postags 输入的词性序列
const std::vector<std::string> & nes 输入的命名实体序列
const std::vector<
std::pair<int, std::string>
> & parse
输入的依存句法结果
依存句法结果表示为长度为句子长的序列
序列中每个元素由两个成员组成,分别表示这个词的父节点的编号 [1] 和依存关系类型
std::vector<
std::pair<
int,
std::vector<
std::pair<
std::string,
std::pair<int, int>
>
>
>
>
输出的语义角色标注结果
语义角色标注结果表示为一个句子中谓词个数的序列
序列中每个谓词有两个成员组成,第一个成员表示谓词的下标,第二个成员是一个列表
列表中每个元素表示与这个谓词对应的论元
每个论元由两个成员组成:
第一个成员代表这个论元的语义角色类型,
第二个成员代表这个论元的管辖范围,表示成一个二元组

返回值:

返回结果中词的个数

[1]编号从0记起

使用ltp_server

注意

ltp_server只提供Linux版本

本文档中提到的LTP Server与语言云服务不同。语言云建立在LTP Server之上,并封装了一层REST API接口。语言云API(ltp-cloud-api)的请求方式与LTP Server不同。

搭建LTP Server

LTP Server在轻量级服务器程序mongoose基础上开发。在编译LTP源码之后,运行`./bin/ltp_server`就可以启动LTP Server。:

ltp_server in LTP 3.3.1 - (C) 2012-2015 HIT-SCIR
The HTTP server frontend for Language Technology Platform.

usage: ./ltp_server <options>

options:
  --port arg              The port number [default=12345].
  --threads arg           The number of threads [default=1].
  --last-stage arg        The last stage of analysis. This option can be used
                          when the user onlywants to perform early stage
                          analysis, like only segment without postagging.value
                          includes:
                          - ws: Chinese word segmentation
                          - pos: Part of speech tagging
                          - ner: Named entity recognization
                          - dp: Dependency parsing
                          - srl: Semantic role labeling (equals to all)
                          - all: The whole pipeline [default]
  --segmentor-model arg   The path to the segment model
                          [default=ltp_data/cws.model].
  --segmentor-lexicon arg The path to the external lexicon in segmentor
                          [optional].
  --postagger-model arg   The path to the postag model
                          [default=ltp_data/pos.model].
  --postagger-lexicon arg The path to the external lexicon in postagger
                          [optional].
  --ner-model arg         The path to the NER model [default=ltp_data/ner.model
                          ].
  --parser-model arg      The path to the parser model
                          [default=ltp_data/parser.model].
  --srl-data arg          The path to the SRL model directory
                          [default=ltp_data/srl_data/].
  --log-level arg         The log level:
                          - 0: TRACE level
                          - 1: DEBUG level
                          - 2: INFO level [default]

  -h [ --help ]           Show help information

其中较为重要的参数包括:

  • port:指定LTP server监听的端口
  • threads:指定LTP server运行的线程数,线程数影响并发的处理能力
  • log-level:指定日志级别,TRACE级别最低,显示日志信息最详细。INFO级别最高,显示日志最粗略。WARN与ERROR级日志默认显示。

其余参数用以指定模型路径,具体含义与`ltp_test`相同。

请求LTP Server

原理

在ltp web service中,client与server之间采用http协议通信。client以post方式提交的数据到server,server将数据以xml的方式返回给client。

client提交的post请求主要有以下几个字段。

字段名 含义
s 输入字符串,在xml选项x为n的时候,代表输入句子;为y时代表输入xml
x 用以指明是否使用xml
t 用以指明分析目标,t可以为分词(ws),词性标注(pos),命名实体识别(ner),依存句法分析(dp),语义角色标注(srl)或者全部任务(all)

数据表示

LTP 数据表示标准称为LTML。下面是LTML的一个简单例子:

<?xml version="1.0" encoding="utf-8" ?>
<xml4nlp>
    <note sent="y" word="y" pos="y" ne="y" parser="y" wsd="y" srl="y" />
    <doc>
        <para id="0">
            <sent id="0" cont="我们都是中国人">
                <word id="0" cont="我们" pos="r" ne="O" parent="2" relate="SBV" />
                <word id="1" cont="都" pos="d" ne="O" parent="2" relate="ADV" />
                <word id="2" cont="是"  pos="v" ne="O" parent="-1" relate="HED">
                    <arg id="0" type="A0" beg="0" end="0" />
                    <arg id="1" type="AM-ADV" beg="1" end="1" />
                </word>
                <word id="3" cont="中国" pos="ns" ne="S-Ns" parent="4" relate="ATT" />
                <word id="4" cont="人" pos="n" ne="O" parent="2" relate="VOB" />
            </sent>
        </para>
    </doc>
</xml4nlp>

LTML 标准要求如下:

结点标签分别为 xml4nlp, note, doc, para, sent, word, arg 共七种结点标签:

  1. xml4nlp 为根结点,无任何属性值;
  2. note 为标记结点,具有的属性分别为:sent, word, pos, ne, parser, srl; 分别代表分句,分词,词性标注,命名实体识别,依存句法分析,词义消歧,语义角色标注; 值为”n”,表明未做,值为”y”则表示完成,如pos=”y”,表示已经完成了词性标注;
  3. doc 为篇章结点,以段落为单位包含文本内容;无任何属性值;
  4. para 为段落结点,需含id 属性,其值从0 开始;
  5. sent 为句子结点,需含属性为id,cont;
    1. id 为段落中句子序号,其值从0 开始;
    2. cont 为句子内容;
  6. word 为分词结点,需含属性为id, cont;
    1. id 为句子中的词的序号,其值从0 开始,
    2. cont为分词内容;可选属性为 pos, ne, parent, relate;
      1. pos 的内容为词性标注内容;
      2. ne 为命名实体内容;
      3. parent 与relate 成对出现,parent 为依存句法分析的父亲结点id 号,relate 为相对应的关系;
  7. arg 为语义角色信息结点,任何一个谓词都会带有若干个该结点;其属性为id, type, beg,end;
    1. id 为序号,从0 开始;
    2. type 代表角色名称;
    3. beg 为开始的词序号,end 为结束的序号;

各结点及属性的逻辑关系说明如下:

  1. 各结点层次关系可以从图中清楚获得,凡带有id 属性的结点是可以包含多个;
  2. 如果sent=”n”即未完成分句,则不应包含sent 及其下结点;
  3. 如果sent=”y” word=”n”即完成分句,未完成分词,则不应包含word 及其下结点;
  4. 其它情况均是在sent=”y” word=”y”的情况下:
    1. 如果 pos=”y”则分词结点中必须包含pos 属性;
    2. 如果 ne=”y”则分词结点中必须包含ne 属性;
    3. 如果 parser=”y”则分词结点中必须包含parent 及relate 属性;
    4. 如果 srl=”y”则凡是谓词(predicate)的分词会包含若干个arg 结点;

示例程序

下面这个python程序例子显示如何向LTP Server发起http请求,并获得返回结果:

# -*- coding: utf-8 -*-
#!/usr/bin/env python
import urllib, urllib2

uri_base = "http://127.0.0.1:12345/ltp"

data = {
    's': '我爱北京天安门',
    'x': 'n',
    't': 'all'}

request = urllib2.Request(uri_base)
params = urllib.urlencode(data)
response = urllib2.urlopen(request, params)
content = response.read().strip()
print content

错误返回

如果请求有不符合格式要求,LTP Server会返回400错误。下面的表格显示了LTP Server返回的错误类型以及原因。

code reason 解释
400 EMPTY SENTENCE 输入句子为空
400 ENCODING NOT IN UTF8 输入句子非UTF8编码
400 SENTENCE TOO LONG 输入句子不符合 长度限制
400 BAD XML FORMAT 输入句子不符合LTML格式

当前版本服务性能

版本:3.3.0

测试使用Xeon(R) CPU E5-2620 0 @ 2.00GHz,4线程,请求时间:3分钟,测试脚本使用pylot 1.26。

Number of agents = 10

Last Stage Response Time (secs) Throughput (req/sec)
ws 0.010 643.308
pos 0.012 743.809
dp 0.016 574.785
ne 0.014 673.661
srl/all 0.036 266.094

使用其他语言调用ltp

如果您希望在本地使用除C++之外的其他语言调用LTP,我们针对常用语言对LTP进行了封装。

使用训练套件

分词训练套件otcws用法

otcws是ltp分词模型的训练套件,用户可以使用otcws训练获得ltp的分词模型。otcws支持从人工切分数据中训练分词模型和调用分词模型对句子进行切分。人工切分的句子的样例如下::

对外      ,       他们      代表      国家      。

编译之后,在tools/train下面会产生名为otcws的二进制程序。运行可见:

$ ./tools/train/otcws
otcws in LTP 3.3.0 - (C) 2012-2015 HIT-SCIR
Training and testing suite for Chinese word segmentation

usage: ./otcws [learn|customized-learn|test|customized-test|dump] <options>

其中第二个参数调用训练(learn)或测试(test)或可视化模型(dump),对于customized-learn以及customized-test,请参考 个性化分词

训练一个模型

如果进行模型训练(learn),:

$ ./tools/train/otcws learn
otcws(learn) in LTP 3.3.0 - (C) 2012-2015 HIT-SCIR
Training suite for Chinese word segmentation

usage: ./otcws learn <options>

options:
  --model arg                  The prefix of the model file, model will be
                               stored as model.$iter.
  --reference arg              The path to the reference file.
  --development arg            The path to the development file.
  --algorithm arg              The learning algorithm
                                - ap: averaged perceptron
                                - pa: passive aggressive [default]
  --max-iter arg               The number of iteration [default=10].
  --rare-feature-threshold arg The threshold for rare feature, used in model
                               truncation. [default=0]
  --dump-details arg           Save the detailed model, used in incremental
                               training. [default=false]
  -h [ --help ]                Show help information

其中:

  • reference:指定训练集文件
  • development:指定开发集文件
  • algorithm:指定参数学习方法,现在LTP在线学习框架支持两种参数学习方法,分别是passive aggressive(pa)和average perceptron(ap)。
  • model:指定输出模型文件名前缀,模型采用model.$iter方式命名
  • max-iter:指定最大迭代次数
  • rare-feature-threshold:模型裁剪力度,如果rare-feature-threshold为0,则只去掉为0的特征;rare-feature-threshold;如果大于0时将进一步去掉更新次数低于阈值的特征。关于模型裁剪算法细节,请参考 模型裁剪 部分。
  • dump-details:指定保存模型时输出所有模型信息,这一参数用于 个性化分词 ,具体请参考 个性化分词

需要注意的是,reference和development都需要是人工切分的句子。

测试模型/切分句子

如果进行模型测试(test),:

$ ./tools/train/otcws test
otcws(test) in LTP 3.3.0 - (C) 2012-2015 HIT-SCIR
Testing suite for Chinese word segmentation

usage: ./otcws test <options>

options:
  --model arg           The path to the model file.
  --lexicon arg         The lexicon file, (optional, if configured, constrained
                        decoding will be performed).
  --input arg           The path to the reference file.
  --evaluate arg        if configured, perform evaluation, input words in
                        sentence should be separated by space.
  -h [ --help ]         Show help information

其中,

  • model:指定模型文件位置
  • lexicon:指定外部词典位置,这个参数是可选的
  • input:指定输入文件
  • evaluate:true或false,指定是否进行切词结果准确率的评价。如果进行评价,输入的文件应该是人工切分的数据。

外部词典 (lexicon) 格式请参考 外部词典

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

词性标注训练套件otpos用法

otpos是ltp分词模型的训练套件,用户可以使用otpos训练获得ltp的分词模型。otpos支持从人工切分并标注词性的数据中训练词性标注模型和调用词性标注模型对切分好的句子进行词性标注。人工标注的词性标注句子样例如下::

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

编译之后,在tools/train下面会产生名为otpos的二进制程序。otpos的使用方法与otcws非常相似,同名参数含义也完全相同。其中不同之处在于词性标注模块的外部词典含义与分词的外部词典含义不同。:

$ ./tools/train/otpos test
otpos(test) in LTP 3.3.0 - (C) 2012-2015 HIT-SCIR
Testing suite for Part of Speech Tagging

usage: ./otpos test <options>

options::
  --model arg           The path to the model file.
  --lexicon arg         The lexicon file, (optional, if configured, constrained
                        decoding will be performed).
  --input arg           The path to the reference file.
  --evaluate arg        if configured, perform evaluation, input should contain
                        '_' concatenated tag
  -h [ --help ]         Show help information

外部词典 (lexicon) 格式请参考 外部词典

命名实体识别训练套件otner用法

otner是ltp命名实体识别模型的训练套件,用户可以使用otner训练获得ltp的命名实体识别模型。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

编译之后,在tools/train下面会产生名为otner的二进制程序。otner的使用方法与otcws非常相似,同名参数含义也完全相同。

依存句法分析训练套件nndepparser用法

nndepparser是ltp神经网络依存句法分析模型的训练套件,用户可以使用nndepparser训练获得ltp的依存句法分析模型。nndepparser分别支持从人工标注依存句法的数据中训练依存句法分析模型和调用依存句法分析模型对句子进行依存句法分析。人工标注的词性标注依存句法的句子遵从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      _       _

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

./nndepparser [learn|test] <options>

训练一个parser

运行./nndepparser learn,可见如下参数:

$ ./tools/train/nndepparser learn
nndepparser(learn) in ltp 3.3.0 - (c) 2012-2015 hit-scir
training suite for neural network parser
usage: ./nndepparser learn <options>

options:
  --model arg               the path to the model.
  --embedding arg           the path to the embedding file.
  --reference arg           the path to the reference file.
  --development arg         the path to the development file.

  --init-range arg          the initialization range. [default=0.01]
  --word-cutoff arg         the frequency of rare word. [default=1]
  --max-iter arg            the number of max iteration. [default=20000]
  --batch-size arg          the size of batch. [default=10000]
  --hidden-size arg         the size of hidden layer. [default=200]
  --embedding-size arg      the size of embedding. [default=50]
  --features-number arg     the number of features. [default=48]
  --precomputed-number arg  the number of precomputed. [default=100000]
  --evaluation-stops arg    evaluation on per-iteration. [default=100]
  --ada-eps arg             the eps in adagrad. [defautl=1e-6]
  --ada-alpha arg           the alpha in adagrad. [default=0.01]
  --lambda arg              the regularizer parameter. [default=1e-8]
  --dropout-probability arg the probability for dropout. [default=0.5]
  --oracle arg              the oracle type
                             - static: the static oracle [default]
                             - nondet: the non-deterministic oracle
                             - explore: the explore oracle.
  --save-intermediate arg   save the intermediate. [default=true]
  --fix-embeddings arg      fix the embeddings. [default=false]
  --use-distance arg        specify to use distance feature. [default=false]
  --use-valency arg         specify to use valency feature. [default=false]
  --use-cluster arg         specify to use cluster feature. [default=false]
  --cluster arg             specify the path to the cluster file.
  --root arg                the root tag. [default=root]
  --verbose                 logging more details.
  -h [ --help ]             show help information.

nndepparser具有较多参数,但大部分与Chen and Manning (2014)中的定义一致。希望使用nndepparser的用户需要首先阅读其论文。 另,经验表明,大部分参数采用默认值亦可取得较好的效果。 所以在不能明确各参数含义的情况下,可以直接使用默认值。

相较Chen and Manning (2014),nndepparser中特有的参数包括:

  • oracle:指定oracle函数类型,可选的oracle包括static,nondet和explore。一般来讲,explore效果最好,具体算法请参考Yoav et. al, (2014)
  • use-distance:指定使用距离特征,具体参考Zhang and Nivre (2011)
  • use-valency:指定使用valency特征,具体参考Zhang and Nivre (2011)
  • use-cluster:指定使用词聚类特征,具体参考Guo et. al, (2015)
  • root:根节点的deprel的类型,需要注意的是,当前版本nndepparser只能处理projective single-root的依存树。

参考文献

  • Danqi Chen and Christopher Manning, 2014, A Fast and Accurate Dependency Parser using Neural Networks, In Proc. of EMNLP2014
  • Yue Zhang and Joakim Nivre, 2011, Transition-based Dependency Parsing with Rich Non-local Features, In Proc. of ACL2011
  • Yoav Goldberg, Francesco Sartorioand Giorgio Satta, 2014, A Tabular Method for Dynamic Oracles in Transition-Based Parsing, In TACL2014
  • Jiang Guo, Wanxiang Che, David Yarowsky, Haifeng Wang and Ting Liu, 2015, Cross-lingual Dependency Parsing Based on Distributed Representations, (to apper) In Proc. of ACL2015

实现原理与性能

在线学习算法框架

在机器学习领域,在线学习(Online learning)指每次通过一个训练实例学习模型的学习方法。在线学习的目的是正确预测训练实例的标注。在线学习最重要的一个特点是,当一次预测完成时,其正确结果便被获得,这一结果可直接用来修正模型。

http://ir.hit.edu.cn/~yjliu/image/2013-7-12-ot-framework.jpg

在自然语言处理领域,在线学习已经被广泛地应用在分词、词性标注、依存句法分析等结构化学习任务中。

模型裁剪

在LTP中,词性标注、句法分析两个模块还存在模型比较大的问题。为了缩小模型的大小,我们参考 Learning Sparser Perceptron Model ,将其中提到的特征裁剪策略加入了LTP。

具体来讲,LTP特征映射是以特征前缀为单位进行组织的。对应的,我们裁剪了同一前缀下更新次数较少的所有特征。

测试设置

下述实验的测试硬件环境如下:

  • CPU: Intel(R) Xeon(R) CPU E5-2620 0 @ 2.00GHz
  • RAM: 128G

分词模块

在LTP中,我们将分词任务建模为基于字的序列标注问题。对于输入句子的字序列,模型给句子中的每个字标注一个标识词边界的标记。在LTP中,我们采用的标记集如附录所示。

对于模型参数,我们采用在线机器学习算法框架从标注数据中学习参数。对于分词模型,我们使用的基本模型特征有:

类别 特征
char-unigram ch[-2], ch[-1], ch[0], ch[1], ch[2]
char-bigram ch[-2]ch[-1], ch[-1]ch[0],ch[0]ch[1],ch[1]ch[2]
dulchar ch[-1]=ch[0]?
dul2char ch[-2]=ch[0]?

同时,为了提高互联网文本特别是微博文本的处理性能。我们在分词系统中加入如下一些优化策略:

  • 英文、URI一类特殊词识别规则
  • 利用空格等自然标注线索
  • 在统计模型中融入词典信息
  • 从大规模未标注数据中统计的字间互信息、上下文丰富程度

在统计模型中融合词典的方法是将最大正向匹配得到的词特征

类别 特征
begin-of-lexicon-word ch[0] is preffix of words in lexicon?
middle-of-lexicon-word ch[0] is middle of words in lexicon?
end-of-lexicon-word ch[0] is suffix of words in lexicon?

基础模型在人民日报测试数据上的性能如下:

语料信息:人民日报1998年2月-6月(后10%数据作为开发集)作为训练数据,1月作为测试数据。

  • 准确率为:

      P R F
    开发集 0.973152 0.972430 0.972791
    测试集 0.972316 0.970354 0.972433
  • 运行时内存:124M

  • 速度:392.5K/sec

个性化分词

个性化分词是LTP的特色功能。个性化分词为了解决测试数据切换到如小说、财经等不同于新闻领域的领域。 在切换到新领域时,用户只需要标注少量数据。 个性化分词会在原有新闻数据基础之上进行增量训练。 从而达到即利用新闻领域的丰富数据,又兼顾目标领域特殊性的目的。

准备基础模型

用户可以从百度云托管上获得符合北大切词规范的基础模型。 如果需要利用其它切词规范的数据作为基础模型,使用 ./tools/train/otcws learn 训练模型时需要指定 --dump-details 选项为true。

个性化训练

个性化分词模型的训练同样可以通过分词训练套件 otcws 来实现。:

$ ./tools/train/otcws customized-learn
otcws(customized-learn) in LTP 3.3.0 - (C) 2012-2015 HIT-SCIR
Customized training suite for Chinese word segmentation

usage: ./otcws learn <options>

options:
  --baseline-model arg         The baseline model, which should be saved with
                               --dump-details options.
  --model arg                  The prefix of the model file, model will be
                               stored as model.$iter.
  --reference arg              The path to the reference file.
  --development arg            The path to the development file.
  --algorithm arg              The learning algorithm
                                - ap: averaged perceptron
                                - pa: passive aggressive [default]
  --max-iter arg               The number of iteration [default=10].
  --rare-feature-threshold arg The threshold for rare feature, used in model
                               truncation. [default=0]
  -h [ --help ]                Show help information

这种情况下,需要指定 --baseline-model 参数为前面获得的基础模型。其余选项与 ./tools/train/otcws learn 一致。

个性化测试

个性化分词模型的训练同样可以通过分词训练套件 otcws 来实现。:

$ ./tools/train/otcws customized-test
otcws(customized-test) in LTP 3.3.0 - (C) 2012-2015 HIT-SCIR
Customized testing suite for Chinese word segmentation

usage: ./otcws test <options>

options:
  --baseline-model arg  The path to the baseline model.
  --model arg           The path to the model file.
  --lexicon arg         The lexicon file, (optional, if configured, constrained
                        decoding will be performed).
  --input arg           The path to the reference file.
  --evaluate arg        if configured, perform evaluation, input words in
                        sentence should be separated by space.
  -h [ --help ]         Show help information

与customized-learn类似,需指定 --baseline-model 参数为前面获得的基础模型。其余选项与 ./tools/train/otcws test 一致。

词性标注模块

与分词模块相同,我们将词性标注任务建模为基于词的序列标注问题。对于输入句子的词序列,模型给句子中的每个词标注一个标识词边界的标记。在LTP中,我们采用的北大标注集。关于北大标注集信息,请参考:

对于模型参数,我们采用在线机器学习算法框架从标注数据中学习参数。对于词性标注模型,我们使用的模型特征有:

类别 特征
word-unigram w[-2], w[-1], w[0], w[1], w[2]
word-bigram w[-2]w[-1],w[-1]w[0],w[0]w[1],w[1]w[2]
word-trigram w[-1]w[0]w[1]
last-first-character ch[0,0]ch[0,n],ch[-1,n]ch[0,0],ch[0,-1]ch[1,0]
length length
prefix ch[0,0],ch[0,0:1],ch[0,0:2]
suffix ch[0,n-2:n],ch[0,n-1:n],ch[0,n]

基础模型在人民日报数据集上的性能如下:

语料信息:人民日报1998年2月-6月(后10%数据作为开发集)作为训练数据,1月作为测试数据。

  • 准确率为:

      P
    开发集 0.979621
    测试集 0.978337
  • 运行时内存:276M

  • 速度:169.5K/sec

命名实体识别模块

与分词模块相同,我们将命名实体识别建模为基于词的序列标注问题。对于输入句子的词序列,模型给句子中的每个词标注一个标识命名实体边界和实体类别的标记。在LTP中,我们支持人名、地名、机构名三类命名实体的识别。关于LTP使用的标记参考附录。

对于模型参数,我们采用在线机器学习算法框架从标注数据中学习参数。对于词性标注模型,我们使用的模型特征有:

类别 特征
word-unigram w[-2], w[-1], w[0], w[1], w[2]
word-bigram w[-2]w[-1],w[-1]w[0],w[0]w[1],w[1]w[2]
postag-unigram p[-2],p[-1],p[0],p[1],p[2]
postag-bigram p[-1]p[0],p[0]p[1]

基础模型在人民日报数据集上的性能如下:

语料信息:人民日报1998年1月做训练(后10%数据作为开发集),6月前10000句做测试作为训练数据。

  • 准确率

      P R F
    开发集 0.924149 0.909323 0.916676
    测试集 0.939552 0.936372 0.937959
  • 运行时内存:33M

依存句法分析模块

依存句法分析模块的主要算法依据神经网络依存句法分析算法,Chen and Manning (2014)。同时加入丰富的全局特征和聚类特征。在模型训练时,我们也参考了Yoav等人关于dynamic oracle的工作。 在 Chinese Dependency Treebank(CDT) 数据集上,其中运行速度和内存开销从CDT测试集上结果中获得。

  UAS LAS
开发集 85.80 83.19
测试集 84.11 81.17
速度 8000 tok./sed
运行时内存 338.06M

语义角色标注模块

在LTP中,我们将SRL分为两个子任务,其一是谓词的识别(Predicate Identification, PI),其次是论元的识别以及分类(Argument Identification and Classification, AIC)。对于论元的识别及分类,我们将其视作一个联合任务,即将“非论元”也看成是论元分类问题中的一个类别。在SRL系统中,我们在最大熵模型中引入L1正则,使得特征维度降至约为原来的1/40,从而大幅度地减小了模型的内存使用率,并且提升了预测的速度。同时,为了保证标注结果满足一定的约束条件,系统增加了一个后处理过程。

在CoNLL 2009评测数据集上,利用LTP的自动词性及句法信息,SRL性能如下所示:

Precision Recall F-Score Speed Mem.
0.8444 0.7234 0.7792 41.1 sent./s 94M(PI+AIC)

常见问题

  1. “我在本地使用ltp的时候出现 [ERROR] … in LTP::wordseg, failed to load segmentor resource 是怎么回事儿?”

这个提示的含义是模型加载失败。

可能原因一 :模型不存在

如果您没有下载模型,请参考 LTP模型文件 下载部署模型

可能原因二 :模型与ltp版本不对应

ltp在加载模型是会检查模型签名和当前版本号,所以请确定您使用的模型与您使用的ltp版本号对应。 ltp版本号可以用 ./bin/ltp_test --help 查看。 模型版本号可以通过 ltp_data/version 查看。

未知原因

LTP模型使用二进制文件存储。 由于 unsigned long long 在不同编译器下长度不同,可能存在加载出错。 对于这种问题,请在我们项目的issue tracker https://github.com/HIT-SCIR/ltp/issues 里面反馈问题。 在提交issue时,请将您的编译器情况、系统情况(32bit/64bit等)反隐给我们。

  1. “我使用分词词典了,但是为什么某些词典词还是被切开了”

ltp的分词模块 并非采用词典匹配的策略 ,外部词典以特征方式加入机器学习算法,并不能保证所有的词都是按照词典里的方式进行切分。 如果要完全按照词典匹配的方式切词,您可以尝试对切词结果进行后处理。

  1. “可不可以把Java/Python调用LTP,或切词原理文档, 发我一份吗?”

使用Java或Python调用ltp请参考ltp4j和pyltp这两个项目以及文档中 使用其他语言调用ltp 部分。

  1. “调用ltp_server时为什会出现400错误?”

可能原因一 :句子过长

为了保证处理效率,ltp对于输入句子长度进行了限制。现在的限制是最大句子长度 1024字 ,切词结果最多 256词

可能原因二 :编码错误

ltp只接受UTF8编码输入。如果您的输入是GBK编码,请转为 UTF8无bom编码

  1. “我有很长很长的句子,如何才能打破1024字/256词的限制?”

方案一 :使用 xxx_cmdline

您可以使用 xxx_cmdline 作为替代。xxx_cmdline 的分词模块、词性标注模块和命名实体识别模块是没有长度限制的。 句法分析模块限制长度为1024词。

方案二 :修改 src/ltp/Ltp.h

修改 src/ltp/Ltp.h`中 :code:`#define MAX_SENTENCE_LEN 1024#define MAX_WORDS_NUM 256 两个宏,重新编译。

  1. 我没找到想要的答案,请问哪里能获得有关ltp的帮助

您可以在我们的Google group https://groups.google.com/forum/#!forum/ltp-cloud 中发帖提问。 提问前,请再次确认您的问题没有现成的答案。并在提问时保持礼貌风度。 有关提问的艺术,请参考池建强老师的博客 http://macshuo.com/?p=367

相关论文

附录

分词标注集

标记 含义 举例
B 词首 __中__国
I 词中 哈__工__大
E 词尾 科__学__
S 单字成词

词性标注集

LTP 使用的是863词性标注集,其各个词性含义如下表。

Tag Description Example Tag Description Example
a adjective 美丽 ni organization name 保险公司
b other noun-modifier 大型, 西式 nl location noun 城郊
c conjunction 和, 虽然 ns geographical name 北京
d adverb nt temporal noun 近日, 明代
e exclamation nz other proper noun 诺贝尔奖
g morpheme 茨, 甥 o onomatopoeia 哗啦
h prefix 阿, 伪 p preposition 在, 把
i idiom 百花齐放 q quantity
j abbreviation 公检法 r pronoun 我们
k suffix 界, 率 u auxiliary 的, 地
m number 一, 第一 v verb 跑, 学习
n general noun 苹果 wp punctuation ,。!
nd direction noun 右侧 ws foreign words CPU
nh person name 杜甫, 汤姆 x non-lexeme 萄, 翱

命名实体识别标注集

NE识别模块的标注结果采用O-S-B-I-E标注形式,其含义为

标记 含义
O 这个词不是NE
S 这个词单独构成一个NE
B 这个词为一个NE的开始
I 这个词为一个NE的中间
E 这个词位一个NE的结尾

LTP中的NE 模块识别三种NE,分别如下:

标记 含义
Nh 人名
Ni 机构名
Ns 地名

依存句法关系

关系类型 Tag Description Example
主谓关系 SBV subject-verb 我送她一束花 (我 <– 送)
动宾关系 VOB 直接宾语,verb-object 我送她一束花 (送 –> 花)
间宾关系 IOB 间接宾语,indirect-object 我送她一束花 (送 –> 她)
前置宾语 FOB 前置宾语,fronting-object 他什么书都读 (书 <– 读)
兼语 DBL double 他请我吃饭 (请 –> 我)
定中关系 ATT attribute 红苹果 (红 <– 苹果)
状中结构 ADV adverbial 非常美丽 (非常 <– 美丽)
动补结构 CMP complement 做完了作业 (做 –> 完)
并列关系 COO coordinate 大山和大海 (大山 –> 大海)
介宾关系 POB preposition-object 在贸易区内 (在 –> 内)
左附加关系 LAD left adjunct 大山和大海 (和 <– 大海)
右附加关系 RAD right adjunct 孩子们 (孩子 –> 们)
独立结构 IS independent structure 两个单句在结构上彼此独立
核心关系 HED head 指整个句子的核心

语义角色类型

语义角色类型 说明
ADV adverbial, default tag ( 附加的,默认标记 )
BNE beneficiary ( 受益人 )
CND condition ( 条件 )
DIR direction ( 方向 )
DGR degree ( 程度 )
EXT extent ( 扩展 )
FRQ frequency ( 频率 )
LOC locative ( 地点 )
MNR manner ( 方式 )
PRP purpose or reason ( 目的或原因 )
TMP temporal ( 时间 )
TPC topic ( 主题 )
CRD coordinated arguments ( 并列参数 )
PRD predicate ( 谓语动词 )
PSR possessor ( 持有者 )
PSE possessee ( 被持有 )

开源协议

  1. 语言技术平台面向国内外大学、中科院各研究所以及个人研究者免费开放源代码,但如上述机构和个人将该平台用于商业目的(如企业合作项目等)则需要付费。
  2. 除上述机构以外的企事业单位,如申请使用该平台,需付费。
  3. 凡涉及付费问题,请发邮件到 car@ir.hit.edu.cn 洽商。
  4. 如果您在LTP基础上发表论文或取得科研成果,请您在发表论文和申报成果时声明“使用了哈工大社会计算与信息检索研究中心研制的语言技术平台(LTP)”,参考文献中加入以下论文: Wanxiang Che, Zhenghua Li, Ting Liu. LTP: A Chinese Language Technology Platform. In Proceedings of the Coling 2010:Demonstrations. 2010.08, pp13-16, Beijing, China. 同时,发信给 car@ir.hit.edu.cn ,说明发表论文或申报成果的题目、出处等。

索引及表格