08_采用LTP抽取图谱三元组

在这里插入图片描述

博文配套视频课程:自然语言处理与知识图谱


图谱三元组概述

知识图谱的数据是通过三元组(主语,谓词,宾语)的方式进行组织,每一个三元组代表一条知识,这些三元组并不是杂乱无章的堆砌在知识图谱中,而是按照一定的逻辑组织起来的。

  1. 数据模型层:勾画出来的数据组织模式 (实体、属性、关系)
  2. 数据层:数据是一条条的知识,它是依据数据模型组织起来的。我们可以把数据模型看作是骨架,把具体数据看作是肌肉

在这里插入图片描述

自顶向下构建

是指先确定知识图谱的数据模型,再根据模型去填充具体数据,最终形成知识图谱。一般适用于垂直行业知识图谱的构建, 适用于那些知识内容比较明确,关系比较清晰的领域构建知识图谱,最好有行业专家介入。

  1. 新冠疫情
  2. 电商商品数据

自下向上构建

是先按照三元组的方式收集具体数据,然后根据数据内容来提炼数据模型。 采用这种方式构建知识图谱,是因为在开始构建知识图谱的时候,还不清楚收集数据的范围,也不清楚数据怎么使用,就是先把所有的数据收集起来,形成一个庞大的数据集,然后再根据数据内容,总结数据的特点,将数据进行整理、分析、归纳、总结,形成一个框架,也就是数据模型

  1. 评论数据抽取
  2. 百科词条抽取

语义角色构建图谱

无论是通过词性、语义还是依存语法分析。基本都需要按照下面三个步骤来实现

  1. 分句
  2. 分词
  3. 词性标注 / 语义角色 / 依存语法分析
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结果如下:

在这里插入图片描述

在这里插入图片描述

  • 5
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值