赞
踩
语言技术平台(LTP)经过哈工大社会计算与信息检索研究中心 11 年的持续研发和推广, 是国内外最具影响力的中文处理基础平台。它提供的功能包括中文分词、词性标注、命名实体识别、依存句法分析、语义角色标注等。
pyltp 是 LTP 的 Python 封装,同时支持Python2和Python3版本。Python3的安装方法为:
pip3 install pyltp
若pyltp安装失败,可以参考博文:pyltp安装教程及简单使用 - 大明王 - 博客园
在使用该模块前,需要下载完整的模型文件,文件下载地址为:https://pan.baidu.com/share/link?shareid=1988562907&uk=2738088569#list/path=%2F 。pyltp 的所有输入的分析文本和输出的结果的编码均为 UTF-8。模型的数据文件如下:
其中,cws.model用于分词模型,lexicon.txt为分词时添加的用户字典,ner.model为命名实体识别模型,parser.model为依存句法分析模型,pisrl.model为语义角色标注模型,pos为词性标注模型。
pyltp的使用示例项目结构如下:
分句指的是将一段话或一片文章中的文字按句子分开,按句子形成独立的单元。示例的Python代码sentenct_split.py如下:
- from pyltp import SentenceSplitter
-
- # 分句
- doc = '据韩联社12月28日反映,美国防部发言人杰夫·莫莱尔27日表示,美国防部长盖茨将于2011年1月14日访问韩国。' \
- '盖茨原计划从明年1月9日至14日陆续访问中国和日本,目前,他决定在行程中增加对韩国的访问。莫莱尔表示,' \
- '盖茨在访韩期间将会晤韩国国防部长官金宽镇,就朝鲜近日的行动交换意见,同时商讨加强韩美两军同盟关系等问题,' \
- '拟定共同应对朝鲜挑衅和核计划的方案。'
-
- # 分句
- sents = SentenceSplitter.split(doc)
-
- for i, sent in enumerate(sents):
- print(i, sent)
运行结果:
- 0 据韩联社12月28日反映,美国防部发言人杰夫·莫莱尔27日表示,美国防部长盖茨将于2011年1月14日访问韩国。
- 1 盖茨原计划从明年1月9日至14日陆续访问中国和日本,目前,他决定在行程中增加对韩国的访问。
- 2 莫莱尔表示,盖茨在访韩期间将会晤韩国国防部长官金宽镇,就朝鲜近日的行动交换意见,同时商讨加强韩美两军同盟关系等问题,拟定共同应对朝鲜挑衅和核计划的方案。
分词指的是将一句话按词语分开,按词语形成独立的单元。示例的Python代码words_split.py如下:
- import os
- from pyltp import Segmentor
-
-
- cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分词模型路径,模型名称为`cws.model`
- lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 参数lexicon是自定义词典的文件路径
-
- segmentor = Segmentor()
- segmentor.load_with_lexicon(cws_model_path, lexicon_path)
-
- sent = '据韩联社12月28日反映,美国防部发言人杰夫·莫莱尔27日表示,美国防部长盖茨将于2011年1月14日访问韩国。'
- words = segmentor.segment(sent) # 分词
- print(type(words)) # type:是对象
- print('/'.join(words))
-
- segmentor.release()
运行结果:
- <class 'pyltp.VectorOfString'>
- 据/韩联社/12月/28日/反映/,/美/国防部/发言人/杰夫·莫莱尔/27日/表示/,/美/国防部长/盖茨/将/于/2011年/1月/14日/访问/韩国/。
词性标注指的是一句话分完词后,制定每个词语的词性。示例的Python代码postagger.py如下:
- import os
- from pyltp import Segmentor, Postagger
-
- # 分词
- cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分词模型路径,模型名称为`cws.model`
- lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 参数lexicon是自定义词典的文件路径
-
- segmentor = Segmentor()
- segmentor.load_with_lexicon(cws_model_path, lexicon_path)
-
- sent = '据韩联社12月28日反映,美国防部发言人杰夫·莫莱尔27日表示,美国防部长盖茨将于2011年1月14日访问韩国。'
- words = segmentor.segment(sent) # 分词
- print(words) # type: object
-
- # 词性标注
- pos_model_path = os.path.join(os.path.dirname(__file__), 'data/pos.model') # 词性标注模型路径,模型名称为`pos.model`
-
- postagger = Postagger() # 初始化实例
- postagger.load(pos_model_path) # 加载模型
- postags = postagger.postag(words) # 词性标注
-
- for word, postag in zip(words, postags):
- print(word, postag)
-
- # 释放模型
- segmentor.release()
- postagger.release()
-
- '''
- 词性标注结果说明
- https://ltp.readthedocs.io/zh_CN/latest/appendix.html#id3
- '''
运行结果:
- <pyltp.VectorOfString object at 0x000001B4139C9CF0>
- 据 p
- 韩联社 ni
- 12月 nt
- 28日 nt
- 反映 v
- , wp
- 美 j
- 国防部 n
- 发言人 n
- 杰夫·莫莱尔 nh
- 27日 nt
- 表示 v
- , wp
- 美 j
- 国防部长 n
- 盖茨 nh
- 将 d
- 于 p
- 2011年 nt
- 1月 nt
- 14日 nt
- 访问 v
- 韩国 ns
- 。 wp
词性标注结果可参考网址:https://ltp.readthedocs.io/zh_CN/latest/appendix.html 。
命名实体识别(NER)指的是识别出一句话或一段话或一片文章中的命名实体,比如人名,地名,组织机构名。示例的Python代码ner.py如下:
- import os
- from pyltp import Segmentor, Postagger
- from pyltp import NamedEntityRecognizer
-
- # 分词
- cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分词模型路径,模型名称为`cws.model`
- lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 参数lexicon是自定义词典的文件路径
-
- segmentor = Segmentor()
- segmentor.load_with_lexicon(cws_model_path, lexicon_path)
-
- sent = '据韩联社12月28日反映,美国防部发言人杰夫·莫莱尔27日表示,美国防部长盖茨将于2011年1月14日访问韩国。'
- words = segmentor.segment(sent) # 分词
- print(list(words))
-
- # 词性标注
- pos_model_path = os.path.join(os.path.dirname(__file__), 'data/pos.model') # 词性标注模型路径,模型名称为`pos.model`
-
- postagger = Postagger() # 初始化实例
- postagger.load(pos_model_path) # 加载模型
- postags = postagger.postag(words) # 词性标注
- print(list(postags))
-
- # 命名实体识别
- ner_model_path = os.path.join(os.path.dirname(__file__), 'data/ner.model') # 命名实体识别模型路径,模型名称为`pos.model`
-
- recognizer = NamedEntityRecognizer() # 初始化实例
- recognizer.load(ner_model_path) # 加载模型
- # netags = recognizer.recognize(words, postags) # 命名实体识别
- # print(type(netags)) # type: object
-
- # 提取识别结果中的人名,地名,组织机构名
- persons, places, orgs = set(), set(), set()
-
- netags = list(recognizer.recognize(words, postags)) # 命名实体识别
- print(netags)
-
- i = 0
- for tag, word in zip(netags, words):
- j = i
- # 人名
- if 'Nh' in tag:
- if str(tag).startswith('S'):
- persons.add(word)
- elif str(tag).startswith('B'):
- union_person = word
- while netags[j] != 'E-Nh':
- j += 1
- if j < len(words):
- union_person += words[j]
- persons.add(union_person)
- # 地名
- if 'Ns' in tag:
- if str(tag).startswith('S'):
- places.add(word)
- elif str(tag).startswith('B'):
- union_place = word
- while netags[j] != 'E-Ns':
- j += 1
- if j < len(words):
- union_place += words[j]
- places.add(union_place)
- # 机构名
- if 'Ni' in tag:
- if str(tag).startswith('S'):
- orgs.add(word)
- elif str(tag).startswith('B'):
- union_org = word
- while netags[j] != 'E-Ni':
- j += 1
- if j < len(words):
- union_org += words[j]
- orgs.add(union_org)
-
- i += 1
-
- print('人名:', ','.join(persons))
- print('地名:', ','.join(places))
- print('组织机构:', ','.join(orgs))
-
- # 释放模型
- segmentor.release()
- postagger.release()
- recognizer.release()
运行结果:
- ['据', '韩联社', '12月', '28日', '反映', ',', '美', '国防部', '发言人', '杰夫·莫莱尔', '27日', '表示', ',', '美', '国防部长', '盖茨', '将', '于', '2011年', '1月', '14日', '访问', '韩国', '。']
- ['p', 'ni', 'nt', 'nt', 'v', 'wp', 'j', 'n', 'n', 'nh', 'nt', 'v', 'wp', 'j', 'n', 'nh', 'd', 'p', 'nt', 'nt', 'nt', 'v', 'ns', 'wp']
- ['O', 'S-Ni', 'O', 'O', 'O', 'O', 'B-Ni', 'E-Ni', 'O', 'S-Nh', 'O', 'O', 'O', 'S-Ns', 'O', 'S-Nh', 'O', 'O', 'O', 'O', 'O', 'O', 'S-Ns', 'O']
- 人名: 盖茨,杰夫·莫莱尔
- 地名: 韩国,美
- 组织机构: 美国防部,韩联社
命名实体识别结果可参考网址:https://ltp.readthedocs.io/zh_CN/latest/appendix.html 。
依存语法 (Dependency Parsing, DP) 通过分析语言单位内成分之间的依存关系揭示其句法结构。 直观来讲,依存句法分析识别句子中的“主谓宾”、“定状补”这些语法成分,并分析各成分之间的关系。示例的Python代码parser.py代码如下:
- import os
- from pyltp import Segmentor, Postagger, Parser
-
- # 分词
- cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分词模型路径,模型名称为`cws.model`
- lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 参数lexicon是自定义词典的文件路径
-
- segmentor = Segmentor()
- segmentor.load_with_lexicon(cws_model_path, lexicon_path)
-
- sent = '据韩联社12月28日反映,美国防部发言人杰夫·莫莱尔27日表示,美国防部长盖茨将于2011年1月14日访问韩国。'
- words = segmentor.segment(sent) # 分词
- print(list(words))
-
- # 词性标注
- pos_model_path = os.path.join(os.path.dirname(__file__), 'data/pos.model') # 词性标注模型路径,模型名称为`pos.model`
-
- postagger = Postagger() # 初始化实例
- postagger.load(pos_model_path) # 加载模型
- postags = postagger.postag(words) # 词性标注
- print(list(postags))
-
- # 依存句法分析
- par_model_path = os.path.join(os.path.dirname(__file__), 'data/parser.model') # 模型路径,模型名称为`parser.model`
-
- parser = Parser() # 初始化实例
- parser.load(par_model_path) # 加载模型
- arcs = parser.parse(words, postags) # 句法分析
- print(arcs) # type: object
-
- rely_id = [arc.head for arc in arcs] # 提取依存父节点id
- print(rely_id)
- relation = [arc.relation for arc in arcs] # 提取依存关系
- print(relation)
- heads = ['Root' if id == 0 else words[id - 1] for id in rely_id] # 匹配依存父节点词语
- print(heads)
-
- for i in range(len(words)):
- print(relation[i] + '(' + words[i] + ', ' + heads[i] + ')')
-
- # 释放模型
- segmentor.release()
- postagger.release()
- parser.release()
运行结果:
- ['据', '韩联社', '12月', '28日', '反映', ',', '美', '国防部', '发言人', '杰夫·莫莱尔', '27日', '表示', ',', '美', '国防部长', '盖茨', '将', '于', '2011年', '1月', '14日', '访问', '韩国', '。']
- ['p', 'ni', 'nt', 'nt', 'v', 'wp', 'j', 'n', 'n', 'nh', 'nt', 'v', 'wp', 'j', 'n', 'nh', 'd', 'p', 'nt', 'nt', 'nt', 'v', 'ns', 'wp']
- <pyltp.VectorOfParseResult object at 0x000001DDF2F797B0>
- [12, 5, 4, 5, 1, 1, 8, 9, 10, 12, 12, 0, 12, 15, 16, 22, 22, 22, 21, 21, 18, 12, 22, 12]
- ['ADV', 'SBV', 'ATT', 'ADV', 'POB', 'WP', 'ATT', 'ATT', 'ATT', 'SBV', 'ADV', 'HED', 'WP', 'ATT', 'ATT', 'SBV', 'ADV', 'ADV', 'ATT', 'ATT', 'POB', 'VOB', 'VOB', 'WP']
- ['表示', '反映', '28日', '反映', '据', '据', '国防部', '发言人', '杰夫·莫莱尔', '表示', '表示', 'Root', '表示', '国防部长', '盖茨', '访问', '访问', '访问', '14日', '14日', '于', '表示', '访问', '表示']
- ADV(据, 表示)
- SBV(韩联社, 反映)
- ATT(12月, 28日)
- ADV(28日, 反映)
- POB(反映, 据)
- WP(,, 据)
- ATT(美, 国防部)
- ATT(国防部, 发言人)
- ATT(发言人, 杰夫·莫莱尔)
- SBV(杰夫·莫莱尔, 表示)
- ADV(27日, 表示)
- HED(表示, Root)
- WP(,, 表示)
- ATT(美, 国防部长)
- ATT(国防部长, 盖茨)
- SBV(盖茨, 访问)
- ADV(将, 访问)
- ADV(于, 访问)
- ATT(2011年, 14日)
- ATT(1月, 14日)
- POB(14日, 于)
- VOB(访问, 表示)
- VOB(韩国, 访问)
- WP(。, 表示)
依存句法关系:
关系类型 | 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 | 指整个句子的核心 |
依存句法分析结果可参考网址:https://ltp.readthedocs.io/zh_CN/latest/appendix.html 。
语义角色标注是实现浅层语义分析的一种方式。在一个句子中,谓词是对主语的陈述或说明,指出“做什么”、“是什么”或“怎么样,代表了一个事件的核心,跟谓词搭配的名词称为论元。语义角色是指论元在动词所指事件中担任的角色。主要有:施事者(Agent)、受事者(Patient)、客体(Theme)、经验者(Experiencer)、受益者(Beneficiary)、工具(Instrument)、处所(Location)、目标(Goal)和来源(Source)等。示例的Python代码rolelabel.py如下:
- import os
- from pyltp import Segmentor, Postagger, Parser, SementicRoleLabeller
-
- # 分词
- cws_model_path = os.path.join(os.path.dirname(__file__), 'data/cws.model') # 分词模型路径,模型名称为`cws.model`
- lexicon_path = os.path.join(os.path.dirname(__file__), 'data/lexicon.txt') # 参数lexicon是自定义词典的文件路径
-
- segmentor = Segmentor()
- segmentor.load_with_lexicon(cws_model_path, lexicon_path)
-
- sent = '据韩联社12月28日反映,美国防部发言人杰夫·莫莱尔27日表示,美国防部长盖茨将于2011年1月14日访问韩国。'
- words = segmentor.segment(sent) # 分词
- print(list(words))
-
- # 词性标注
- pos_model_path = os.path.join(os.path.dirname(__file__), 'data/pos.model') # 词性标注模型路径,模型名称为`pos.model`
-
- postagger = Postagger() # 初始化实例
- postagger.load(pos_model_path) # 加载模型
- postags = postagger.postag(words) # 词性标注
- print(list(postags))
-
- # 依存句法分析
- par_model_path = os.path.join(os.path.dirname(__file__), 'data/parser.model') # 模型路径,模型名称为`parser.model`
-
- parser = Parser() # 初始化实例
- parser.load(par_model_path) # 加载模型
- arcs = parser.parse(words, postags) # 句法分析
- print(arcs)
-
- # 语义角色标注
- srl_model_path = os.path.join(os.path.dirname(__file__), 'data/pisrl_win.model') # 语义角色标注模型目录路径
-
- labeller = SementicRoleLabeller() # 初始化实例
- labeller.load(srl_model_path) # 加载模型
- roles = labeller.label(words, postags, arcs) # 语义角色标注
- print(roles) # type: object
-
- # 打印结果
- for role in roles:
- print(words[role.index], end=' ')
- print(role.index, "".join(["%s:(%d,%d) " % (arg.name, arg.range.start, arg.range.end) for arg in role.arguments]))
-
- # 释放模型
- segmentor.release()
- postagger.release()
- parser.release()
- labeller.release()
运行结果:
- ['据', '韩联社', '12月', '28日', '反映', ',', '美', '国防部', '发言人', '杰夫·莫莱尔', '27日', '表示', ',', '美', '国防部长', '盖茨', '将', '于', '2011年', '1月', '14日', '访问', '韩国', '。']
- ['p', 'ni', 'nt', 'nt', 'v', 'wp', 'j', 'n', 'n', 'nh', 'nt', 'v', 'wp', 'j', 'n', 'nh', 'd', 'p', 'nt', 'nt', 'nt', 'v', 'ns', 'wp']
- <pyltp.VectorOfParseResult object at 0x0000014214F89750>
- [dynet] random seed: 1145443137
- [dynet] allocating memory: 2000MB
- [dynet] memory allocation done.
- <pyltp.SementicRoles object at 0x0000014214F89870>
- 反映 4 A0:(1,1) A0:(2,3)
- 表示 11 MNR:(0,5) A0:(6,9) TMP:(10,10) A1:(13,22)
- 访问 21 A0:(13,15) ADV:(16,16) TMP:(17,20) A1:(22,22)
如果windows下使用模型pisrl.model会报错,解决办法:
下载这个把pisrl.model替换掉
http://model.scir.yunfutech.com/server/3.4.0/pisrl_win.model
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。