本系列文章主要结合Python语言实现知识图谱构建相关工程,具有一定创新性和实用性,非常希望各位博友交流讨论,相互促进成长。第一篇文章主要介绍哈工大pyltp工具,包括安装过程、中文分词等;第二篇文章主要讲解词性标注、实体识别、依存句法分析和语义角色标注。
知识图谱系列文章:
[知识图谱实战篇] 一.数据抓取之Python3抓取JSON格式的电影实体
[知识图谱实战篇] 二.Json+Seaborn可视化展示电影实体
[知识图谱实战篇] 三.Python提取JSON数据、HTML+D3构建基本可视化布局
[知识图谱实战篇] 四.HTML+D3+CSS绘制关系图谱
[知识图谱实战篇] 五.HTML+D3添加鼠标响应事件显示相关节点及边
[知识图谱实战篇] 六.HTML+D3实现点击节点显示相关属性及属性值
[知识图谱实战篇] 七.HTML+D3实现关系图谱搜索功能
[知识图谱实战篇] 八.HTML+D3绘制时间轴线及显示实体
环境下载地址:https://download.csdn.net/download/eastmount/11226539
原文地址:
[Python知识图谱] 一.哈工大pyltp安装及中文分句、中文分词、导入词典基本用法
词性标注(Part-Of-Speech tagging, POS tagging)也被称为语法标注(grammatical tagging)或词类消疑(word-category disambiguation),是语料库语言学(corpus linguistics)中将语料库内单词的词性按其含义和上下文内容进行标记的文本数据处理技术。
pyltp词性标注与分词模块相同,将词性标注任务建模为基于词的序列标注问题。对于输入句子的词序列,模型给句子中的每个词标注一个标识词边界的标记。在LTP中,采用的北大标注集。
完整代码
# -*- coding: utf-8 -*-
from pyltp import SentenceSplitter
from pyltp import Segmentor
from pyltp import Postagger
from pyltp import NamedEntityRecognizer
ldir='AgriKG\\ltp\\cws.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='AgriKG\\ltp\\pos.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 Description 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 descriptive words 描写,叙述的词 瑟瑟,匆匆
命名实体识别(Named Entity Recognition,简称NER),又称作“专名识别”,是指识别文本中具有特定意义的实体,主要包括人名、地名、机构名、专有名词等。命名实体识别是信息提取、问答系统、句法分析、机器翻译、面向Semantic Web的元数据标注等应用领域的重要基础工具,在自然语言处理技术走向实用化的过程中占有重要地位。
在哈工大Pyltp中,NE识别模块的标注结果采用O-S-B-I-E标注形式,其含义如下(参考):
LTP中的NE 模块识别三种NE,分别为人名(Nh)、机构名(Ni)、地名(Ns)。
完整代码
# -*- coding: utf-8 -*-
from pyltp import SentenceSplitter
from pyltp import Segmentor
from pyltp import Postagger
from pyltp import NamedEntityRecognizer
ldir='AgriKG\\ltp\\cws.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='AgriKG\\ltp\\pos.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='AgriKG\\ltp\\ner.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 -*-
from pyltp import SentenceSplitter
from pyltp import Segmentor
from pyltp import Postagger
from pyltp import Parser
from pyltp import NamedEntityRecognizer
ldir = 'AgriKG\\ltp\\cws.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 = 'AgriKG\\ltp\\pos.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 = 'AgriKG\\ltp\\ner.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 = 'AgriKG\\ltp\\parser.model'
parser = Parser() #初始化命名实体实例
parser.load(parmodel) #加载模型
arcs = parser.parse(words, postags) #句法分析
#输出结果
print(words)
print("\t".join("%d:%s" % (arc.head, arc.relation) for arc in arcs))
rely_id = [arc.head for arc in arcs] # 提取依存父节点id
relation = [arc.relation for arc in arcs] # 提取依存关系
heads = ['Root' if id == 0 else words[id-1] for id in rely_id] # 匹配依存父节点词语
for i in range(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。
该部分代码仅供博友们参考,作者还在深入研究中。
#语义角色标注
from pyltp import SementicRoleLabeller
srlmodel = 'AgriKG\\ltp\\pisrl.model'
labeller = SementicRoleLabeller() #初始化实例
labeller.load(srlmodel) #加载模型
words = ['元芳', '你', '怎么', '看']
postags = ['nh', 'r', 'r', 'v']
arcs = parser.parse(words, postags) #依存句法分析
#arcs使用依存句法分析的结果
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() #释放模型
输出结果如下:
3 A0:(1,1)ADV:(2,2)
上面的例子,由于结果输出一行,所以“元芳你怎么看”有一组语义角色。 其谓词索引为3,即“看”。这个谓词有三个语义角色,范围分别是(0,0)即“元芳”,(1,1)即“你”,(2,2)即“怎么”,类型分别是A0、A0、ADV。
希望这篇基础性文章对你有所帮助,如果有错误或不足之处,还请海涵。
你好!六月。
这些年通过CSDN认识了很多志同道合的朋友,也有很多编程领域的大佬,每天都感觉自己差距还很大,优秀的很多。很高兴认识这些素未谋面的新朋友。靡不有初,鲜克有终,一起加油。coding~
(By:Eastmount 2019-06-17 中午12点写于花溪 https://blog.csdn.net/Eastmount )