前言
NLTK是使用最广泛的自然语言处理工具集,我最开始的时候也是想用它的,但是后来发现中文效果并不好,你如果翻译成了英文,文章意思根本就不一样了。
推荐使用哈工大的LTP自然语言处理平台http://www.ltp-cloud.com/,我们使用pyltp包进行操作
安装包
pip install pyltp
不成功的话直接下载whl文件,使用whl文件安装,不过这是64位的3.6使用版本,为了挣点积分,我放在了CSDN上,下载链接如下
https://wwx.lanzoux.com/i7QnTigy0gj
# pyltp官方文档
https://pyltp.readthedocs.io/zh_CN/latest/
分句
# -*- coding: utf-8 -*-
from pyltp import SentenceSplitter
sents = SentenceSplitter.split('元芳你怎么看?我就趴窗口上看呗!') # 分句
print('\n'.join(sents))
分词
# -*- coding: utf-8 -*-
from pyltp import Segmentor
segmentor = Segmentor() # 初始化实例
segmentor.load('ltp_data_v3.4.0/cws.model') # 加载模型
words = segmentor.segment('元芳你怎么看') # 分词
print(list(words))
segmentor.release() # 释放模型
除此之外。pyltp还支持使用分词外部词典,使用个性化分词模型,使用个性化分词模型同时使用外部词典分词,大家有兴趣可以看看官网
词性标注
词性标注一般是作为中间结果,然后来做依存句法分析和语义角色标注的
# -*- coding: utf-8 -*-
from pyltp import Postagger
postagger = Postagger() # 初始化实例
postagger.load('ltp_data_v3.4.0/pos.model') # 加载模型
words = ['元芳', '你', '怎么', '看'] # 分词结果
postags = postagger.postag(words) # 词性标注
print(list(postags))
postagger.release() # 释放模型
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 | 萄, 翱 |
当然,pyltp支持使用词性标注外部词典进行个性化的词性标注,详情见官方文档
命名实体识别
# -*- coding: utf-8 -*-
from pyltp import NamedEntityRecognizer
recognizer = NamedEntityRecognizer() # 初始化实例
recognizer.load('ltp_data_v3.4.0/ner.model') # 加载模型
words = ['元芳', '你', '怎么', '看']
postags = ['nh', 'r', 'r', 'v']
netags = recognizer.recognize(words, postags) # 命名实体识别
print (list(netags))
recognizer.release() # 释放模型
LTP 采用 BIESO 标注体系。B 表示实体开始词,I表示实体中间词,E表示实体结束词,S表示单独成实体,O表示不构成命名实体。
LTP 提供的命名实体类型为:人名(Nh)、地名(Ns)、机构名(Ni)。
B、I、E、S位置标签和实体类型标签之间用一个横线 -
相连;O标签后没有类型标签。
语义角色类型
关系类型 | Tag | Description | Example |
---|---|---|---|
ARG0 | causers or experiencers | 施事者、主体、触发者 | [政府 ARG0]鼓励个人投资服务业。 |
ARG1 | patient | 受事者 | 政府鼓励[个人 ARG1]投资服务业。 |
ARG2 | range | 语义角色2 | 政府鼓励个人[投资服务业 ARG2]。 |
ARG3 | starting point | 语义角色3 | 巴基斯坦[对谈判前景 ARG3]表示悲观。 |
ARG4 | end point | 语义角色4 | 产检部门将产检时间缩短到[一至三天 ARG4]。 |
ADV | adverbial | 状语 | 我们[即将 ADV]迎来新年。 |
BNF | beneficiary | 受益人 | 义务[为学童及老师 BNF]做超音波检查 。 |
CND | condition | 条件 | [如果早期发现 CND],便能提醒当事人注意血压的变化。 |
CRD | coordinated arguments | 并列 | 跟南韩、[跟美国 CRD]谋求和平关系的举动也更加积极。 |
DGR | degree | 程度 | 贫铀弹含有放射性比铀强[20万倍 DGR]。 |
DIR | direction | 方向 | [从此处 DIR] 我们可以发现寇克斯报告的精髓。 |
DIS | discourse marker | 会话标记 | 警方上午针对目击者做笔录,[而 DIS]李士东仍然不见踪影。 |
EXT | extent | 范围 | 回归3年多[来 EXT] ,香港成为台商对大陆贸易的财务运作及资金调度中心。 |
FRQ | frequency | 频率 | 这类听证会在赖昌兴拘押期间每30天举行[一次 FRQ]。 |
LOC | locative | 地点 | 请听美国之音特邀记者康妮[在加拿大温哥华 LOC]发来的报道。 |
MNR | manner | 方式 | 以便他能继续[作为俄罗斯官员 MNR]从事他在一个特殊机构中的工作。 |
PRP | purpose or reason | 目的 | 执政党和在野党[为了应付这场攻守战 PRP]都发出了紧急动员令。 |
QTY | quantity | 数量 | 每年创汇[100万 QTY]美元。 |
TMP | temporal | 时间 | [下星期 TMP]布什将提出一项周密计划。 |
TPC | topic | 话题 | [这么大的事情 TPC],你怎么不和我说? |
PRD | predicate | 谓语动词 | |
PSR | possessor | 持有者 | |
PSE | possessee | 被持有 |
依存句法分析
就是哪些词和哪些词之间有什么关系
# -*- coding: utf-8 -*-
import os
from pyltp import Parser
parser = Parser() # 初始化实例
parser.load('ltp_data_v3.4.0/parser.model') # 加载模型
words = ['元芳', '你', '怎么', '看']
postags = ['nh', 'r', 'r', 'v']
arcs = parser.parse(words, postags) # 句法分析
print("\t".join("%d:%s" % (arc.head, arc.relation) for arc in arcs))
parser.release() # 释放模型
'''
4:SBV 4:SBV 4:ADV 0:HED
'''
arc.head
表示依存弧的父节点词的索引。ROOT节点的索引是0,第一个词开始的索引依次为1、2、3…
arc.relation
表示依存弧的关系。
依存句法关系如下
关系类型 | 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 | 指整个句子的核心 |
语义角色标注
# -*- coding: utf-8 -*-
from pyltp import SementicRoleLabeller
labeller = SementicRoleLabeller() # 初始化实例
labeller.load('ltp_data_v3.4.0/pisrl.model') # 加载模型,windows环境下自行下载pisrl_win.model这个模型
words = ['元芳', '你', '怎么', '看']
postags = ['nh', 'r', 'r', 'v']
# arcs 使用依存句法分析的结果
arcs = parser.parse(words, postags) # 句法分析
roles = labeller.label(words, postags, 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() # 释放模型