APP下载

从 0 到 1 | 手把手教你如何使用哈工大 NLP 工具 —— PyLTP _pytltp

消息来源:baojiabao.com 作者: 发布时间:2024-05-14

报价宝综合消息从 0 到 1 | 手把手教你如何使用哈工大 NLP 工具 —— PyLTP _pytltp

作者 | 杨秀璋

来源 | CSDN 部落格(CSDN id:Eastmount)

(本文经作者授权,此系列文章整理后微信平台首发于AI科技大本营)

【导语】此文是作者基于 Python 构建知识图谱的系列实践教程,具有一定创新性和实用性。文章前半部分内容先介绍哈工大 pytltp 工具,包括安装过程、中文分词、词性标注和实体识别的一些基本用法;后半部分内容讲解词性标注、实体识别、依存句法分析和语义角色标注及程式码实现。

哈工大LTP

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

LTP开发档案:

https://ltp.readthedocs.io/zh_CN/latest/index.html

语言云LTP-Cloud:

http://www.ltp-cloud.com/

模型下载地址:

http://ltp.ai/download.html

相信从事NLP、资料探勘、知识图谱等领域的博友都知道哈工大LTP、同义词词林这些工具,该系列文章也会介绍相关的知识,希望对您有所帮助。

此外,再补充另一个线上NLP分析系统,感兴趣的朋友们也可以试一下~

http://ictclas.nlpir.org/nlpir/

pyltp 终极安装

下面介绍 Windows10 Python 环境下 LTP 的扩充套件包 pyltp 安装过程。

1.常见错误

大家通常会呼叫 “pip install pyltp” 安装该扩充套件包,但会遇到各种错误,下面介绍一种可行的方法。

2.安装pyltp包

首先,安装Python3.6环境,如下图所示“python-3.6.7-amd64.exe”。

接着,下载pyltp扩充套件包的whl档案至本地,呼叫CMD环境进行安装,注意需要将所在档案的路径写清楚。

pyltp-0.2.1-cp35-cp35m-win_amd64.whl(对应Python3.5版本)

pyltp-0.2.1-cp36-cp36m-win_amd64.whl(对应Python3.6版本)

pipinstallC:Python36spyltp-0.2.1-cp36-cp36m-win_amd64.whl

whl下载地址:

https://download.csdn.net/download/qq_22521211/10460778

安装过程下图所示,此时表示pyltp安装成功。

注意,如果报错“error:Microsoft Visual C++ 9.0 is required”,则安装下面exe档案。

3.下载模型档案

百度云

https://pan.baidu.com/share/link?shareid=1988562907&uk=2738088569#list/path=%2F

七牛云

http://ltp.ai/download.html

在编写程式码时,需要汇入指定资料夹中的模型,再进行中文分词、词性标注、命名实体识别、依存句法分析、语义角色标注等分析。例如:

#词性标注

pdir='AgriKGltppos.model'

pos = Postagger

pos.load(pdir)

postags = pos.postag(word) #基于分词得到的list将下词性标注

postags = list(postags)

print(u"词性:", postags)

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

讲到这里,哈工大pyltp基本安装成功,接下来将介绍它的基本用法。

中文分句和分词

官方档案:

https://pyltp.readthedocs.io/zh_CN/latest/api.html#id13

实现原理:

https://ltp.readthedocs.io/zh_CN/latest/theory.html#customized-cws-reference-label

1.中文分句

# -*- coding: utf-8 -*-

frompyltp importSentenceSplitter

frompyltp importSegmentor

frompyltp importPostagger

frompyltp importNamedEntityRecognizer

#分句

text = "贵州财经大学要举办大资料比赛吗?那让欧几里得去问问看吧!其实是在贵阳花溪区吧。"

sents = SentenceSplitter.split(text)

print('n'.join(sents))

贵州财经大学要举办大资料比赛吗?

那让欧几里得去问问看吧!

其实是在贵阳花溪区吧。

2.中文分词

# -*- coding: utf-8 -*-

frompyltp importSentenceSplitter

frompyltp importSegmentor

frompyltp importPostagger

frompyltp importNamedEntityRecognizer

text = "贵州财经大学要举办大资料比赛吗?那让欧几里得去问问看吧!其实是在贵阳花溪区吧。"

#中文分词

segmentor = Segmentor #初始化例项

segmentor.load("AgriKGltpcws.model") #载入模型

words = segmentor.segment(text) #分词

print(type(words))

print(' '.join(words))

segmentor.release #释放模型

class'pyltp.VectorOfString'>

贵州 财经 大学 要 举办 大 资料 比赛 吗 ?

那 让 欧 几 里 得 去 问问 看 吧 !

其实 是 在 贵阳 花溪区 吧 。

此时的分词效果并不理想,如 “大资料” 分为了“大”、“资料”,“欧几里得”分为了“欧”、“几”、“里”、“得”,“贵阳花溪区”分为了“贵阳”、“花溪区”等,故需要引入词典进行更为准确的分词。同时,返回值型别是native的VectorOfString型别,可以使用list转换成Python的列表型别。

3.汇入词典中文分词

pyltp 分词支援使用者使用自定义词典。分词外部词典本身是一个文字档案(plain text),每行指定一个词,编码同样须为 UTF-8,比如“word”档案,如下图所示:

# -*- coding: utf-8 -*-

frompyltp importSentenceSplitter

frompyltp importSegmentor

frompyltp importPostagger

frompyltp importNamedEntityRecognizer

ldir='AgriKGltpcws.model'#分词模型

dicdir='word'#外部字典

text = "贵州财经大学要举办大资料比赛吗?那让欧几里得去问问看吧!其实是在贵阳花溪区吧。"

#中文分词

segmentor = Segmentor #初始化例项

segmentor.load_with_lexicon(ldir, 'word') #载入模型

words = segmentor.segment(text) #分词

print(' '.join(words)) #分词拼接

words = list(words) #转换list

print(u"分词:", words)

segmentor.release #释放模型

输出结果如下所示,它将“大资料”、“欧几里得”、“贵阳花溪区”进行了词典匹配,再进行相关分词,但是“贵州财经大学”仍然划分为“贵州”、“财经”、“大学”。Why?

贵州 财经 大学 要 举办 大资料 比赛 吗 ?

那 让 欧几里得 去 问问 看 吧 !

其实 是 在 贵阳花溪区 吧 。

分词: ['贵州', '财经', '大学', '要', '举办', '大资料', '比赛', '吗', '?',

'那', '让', '欧几里得', '去', '问问', '看', '吧', '!',

'其实', '是', '在', '贵阳花溪区', '吧', '。']

4.个性化分词

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

pyltp 支援使用使用者训练好的个性化模型。关于个性化模型的训练需使用 LTP,详细介绍和训练方法请参考 个性化分词 。在 pyltp 中使用个性化分词模型的示例如下:

# -*- coding: utf-8 -*-

frompyltp importCustomizedSegmentor

customized_segmentor = CustomizedSegmentor #初始化例项

customized_segmentor.load('基本模型', '个性模型') #载入模型

words = customized_segmentor.segment('亚硝酸盐是一种化学物质')

print't'.join(words)

customized_segmentor.release

词性标注(Part-Of-Speech tagging, POS tagging)也被称为语法标注(grammatical tagging)或词类消疑(word-category disambiguation),是语料库语言学(corpus linguistics)中将语料库内单词的词性按其含义和上下文内容进行标记的文字资料处理技术。

pyltp词性标注与分词模组相同,将词性标注任务建模为基于词的序列标注问题。对于输入句子的词序列,模型给句子中的每个词标注一个标识词边界的标记。在LTP中,采用的北大标注集。

完整程式码:

# -*- coding: utf-8 -*-

frompyltp importSentenceSplitter

frompyltp importSegmentor

frompyltp importPostagger

frompyltp importNamedEntityRecognizer

ldir='AgriKGltpcws.model'#分词模型

dicdir='word'#外部字典

text = "贵州财经大学要举办大资料比赛吗?"

#中文分词

segmentor = Segmentor #初始化例项

segmentor.load_with_lexicon(ldir, 'word') #载入模型

words = segmentor.segment(text) #分词

print(text)

print(' '.join(words)) #分词拼接

words = list(words) #转换list

print(u"分词:", words)

segmentor.release #释放模型

#词性标注

pdir='AgriKGltppos.model'

pos = Postagger #初始化例项

pos.load(pdir) #载入模型

postags = pos.postag(words) #词性标注

postags = list(postags)

print(u"词性:", postags)

pos.release #释放模型

data = {"words": words, "tags": postags}

print(data)

输出结果如下图所示,“贵州”词性为“ns”(地理名词 ),“财经”词性为“n”(一般名词),“举办”词性为“v”(动词),“吗”词性为“u”(助词),“?”词性为“wp”(标点)。

贵州财经大学要举办大资料比赛吗?

贵州 财经 大学 要 举办 大资料 比赛 吗 ?

分词: ['贵州', '财经', '大学', '要', '举办', '大资料', '比赛', '吗', '?']

词性: ['ns', 'n', 'n', 'v', 'v', 'n', 'v', 'u', 'wp']

{'words': ['贵州', '财经', '大学', '要', '举办', '大资料', '比赛', '吗', '?'],

'tags': ['ns', 'n', 'n', 'v', 'v', 'n', 'v', 'u', 'wp']}

具体词性为:

Tag Deion Example

a adjective:形容词 美丽

b other noun-modifier:其他的修饰名词 大型, 西式

c conjunction:连词 和, 虽然

d adverb:副词 很

e exclamation:感叹词 哎

g morpheme 茨, 甥

h prefix:字首 阿, 伪

i idiom:成语 百花齐放

j abbreviation:缩写 公检法

k suffix:字尾 界, 率

m number:数字 一, 第一

n general noun:一般名词 苹果

nd direction noun:方向名词 右侧

nh person name:人名 杜甫, 汤姆

ni organization name:公司名 保险公司,中国银行

nl location noun:地点名词 城郊

ns geographical name:地理名词 北京

nt temporal noun:时间名词 近日, 明代

nz other proper noun:其他名词 诺贝尔奖

o onomatopoeia:拟声词 哗啦

p preposition:介词 在, 把,与

q quantity:量词 个

r pronoun:代词 我们

u auxiliary:助词 的, 地

v verb:动词 跑, 学习

wp punctuation:标点 ,。!

ws foreign words:国外词 CPU

x non-lexeme:不构成词 萄, 翱

z deive words 描写,叙述的词 瑟瑟,匆匆

命名实体识别

命名实体识别(Named Entity Recognition,简称NER),又称作“专名识别”,是指识别文字中具有特定意义的实体,主要包括人名、地名、机构名、专有名词等。命名实体识别是资讯提取、问答系统、句法分析、机器翻译、面向Semantic Web的元资料标注等应用领域的重要基础工具,在自然语言处理技术走向实用化的过程中占有重要地位。

在哈工大Pyltp中,NE识别模组的标注结果采用O-S-B-I-E标注形式,其含义如下(参考):

LTP中的NE 模组识别三种NE,分别为人名(Nh)、机构名(Ni)、地名(Ns)。

完整程式码:

# -*- coding: utf-8 -*-

frompyltp importSentenceSplitter

frompyltp importSegmentor

frompyltp importPostagger

frompyltp importNamedEntityRecognizer

ldir='AgriKGltpcws.model'#分词模型

dicdir='word'#外部字典

text = "贵州财经大学要举办大资料比赛吗?"

#中文分词

segmentor = Segmentor #初始化例项

segmentor.load_with_lexicon(ldir, 'word') #载入模型

words = segmentor.segment(text) #分词

print(text)

print(' '.join(words)) #分词拼接

words = list(words) #转换list

print(u"分词:", words)

segmentor.release #释放模型

#词性标注

pdir='AgriKGltppos.model'

pos = Postagger #初始化例项

pos.load(pdir) #载入模型

postags = pos.postag(words) #词性标注

postags = list(postags)

print(u"词性:", postags)

pos.release #释放模型

data = {"words": words, "tags": postags}

print(data)

print(" ")

#命名实体识别

nermodel='AgriKGltpner.model'

reg = NamedEntityRecognizer #初始化命名实体例项

reg.load(nermodel) #载入模型

netags = reg.recognize(words, postags) #对分词、词性标注得到的资料进行实体标识

netags = list(netags)

print(u"命名实体识别:", netags)

#实体识别结果

data={"reg": netags,"words":words,"tags":postags}

print(data)

reg.release

输出结果如下图所示,识别出的三个命名实体分别是:“贵州”(B-Ni)表示一个NE开始-机构名,“财经”(I-Ni)表示一个NE中间-机构名,“大学”(E-Ni)表示一个NE结束-机构名。

PS:虽然汇入指定词典,但“贵州财经大学”分词仍然被分割,后续研究中。

依存句法分析

依存句法是由法国语言学家L.Tesniere最先提出。它将句子分析成一棵依存句法树,描述出各个词语之间的依存关系。也即指出了词语之间在句法上的搭配关系,这种搭配关系是和语义相关联的。如下图所示:

哈工大Pyltp的依存句法关系如下图所示。

https://ltp.readthedocs.io/zh_CN/latest/appendix.html

完整程式码:

# -*- coding: utf-8 -*-

frompyltp importSentenceSplitter

frompyltp importSegmentor

frompyltp importPostagger

frompyltp importParser

frompyltp importNamedEntityRecognizer

ldir = 'AgriKGltpcws.model'#分词模型

dicdir = 'word'#外部字典

text = "贵州财经大学要举办大资料比赛吗?"

#中文分词

segmentor = Segmentor #初始化例项

segmentor.load_with_lexicon(ldir, 'word') #载入模型

words = segmentor.segment(text) #分词

print(text)

print(' '.join(words)) #分词拼接

words = list(words) #转换list

print(u"分词:", words)

segmentor.release #释放模型

#词性标注

pdir = 'AgriKGltppos.model'

pos = Postagger #初始化例项

pos.load(pdir) #载入模型

postags = pos.postag(words) #词性标注

postags = list(postags)

print(u"词性:", postags)

pos.release #释放模型

data = {"words": words, "tags": postags}

print(data)

print(" ")

#命名实体识别

nermodel = 'AgriKGltpner.model'

reg = NamedEntityRecognizer #初始化命名实体例项

reg.load(nermodel) #载入模型

netags = reg.recognize(words, postags) #对分词、词性标注得到的资料进行实体标识

netags = list(netags)

print(u"命名实体识别:", netags)

#实体识别结果

data={"reg": netags,"words":words,"tags":postags}

print(data)

reg.release #释放模型

print(" ")

#依存句法分析

parmodel = 'AgriKGltpparser.model'

parser = Parser #初始化命名实体例项

parser.load(parmodel) #载入模型

arcs = parser.parse(words, postags) #句法分析

#输出结果

print(words)

print("t".join("%d:%s"% (arc.head, arc.relation) forarc inarcs))

rely_id = [arc.head forarc inarcs] # 提取依存父节点id

relation = [arc.relation forarc inarcs] # 提取依存关系

heads = ['Root'ifid == 0elsewords[id-1] forid inrely_id] # 匹配依存父节点词语

fori inrange(len(words)):

print(relation[i] + '('+ words[i] + ', '+ heads[i] + ')')

parser.release

输出结果如下所示,其中ATT表示定中关系,如“贵州-大学”、“财经-大学”;SBV表示主谓关系,如“大学-举办”;ADV表示状中结果“要-举办”;HED表示核心关系“举办-Root”,即“举办大资料”。

补充:arc.head表示依存弧的父节点词的索引,arc.relation表示依存弧的关系。arc.head中的ROOT节点的索引是0,第一个词开始的索引依次为1、2、3。

#语义角色标注

frompyltp importSementicRoleLabeller

srlmodel = 'AgriKGltppisrl.model'

labeller = SementicRoleLabeller #初始化例项

labeller.load(srlmodel) #载入模型

words = ['元芳', '你', '怎么', '看']

postags = ['nh', 'r', 'r', 'v']

arcs = parser.parse(words, postags) #依存句法分析

#arcs使用依存句法分析的结果

roles = labeller.label(words, postags, arcs) #语义角色标注

# 打印结果

forrole inroles:

print(role.index, "".join(

["%s:(%d,%d)"% (arg.name, arg.range.start, arg.range.end) forarg inrole.arguments]))

labeller.release #释放模型

http://md.aclickall.com/

上面的例子,由于结果输出一行,所以“元芳你怎么看”有一组语义角色。其谓词索引为3,即“看”。这个谓词有三个语义角色,范围分别是(0,0)即“元芳”,(1,1)即“你”,(2,2)即“怎么”,型别分别是A0、A0、ADV。

希望这篇基础性文章对你有所帮助,如果有错误或不足之处,还请海涵。

https://blog.csdn.net/Eastmount/article/details/90771843

https://blog.csdn.net/Eastmount/article/details/92440722

最近,大家都在谈论高考志愿报考话题,Python大本营也发起投票,欢迎大家与我们交流。(*本文经作者授权微信平台首发于AI科技大本营,转载请微信联络1092722531)

【End】

2019-06-30 12:45:00

相关文章