Python下的自然语言处理利器-LTP语言技术平台 pyltp 学习手札

1 什么是pyltp

语言技术平台(LTP) 是由 哈工大社会计算与信息检索研究中心 11

年的持续研发而形成的一个自然语言处理工具库,其提供包括中文分词、词性标注、命名实体识别、依存句法分析、语义角色标注等丰富、

高效、精准的自然语言处理技术。LTP制定了基于XML的语言处理结果表示,并在此基础上提供了一整套自底向上的丰富而且高效的中文语言处理模块(包括词法、句法、语义等6项中文处理核心技术),以及基于动态链接库(Dynamic

Link Library, DLL)的应用程序接口,可视化工具,并且能够以网络服务(Web Service)的形式进行使用。

默认上来说,ltp平台是基于C++的,但是大家也都知道我是不用C++的,所以我看到了其python的版本,pyltp,于是拿来写了个手札。

我目前主要用到的部分可能还是以中文分词为主,其他后续加上(PS:因为我觉得之前那个不太喜欢)。

NLPIR 汉语分词系统 (PyNLPIR) 学习手札

好了废话不多说,一步一步来,让我们先从安装开始。

这次我首次安装pyltp的平台是windows 10(我的环境osx or windows10 or Ubuntu,一般nlp相关的都是osx或win上,平台相关的都是Ubuntu) + python2.7

1 pyltp 安装

1、使用Pip进行安装

关于Pip,已经不用重复太多了,快速简单,我也一直用,这里也一样。

$ pip install pyltp

这里说一下我遇到的问题,缺少Visual C++ 9.0:

Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall.bat). Get it from http://aka.ms/vcpython27

解决方式(2选1):

1、安装一个Visual Studio 2008 只能是这个版本,网上说12,我的15都不行

2、安装一个Micorsoft Visual C++ Compiler for Python 2.7,或者这个链接直接下载,但是可能会失效 安装完成后,重新运行那个安装指令就可以了

2、模型下载

安装完成后,我们需要安装pyltp的模型,从百度云这里下载 ,注意模型版本必须要和pynlp的版本对应

我写文的时候,使用的是3.3.1,注意网盘里面有个zip和tar两种,选择一个你能下载的就可以了

pyltp 版本:0.1.9 LTP 版本:3.3.2 模型版本:3.3.1

3 配置

当我们完成了安装和模型下载后,就需要做一些相关的配置,保证pyltk可以使用到对应的模型

这里所谓的配置,就是在代码中,需要预先load一下

1、将上述的模型压缩包解压到指定的文件夹

2、在使用时,使用类似的方式的加载模型,注意替换自己的模型地址

segmentor.load(‘/path/to/your/model‘)  # 加载模型

3 pyltk 使用

分句

分句,也就是将一片文本分割为独立的句子,不需要加载模型的哦,我看了一下应该就是按照符号来分割的。

# -*- coding: utf-8 -*-
from pyltp import SentenceSplitter
#分句,也就是将一片文本分割为独立的句子
def sentence_splitter(sentence=‘你好,你觉得这个例子从哪里来的?当然还是直接复制官方文档,然后改了下这里得到的。‘):
    sents = SentenceSplitter.split(sentence)  # 分句
    print ‘\n‘.join(sents)

#测试分句子
sentence_splitter()

运行结果

分词

关于分词是什么,就不用多说了,直接看。

注意分词的模型默认是:cws.model

# -*- coding: utf-8 -*-
from pyltp import Segmentor
#分词
def segmentor(sentence=‘你好,你觉得这个例子从哪里来的?当然还是直接复制官方文档,然后改了下这里得到的。我的微博是MebiuW,转载请注明来自MebiuW!‘):
    segmentor = Segmentor()  # 初始化实例
    segmentor.load(‘C:\\Users\\72770\\Documents\\Chatbot\\ltp-data-v3.3.1\\ltp_data\\cws.model‘)  # 加载模型
    words = segmentor.segment(sentence)  # 分词
    #默认可以这样输出
    # print ‘\t‘.join(words)
    # 可以转换成List 输出
    words_list = list(words)
    for word in words_list:
        print word
    segmentor.release()  # 释放模型
    return words_list
#测试分词
segmentor()

运行结果

分词-高级

注意此部分,我是直接复制了官方文档

以下代码中的XX模型,请自定替换为模型的地址!!!

pyltp 分词支持用户使用自定义词典。分词外部词典本身是一个文本文件(plain text),每行指定一个词,编码同样须为 UTF-8,样例如下所示

苯并芘
亚硝酸盐

示例如下

# -*- coding: utf-8 -*-
from pyltp import Segmentor
segmentor = Segmentor()  # 初始化实例
segmentor.load_with_lexicon(‘模型地址, ‘用户字典‘) # 加载模型
words = segmentor.segment(‘亚硝酸盐是一种化学物质‘)
print ‘\t‘.join(words)
segmentor.release()

使用个性化分词模型

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

pyltp 支持使用用户训练好的个性化模型。关于个性化模型的训练需使用 LTP,详细介绍和训练方法请参考 个性化分词 。

在 pyltp 中使用个性化分词模型的示例如下

# -*- coding: utf-8 -*-
from pyltp import CustomizedSegmentor
customized_segmentor = CustomizedSegmentor()  # 初始化实例
customized_segmentor.load(‘基本模型‘, ‘个性模型‘) # 加载模型
words = customized_segmentor.segment(‘亚硝酸盐是一种化学物质‘)
print ‘\t‘.join(words)
customized_segmentor.release()

同时使用外部字典的话

# -*- coding: utf-8 -*-
from pyltp import CustomizedSegmentor
customized_segmentor = CustomizedSegmentor()  # 初始化实例
customized_segmentor.load_with_lexicon(‘基本模型‘, ‘个性模型‘, ‘用户字典‘) # 加载模型
words = customized_segmentor.segment(‘亚硝酸盐是一种化学物质‘)
print ‘\t‘.join(words)
customized_segmentor.release()

#词性标注

词性标注也是我们经常遇到的任务,也不多解释了

词性标注需要输入分词后的结果,所以请先参考下之前的按个分词部分,其返回的结果可以作为输入直接标注

# -*- coding: utf-8 -*-
from pyltp import Segmentor
from pyltp import Postagger
#分词
def segmentor(sentence=‘你好,你觉得这个例子从哪里来的?当然还是直接复制官方文档,然后改了下这里得到的。我的微博是MebiuW,转载请注明来自MebiuW!‘):
    segmentor = Segmentor()  # 初始化实例
    segmentor.load(‘C:\\Users\\72770\\Documents\\Chatbot\\ltp-data-v3.3.1\\ltp_data\\cws.model‘)  # 加载模型
    words = segmentor.segment(sentence)  # 分词
    #默认可以这样输出
    # print ‘\t‘.join(words)
    # 可以转换成List 输出
    words_list = list(words)
    segmentor.release()  # 释放模型
    return words_list

def posttagger(words=segmentor()):
    postagger = Postagger() # 初始化实例
    postagger.load(‘C:\\Users\\72770\\Documents\\Chatbot\\ltp-data-v3.3.1\\ltp_data\\pos.model‘)  # 加载模型
    postags = postagger.postag(words)  # 词性标注
    for word,tag in zip(words,postags):
        print word+‘/‘+tag
    postagger.release()  # 释放模型
#测试标注
posttagger()

运行结果: 前面是词语,后面是词性,词性的表述请参照这里

命名实体识别

命名实体识别,主要是hi识别一些人名,地名,机构名等。

需要前面分词和词性标注作为输入

#注意,从这里开始,因为牵扯到的代码比较多,所以不是完成的代码,只是片段,要保证正常运行,请参照最后的完整代码附录
# -*- coding: utf-8 -*-
from pyltp import NamedEntityRecognizer
def ner(words, postags):
    recognizer = NamedEntityRecognizer() # 初始化实例
    recognizer.load(‘C:\\Users\\72770\\Documents\\Chatbot\\ltp-data-v3.3.1\\ltp_data\\ner.model‘)  # 加载模型
    netags = recognizer.recognize(words, postags)  # 命名实体识别
    for word, ntag in zip(words, netags):
        print word + ‘/‘ + ntag
    recognizer.release()  # 释放模型
    return netags

#测试分句子
#sentence_splitter()
#测试分词
words = segmentor(‘我家在昆明,我现在在北京上学。中秋节你是否会想到李白?‘)
#测试标注
tags = posttagger(words)
#命名实体识别
ner(words,tags)

运行结果

命名实体的参照标记,也是请看这里

依存句法分析

依存句法依旧需要之前的两个输入,words 和 postags 分别为分词和词性标注的结果。

arc.head 表示依存弧的父节点词的索引,arc.relation 表示依存弧的关系。其具体的表述看这里

# -*- coding: utf-8 -*-
from pyltp import Parser
def parse(words, postags):
    parser = Parser() # 初始化实例
    parser.load(‘C:\\Users\\72770\\Documents\\Chatbot\\ltp-data-v3.3.1\\ltp_data\\parser.model‘)  # 加载模型
    arcs = parser.parse(words, postags)  # 句法分析
    print "\t".join("%d:%s" % (arc.head, arc.relation) for arc in arcs)
    parser.release()  # 释放模型

#测试分句子
#sentence_splitter()
#测试分词
words = segmentor(‘我家在昆明,我现在在北京上学。中秋节你是否会想到李白?还有,微博是MebiuW‘)
#测试标注
tags = posttagger(words)
#依存句法识别
parse(words,tags)

运行结果

语义角色标注

arg.name 表示语义角色关系,arg.range.start 表示起始词位置,arg.range.end 表示结束位置。

# -*- coding: utf-8 -*-
from pyltp import SementicRoleLabeller
def role_label(words, postags, netags, arcs):
    labeller = SementicRoleLabeller() # 初始化实例
    labeller.load(‘C:\\Users\\72770\\Documents\\Chatbot\\ltp-data-v3.3.1\\ltp_data\\srl‘)  # 加载模型
    roles = labeller.label(words, postags, netags, arcs)  # 语义角色标注
    for role in roles:
        print role.index, "".join(
            ["%s:(%d,%d)" % (arg.name, arg.range.start, arg.range.end) for arg in role.arguments])
    labeller.release()  # 释放模型
#测试分句子
#sentence_splitter()
#测试分词
words = segmentor(‘我家在昆明,我现在在北京上学。中秋节你是否会想到李白?还有,微博是MebiuW‘)
#测试标注
tags = posttagger(words)
#命名实体识别
netags = ner(words,tags)
#依存句法识别
arcs = parse(words,tags)
#j角色标注
roles = role_label(words,tags,netags,arcs)

运行结果:

角色对照看这里

结语

有点累,突然写不动了,就先写这些吧,有问题我们评论或者新浪微博@MebiuW 交流

参考

1、Pyltk 官方文档

参考本篇完整代码

可能有些打印有点杂乱,见谅

# -*- coding: utf-8 -*-
#作者:MebiuW
#微博:@MebiuW
#python 版本:2.7
#时间 2016/9/10
from pyltp import SentenceSplitter
from pyltp import Segmentor
from pyltp import Postagger
from pyltp import SementicRoleLabeller
from pyltp import NamedEntityRecognizer
from pyltp import Parser

#分词
def segmentor(sentence=‘你好,你觉得这个例子从哪里来的?当然还是直接复制官方文档,然后改了下这里得到的。我的微博是MebiuW,转载请注明来自MebiuW!‘):
    segmentor = Segmentor()  # 初始化实例
    segmentor.load(‘C:\\Users\\72770\\Documents\\Chatbot\\ltp-data-v3.3.1\\ltp_data\\cws.model‘)  # 加载模型
    words = segmentor.segment(sentence)  # 分词
    #默认可以这样输出
    print ‘\t‘.join(words)
    # 可以转换成List 输出
    words_list = list(words)
    segmentor.release()  # 释放模型
    return words_list

def posttagger(words):
    postagger = Postagger() # 初始化实例
    postagger.load(‘C:\\Users\\72770\\Documents\\Chatbot\\ltp-data-v3.3.1\\ltp_data\\pos.model‘)  # 加载模型
    postags = postagger.postag(words)  # 词性标注
    for word,tag in zip(words,postags):
        print word+‘/‘+tag
    postagger.release()  # 释放模型
    return postags

#分句,也就是将一片文本分割为独立的句子
def sentence_splitter(sentence=‘你好,你觉得这个例子从哪里来的?当然还是直接复制官方文档,然后改了下这里得到的。我的微博是MebiuW,转载请注明来自MebiuW!‘):
    sents = SentenceSplitter.split(sentence)  # 分句
    print ‘\n‘.join(sents)

#命名实体识别
def ner(words, postags):
    recognizer = NamedEntityRecognizer() # 初始化实例
    recognizer.load(‘C:\\Users\\72770\\Documents\\Chatbot\\ltp-data-v3.3.1\\ltp_data\\ner.model‘)  # 加载模型
    netags = recognizer.recognize(words, postags)  # 命名实体识别
    for word, ntag in zip(words, netags):
        print word + ‘/‘ + ntag
    recognizer.release()  # 释放模型
    return netags

#依存语义分析
def parse(words, postags):
    parser = Parser() # 初始化实例
    parser.load(‘C:\\Users\\72770\\Documents\\Chatbot\\ltp-data-v3.3.1\\ltp_data\\parser.model‘)  # 加载模型
    arcs = parser.parse(words, postags)  # 句法分析
    print "\t".join("%d:%s" % (arc.head, arc.relation) for arc in arcs)
    parser.release()  # 释放模型
    return arcs

#角色标注
def role_label(words, postags, netags, arcs):
    labeller = SementicRoleLabeller() # 初始化实例
    labeller.load(‘C:\\Users\\72770\\Documents\\Chatbot\\ltp-data-v3.3.1\\ltp_data\\srl‘)  # 加载模型
    roles = labeller.label(words, postags, netags, arcs)  # 语义角色标注
    for role in roles:
        print role.index, "".join(
            ["%s:(%d,%d)" % (arg.name, arg.range.start, arg.range.end) for arg in role.arguments])
    labeller.release()  # 释放模型
#测试分句子
print(‘******************测试将会顺序执行:**********************‘)
sentence_splitter()
print(‘###############以上为分句子测试###############‘)
#测试分词
words = segmentor(‘我家在昆明,我现在在北京上学。中秋节你是否会想到李白?还有,微博是MebiuW‘)
print(‘###############以上为分词测试###############‘)
#测试标注
tags = posttagger(words)
print(‘###############以上为词性标注测试###############‘)
#命名实体识别
netags = ner(words,tags)
print(‘###############以上为命名实体识别测试###############‘)
#依存句法识别
arcs = parse(words,tags)
print(‘###############以上为依存句法测试###############‘)
#角色标注
roles = role_label(words,tags,netags,arcs)
print(‘###############以上为角色标注测试###############‘)
时间: 2024-10-11 21:43:28

Python下的自然语言处理利器-LTP语言技术平台 pyltp 学习手札的相关文章

ZH奶酪:自然语言处理工具LTP语言云怎么调用?

前言 LTP语言云平台 支持分词.词性标注.命名实体识别.依存句法分析.语义角色标注: 支持自定义分词(你提供分词后的数据,它帮你标注),但是不支持自定义词表: 支持C#.Go.Java.JavaScript.Nodejs.PHP.Python.R.Ruby等语言调用: 还有一些错误响应.频率限制.重要说明(这几个我至今也没用到):正文 官方网址:http://www.ltp-cloud.com/ 使用文档:http://www.ltp-cloud.com/document/ 在线演示:http

编译哈工大语言技术平台云LTP(C++)源码及LTP4J(Java)源码

转自:编译哈工大语言技术平台云LTP(C++)源码及LTP4J(Java)源码 JDK:java version “1.8.0_31”Java(TM) SE Runtime Environment (build 1.8.0_31-b13)Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)OS:win7 64bitcmake:V2.8.12/V3.2.2LTP:V3.2.0LTP4J:V1.0Microsoft VS C+

Python下Json和Msgpack序列化比较

Python下Json和Msgpack序列化比较  最近用Python时,遇到了序列化对象的问题,传统的json和新型序列化工具包msgpack都有涉及,于是做一个简单的总结: 通俗的讲:序列化:将对象信息转化为可以存储或传输的形式:反序列化:把这个存储的内容还原成对象. json就不用多做解释了,是一种轻量级的数据交换格式,广泛应用于web开发中.当然也是将对象序列化成符合json规范的格式.网上有一堆堆资料. 官网:http://www.json.org msgpack就有意思了,先看下官方

Python源码剖析笔记0 ——C语言基础

python源码剖析笔记0--C语言基础回顾 要分析python源码,C语言的基础不能少,特别是指针和结构体等知识.这篇文章先回顾C语言基础,方便后续代码的阅读. 1 关于ELF文件 linux中的C编译得到的目标文件和可执行文件都是ELF格式的,可执行文件中以segment来划分,目标文件中,我们是以section划分.一个segment包含一个或多个section,通过readelf命令可以看到完整的section和segment信息.看一个栗子: char pear[40]; static

Python下进程与线程的原理及区别

对于所有的语言都可能会遇到进程和线程的问题,一般情况下线程是由进程产生的,一个进程产生多个线程来按照一定的规则(Python下根据CPU调度算法和全局进程锁)来利用CPU,我们称之为多线程模式:而一个进程在产生的同时,同时会生成一个主线程,如果程序生成多个进程,那么每个进程都会产生一个线程,多个程序按照一定的规则去利用CPU,我们称之为多进程模式.                 Python下多线程与多进程关系图原理如下所示:

Python下opencv使用笔记(一)(图像简单读取、显示与储存)

写在之前 从去年開始关注python这个软件,途中间间断断看与学过一些关于python的东西.感觉python确实是一个简单优美.easy上手的脚本编程语言,众多的第三方库使得python异常的强大.能够处理很多不同的问题,同一时候它的很多开源免费的库使得python的使用也是十分的广泛. 在科学计算.数据处理与图像领域,自己以前一直在使用matlab.感觉matlab也是一个语言优美.简单方便的编程语言,都说matlab与python在某些领域是非常类似的,确实是这样,就科学计算.数据处理上真

python 下的crc16计算模块 XCRC16

又一次突然遇到用python处理modbus通信而需要crc16校验的问题,当时在百度上没找到,在google上找到了一个外国人开发的python包,结果安装好了之后发现校验的不正确(可能是使用的模式串不一样,xcrc16的模式串为0xa001),后来事情过去了就写了一个包弥补一下,xcrc16 的意思是 extend crc->xcrc ,也是我的第一个开源项目,如果大家使用程序遇到什么情况也麻烦通知我下,我会第一时间进行维护. 介绍: xcrc16 模块是为了解决crc16校验问题而写 目前

在python下学习libsvm

1.下载libsvm,python,gnuplot(链接网上全有,压缩包自己保留着) 2.在python上的实现(主要用截图的形式展现) (1)输入命令寻求最优参数 (2) 参数c,g输出结果 gnuplot输出图像 (3)最后输入训练数据,训练数据,通过建立模型进行预测 大概也就这样了,grid.py里面需要改下gnuplot的路径 在python下学习libsvm,布布扣,bubuko.com

python下通过os模块和shutil模块进行文件处理方式

python下通过os模块和shutil模块进行文件处理方式 得到当前工作目录路径:os.getcwd() 获取指定目录下的所有文件和目录名:os.listdir(dir) 删除文件:os.remove(file) 删除多个目录:os.removedirs(r"/home") 检测路径是否为文件:os.path.isfile(path) 检测路径是否为目录:os.path.isdir(path) 判断是否为绝对路径:os.path.isabs(path) 检测路径是否存在:os.pat