博文配套视频课程:自然语言处理与知识图谱
图谱三元组概述
知识图谱的数据是通过三元组(主语,谓词,宾语)的方式进行组织,每一个三元组代表一条知识,这些三元组并不是杂乱无章的堆砌在知识图谱中,而是按照一定的逻辑组织起来的。
- 数据模型层:勾画出来的数据组织模式 (实体、属性、关系)
- 数据层:数据是一条条的知识,它是依据数据模型组织起来的。我们可以把数据模型看作是骨架,把具体数据看作是肌肉
自顶向下构建
是指先确定知识图谱的数据模型,再根据模型去填充具体数据,最终形成知识图谱。一般适用于垂直行业知识图谱的构建, 适用于那些知识内容比较明确,关系比较清晰的领域构建知识图谱,最好有行业专家介入。
- 新冠疫情
- 电商商品数据
自下向上构建
是先按照三元组的方式收集具体数据,然后根据数据内容来提炼数据模型。 采用这种方式构建知识图谱,是因为在开始构建知识图谱的时候,还不清楚收集数据的范围,也不清楚数据怎么使用,就是先把所有的数据收集起来,形成一个庞大的数据集,然后再根据数据内容,总结数据的特点,将数据进行整理、分析、归纳、总结,形成一个框架,也就是数据模型
- 评论数据抽取
- 百科词条抽取
语义角色构建图谱
无论是通过词性、语义还是依存语法分析。基本都需要按照下面三个步骤来实现
- 分句
- 分词
- 词性标注 / 语义角色 / 依存语法分析
from ltp import LTP
ltp = LTP()
sents = ltp.sent_split(["该僵尸网络包含至少35000个被破坏的Windows系统,攻击者和使用者正在秘密使用这些系统来开采Monero加密货币。该僵尸网络名为“ VictoryGate”,自2019年5月以来一直活跃。"])
# 使用语义角色标注构造关系抽取
def srl_AtoA(sent):
seg, hidden = ltp.seg([sent])
seg = seg[0]
srl = ltp.srl(hidden, keep_empty=False)[0]
results = []
for s in srl:
key = s[0]
values = s[1]
start = ''
end = ''
for value in values:
# 语义角色只需要获取A0,A1
if value[0] == 'A0':
start = ''.join(seg[value[1]:value[2]+1])
if value[0] == 'A1':
end = ''.join(seg[value[1]:value[2]+1])
if start != '' and end != '':
results.append((start,seg[key],end))
return results
for sent in sents:
print('sent:', sent)
results = srl_AtoA(sent)
print('res:', results)
通过语义抽取的结果如下:
res: [('该僵尸网络', '包含', '至少35000个被破坏的Windows系统'), ('攻击者和使用者', '使用', '这些系统'), ('攻击者和使用者', '开采', 'Monero加密货币')]
三元组保存Neo4j
三元组可以保存在类似Neo4j图数据中,下面的案例需要一定的Noo4j基本知识,并且使用到了Python如何操作Neo4j。这块不熟悉的小伙伴可以通过观看视频进行回顾。
from ltp import LTP
ltp = LTP()
# 使用语义角色标注构建和抽取关系
def srl_AtoA(sent):
# 句子进行分词操作
seg,hidden = ltp.seg([sent])
seg = seg[0]
print(seg)
srl = ltp.srl(hidden,keep_empty=False)[0]
print(srl)
results = []
for s in srl:
key = s[0]
values = s[1]
start,end = '',''
for value in values:
print('value:',value)
if value[0] == 'A0':
start = ''.join(seg[value[1]:value[2]+1])
if value[0] == 'A1':
end = ''.join(seg[value[1]:value[2] + 1])
if start!='' and end !='':
results.append([start,seg[key],end])
return results
from py2neo import Node, Graph, Relationship
class DataToNeo4j(object):
"""将excel中数据存入neo4j"""
def __init__(self):
"""建立连接"""
link = Graph("http://localhost:7474/", username="neo4j", password="root")
self.graph = link
# self.graph = NodeMatcher(link)
self.graph.delete_all()
def create_spo(self,result):
start = Node(name = result[0])
end = Node(name = result[2])
self.graph.create(start)
self.graph.create(end)
r1 = Relationship(start, result[1], end)
self.graph.create(r1)
# 分句操作
sents = ltp.sent_split(["该僵尸网络包含至少35000个被破坏的Windows系统,攻击者和使用者正在秘密使用这些系统来开采Monero加密货币。该僵尸网络名为“ VictoryGate”,自2019年5月以来一直活跃。"])
spo = DataToNeo4j()
for sent in sents:
print(sent)
results = srl_AtoA(sent)
print(results)
for result in results:
spo.create_spo(result)
print('-' * 100)
持久化到Neo4j结果如下: