精华内容
下载资源
问答
  • 三元组抽取
    2021-09-22 17:08:29

    前言

    三元组抽取是个很基础的任务了,关于这方面的研究paper很多很多了,这里就罗列一些最新的动态,供不断学习吧。

    ABSA/ASTE

    这是抽取细粒度情感三元组的综述,可以看看:

    细粒度情感三元组抽取任务及其最新进展

    更新中

    更多相关内容
  • 基于 Pytorch 的深度学习三元组抽取
  • 2019年百度的三元组抽取比赛,一个baseline
  • 2019年百度的三元组抽取比赛,“科学空间队”源码
  •  EventTriplesExtraction based on dependency parser and semantic role labeling, 基于依存句法与语义角色标注的事件三元组抽取  文本表示一直是个重要问题,如何以清晰,简介的方式对一个文本信息进行有效表示...
  • 融合对抗主动学习的网络安全知识三元组抽取.pdf
  • 针对当前网络安全领域知识获取中所依赖的流水线模式存在实体识别错误的传播,未考虑实体识别与关系抽取任务间的联系,以及模型训练缺乏标签语料的问题,提出一种融合对抗主动学习的端到端网络安全知识三元组抽取方法...
  • 知识图谱中三元组抽取

    千次阅读 2021-05-24 06:14:21
    这是要解决知识图谱中的其中一个问题:从非结构文本中抽取三元组。 要解决这个问题,总体思路有通过模板抽取、通过模型抽取三元组工业界一般都存储在neo4j中,学术界会采用RDF形式存储。 1结构化数据抽取 定义好...

    内容来自七月算法nlp课程。

    这是要解决知识图谱中的其中一个问题:从非结构文本中抽取三元组。
    要解决这个问题,总体思路有通过模板抽取、通过模型抽取。
    三元组工业界一般都存储在neo4j中,学术界会采用RDF形式存储。

    1结构化数据抽取

    定义好schema。按照schema的格式,把关系型数据转为图数据。

    2 非结构化数据抽取

    2.1 通过模板抽取

    通过模板抽取,这个一般是通过正则实现,课程上不做过多介绍。

    2.2 通过模型抽取

    在这里插入图片描述
    模型的整体结构如图所示,输入是一段文本信息,经过encoder层进行编码,提取出头实体(subject),再对头实体编码并复用文本编码,接下来用了个小trick,同时预测尾实体(object)与关系(predicate),当然你也可以分开先预测尾实体,再预测关系。

    对于实体预测可以使用BIO的方式,也可以采用半指针半标注的方式。

    2.2.1 BIO方式

    2.2.2 半指针半标注方式

    在这里插入图片描述

    模型代码:
    https://github.com/terrifyzhao/spo_extract
    预训练模型
    https://huggingface.co/hfl/chinese-bert-wwm-ext/tree/main

    数据
    https://pan.baidu.com/s/1rNfJ88OD40r26RR0Lg6Geg?at=1621054407864

    展开全文
  • 目前,知识图谱在学术界...笔者之前围绕事件关系三元组抽取,结合语言学背景,尝试了一些朴素方式下的事件关系三元组、事件主谓宾三元组抽取的工作。如: 顺承事件关系三元组抽取,地址: https://github.com/liuh

    目前,知识图谱在学术界如火如荼地进行,但受限于知识图谱各个环节中的性能问题,还尚未能够在工业界大规模运用。而与知识图谱中以实体为知识节点,实体关系为实体关系边对知识进行组织不同,以事件作为节点,事件关系作为节点关联的三元组信息的抽取和应用,当前也是大家在探索的一个方向(即事理图谱,先撇开其建模和应用现状不讲)。
    笔者之前围绕事件关系三元组抽取,结合语言学背景,尝试了一些朴素方式下的事件关系三元组、事件主谓宾三元组抽取的工作。如:
    顺承事件关系三元组抽取,地址:
    https://github.com/liuhuanyong/SequentialEventExtration
    因果事件关系三元组抽取,地址:
    https://github.com/liuhuanyong/CausalityEventExtraction
    复合事件关系三元组抽取,地址:
    https://github.com/liuhuanyong/ComplexEventExtraction
    事件主谓宾三元组抽取,地址:
    https://github.com/liuhuanyong/EventTriplesExtraction
    本文选择复合事件关系三元组抽取和事件主谓宾三元组抽取两个实践项目进行介绍。前者的输出可以作为后者的输入,通过识别出事件关系的两头事件实体,再通过主谓宾关系抽取,可以进一步得到事件的主体和客体,主体和客体可以进一步成为事件实体链接的桥梁,以实现与实体知识的联合建模。

    一、ComplexEventExtraction复合事件关系三元组抽取

    chinese compound event extraction,中文复合事件抽取,包括条件事件、因果事件、顺承事件、反转事件等事件抽取,并形成事件关系三元组。

    1、复合事件关系中事件的界定
    如果要做事件关系三元组抽取,那么就务必要回答其中的事件形态是什么,其边界在哪儿。基于框架体系FrameNet那套的ACE将事件表示成为一个个论元集合,CEC事件数据集、SemEval等数据集中将事件界定为一个动词。不同的事件界定方式,直接决定了后续技术的选择以及对应的技术难度下图总结了当前遇到的几种工业界事件表示方式:
    以因果事件为例, 已知句子:这几天非洲闹猪瘟,导致国内猪肉涨价。
    图片

    图1-复合事件关系的界定

    2、事件关系的几种类型
    坦白的说,对于事件关系的界定,当下有不同的标准。下表列举了当下的几个典型的事件关系类型。而通过结合语言学规则,利用显式的关系词和模式词进行触发、统计,可以发现,因果事件关系是最为明显的,最有规律可循的。
    图片

    图2-复合事件关系的类型

    3、事件关系抽取的实施
    当前朴素的事件关系抽取,还是以显式的关系触发词展开,可以针对因果关系【导致、造成、所以】、条件关系【如果、前提、要是】、反转关系【虽然、但是、尽管】、顺承关系【紧接着、然后、接下来】,构造对应的句法模式,将以该触发词为核心的主语和宾语部分抽取出来,即可以得到事件关系三元组。
    例如:
    1)转折关系三元组模板
    图片

    2)因果关系三元组模版
    图片

    4、事件关系抽取的效果
    通过对已有的非结构化文本如新闻报道等进行模板抽取,我们可以得到相应的关系三元组抽取效果,如下所示:
    1)因果事件三元组图谱可视化效果
    图片

    图2-美国攻打伊拉克因果事件关系三元组效果

    图片

    图3-寿光发生洪水因果事件关系三元组效果

    2)反转与条件事件关系三元组抽取数据表结果
    图片

    3)反转事件关系三元组抽取结果图谱可视化结果
    图片

    图4-反转事件关系可视化效果

    4)条件事件关系三元组抽取结果图谱可视化结果
    图片

    图5-条件事件关系可视化效果

    二、EventTriplesExtraction事件主谓宾三元组抽取

    基于依存句法与语义角色标注的事件三元组抽取,文本表示一直是个重要问题,如何以清晰,简介的方式对一个文本信息进行有效表示是个长远的任务,我尝试过使用关键词,实体之间的关联关系,并使用textgrapher的方式进行展示,但以词作为文本信息单元表示这种效果不是特别好,所以,本项目想尝试从事件三元组的方式出发,对文本进行表示。
    项目地址:
    https://github.com/liuhuanyong/EventTriplesExtraction

    1、基于依存句法分析和语义角色标注的事件三元组抽取
    当前开源的句法分析组件,包括LTP、hannlp、百度DDParse等为我们进行特定句子的依存分析和语义角色标注提供了快速调用的接口。通过对一个句子进行依存句法分析,可以得到一个句子的核心动词、与该动词直接依存的词,如SBV主语关系、VOB动宾关系、OBJ谓语关系集合。因此,我们可以在此基础上,以句子的动词为核心,先后找出其主语和谓语,并通过ATT修饰关系、COO并列关系等进行主语和宾语的扩展,形成三元组。

    1)抽取实施
    本项目分别使用LTP、百度DDParse作为句法分析器针对输入的文本进行抽取,先进行长句切分,然后进行依存句法分析,并设定扩展规则,可以快速得到三元组集合。
    图片

    2)抽取结果
    本项目的抽取结果如下,选取了“以色列对加沙地带进行轰炸”这一新闻快讯进行处理,得到svos等主谓宾集合。
    图片

    2、基于词性模板规则的事件三元组抽取
    基于依存句法的方式进行事件三元组抽取,其性能受限于依存句法性能的精度,但坦白的说,当前的依存句法分析器的性能并不是特别高,中文的精度在80%-85%之间。因此,我们可以有另一种方式来实现三元组抽取,即基于词性模板的方式,其思想在于,通过构造事件三元组的成词词性模板,如一个典型的IP短语、NP短语、VP短语等,就可以得到三元组结果:
    在这里插入图片描述

    1)抽取实施
    本项目分别使用开源jieba分词器作为分词和词性标注组件,针对输入的文本进行抽取,先进行长句切分,然后进行处理,并设定三元组词性模板,快速得到三元组集合。

    2)抽取结果
    同样的,本项目选取了“以色列对加沙地带进行轰炸”这一新闻快讯进行处理,得到svos等主谓宾集合。
    图片

    三、项目总结

    1、ComplexEventExtraction复合事件关系三元组抽取总结
    本项目对事件图谱的类型、表现形式进行了归纳,并结合复合事件模式与语料进行了实验。实验表明,反转事件,其实在某种程度上可以用来构造反义词词典,例如"不是A而是B"这种模式,可以得到很多反义的词或短语,这让我想到了我的一个反义词项目接口:(https://github.com/liuhuanyong/ChineseAntiword) ,我们可以用wordvector找相近词,可以靠这种方式收集反义词,对了,还可以加上情绪。
    实验表明,汉语显示标记其实在中文文本当中还是用的很普遍的,统计了以下,跑了1000W文本,有超过半数的文本中包含以上模式。因此,如果能够把显式的事件关系三元组做好,感觉用处还是很多的。本项目还有很多不足,比如模式上,比如对事件类型和事件表示的z总结上,而且,事件关系三元组还是限定在句子级别,这是一种讨巧的方式,因为放在篇章级上,实施的难度会更大。

    2、EventTriplesExtraction事件主谓宾三元组抽取总结
    本项目公开了基于ltp句法分析和语义角色标注、基于百度DDParser以及基于词法模式的事件三元组抽取方法,并给了实验示例。通过实验,我们发现
    LTP在DDParser之外,还提供了语义角色标注的功能,这个可以用于事件三元组抽取的有效补充,LTP速度比DDParser要快,但语义角色标注模块存在明显的内存泄漏问题。此外,基于词法模式的事件三元组抽取速度最快,但效果取决于分词、词性标注性能,基于词法模式,可以得到语义更长的三元组元素信息。

    关于作者

    刘焕勇,liuhuanyong,现任360人工智能研究院算法专家,前中科院软件所工程师,主要研究方向为知识图谱、事件图谱在实际业务中的落地应用。
    得语言者得天下,得语言资源者,分得天下,得语言逻辑者,争得天下。
    1、个人主页:https://liuhuanyong.github.io。
    2、个人博客:https://blog.csdn.net/lhy2014/。
    欢迎对自然语言处理、知识图谱、事件图谱理论技术、技术实践等落地应用的朋友一同交流。

    展开全文
  • 目录信息抽取实战:三元组抽取一、限定领域的三元组抽取比赛介绍数据分析序列标注模型关系分类模型三元组提取总结开放领域的三元组抽取标注平台文本分类新数据进行三元组抽取总结参考文献 一、限定领域的三元组抽取 ...

    信息抽取实战:三元组抽取

    一、限定领域的三元组抽取

      本项目将会介绍在2019语言与智能技术竞赛三元组抽取比赛方面的一次尝试。由于该比赛早已结束,当时也没有参加这个比赛,因此没有测评成绩,我们也只能拿到训练集和验证集。但是,这并不耽误我们在这方面做实验。

    比赛介绍

      该比赛的网址为:http://lic2019.ccf.org.cn/kg,给定schema约束集合及句子sent,其中schema定义了关系P以及其对应的主体S和客体O的类别,例如(S_TYPE:人物,P:妻子,O_TYPE:人物)、(S_TYPE:公司,P:创始人,O_TYPE:人物)等。比如下面的例子:

    {
      "text": "九玄珠是在纵横中文网连载的一部小说,作者是龙马",
      "spo_list": [
        ["九玄珠", "连载网站", "纵横中文网"],
        ["九玄珠", "作者", "龙马"]
      ]
    }
    

      该比赛一共提供了20多万标注质量很高的三元组,其中17万训练集,2万验证集和2万测试集,实体关系(schema)50个
      在具体介绍的思路和实战前,先介绍下本次任务的处理思路
    在这里插入图片描述

      首先是对拿到的数据进行数据分析,包括统计每个句子的长度及三元组数量,每种关系的数量分布情况。接着,对数据单独走序列标注模型和关系分析模型。最后在提取三元组的时候,用Pipeline模型,先用序列标注模型预测句子中的实体,再对实体(加上句子)走关系分类模型,预测实体的关系,最后形成有效的三元组。
      接下来将逐一介绍,项目结构图如下:
    在这里插入图片描述

    数据分析

      我们对训练集做数据分析,训练集数据文件为train_data.json
      数据分析会统计训练集中每个句子的长度及三元组数量,还有关系的分布图,代码如下:

    # -*- coding: utf-8 -*-
    import json
    from pprint import pprint
    import pandas as pd
    from collections import defaultdict
    import matplotlib.pyplot as plt
    
    plt.figure(figsize=(18, 8), dpi=100)   # 输出图片大小为1800*800
    # # Mac系统设置中文字体支持
    # plt.rcParams["font.family"] = 'Arial Unicode MS'
    # 解决中文显示问题
    plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
    plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
    
    # 加载数据集
    def load_data(filename):
        D = []
        with open(filename, 'r', encoding='utf-8') as f:
            content = f.readlines()
    
        content = [_.replace(' ', '').replace('\u3000', '').replace('\xa0', '').replace('\u2003', '') for _ in content]
    
        for l in content:
            l = json.loads(l)
            D.append({
                'text': l['text'],
                'spo_list': [
                    (spo['subject'], spo['predicate'], spo['object'])
                    for spo in l['spo_list']
                ]
            })
        return D
    
    filename = '../data/train_data.json'
    
    D = load_data(filename=filename)
    pprint(D)
    
    # 创建text, text_length, spo_num的DataFrame
    text_list = [_["text"] for _ in D]
    spo_num = [len(_["spo_list"])for _ in D]
    
    df = pd.DataFrame({"text": text_list, "spo_num": spo_num} )
    df["text_length"] = df["text"].apply(lambda x: len(x))
    print(df.head())
    print(df.describe())
    
    # 绘制spo_num的条形统计图
    pprint(df['spo_num'].value_counts())
    label_list = list(df['spo_num'].value_counts().index)
    num_list = df['spo_num'].value_counts().tolist()
    
    # 利用Matplotlib模块绘制条形图
    x = range(len(num_list))
    rects = plt.bar(x=x, height=num_list, width=0.6, color='blue', label="频数")
    plt.ylim(0, 80000) # y轴范围
    plt.ylabel("数量")
    plt.xticks([index + 0.1 for index in x], label_list)
    plt.xlabel("三元组数量")
    plt.title("三元组频数统计图")
    
    # 条形图的文字说明
    for rect in rects:
        height = rect.get_height()
        plt.text(rect.get_x() + rect.get_width() / 2, height+1, str(height), ha="center", va="bottom")
    
    plt.savefig('./spo_num_bar_chart.png')
    plt.show()
    
    plt.close()
    
    # 关系统计图
    plt.figure(figsize=(18, 8), dpi=100)   # 输出图片大小为1800*800
    # # Mac系统设置中文字体支持
    # plt.rcParams["font.family"] = 'Arial Unicode MS'
    # 解决中文显示问题
    plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
    plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
    
    # 关系统计图
    relation_dict = defaultdict(int)
    
    for spo_dict in D:
        # print(spo_dict["spo_list"])
        for spo in spo_dict["spo_list"]:
            relation_dict[spo[1]] += 1
    
    label_list = list(relation_dict.keys())
    num_list = list(relation_dict.values())
    
    # 利用Matplotlib模块绘制条形图
    x = range(len(num_list))
    rects = plt.bar(x=x, height=num_list, width=0.6, color='blue', label="频数")
    # plt.ylim(0, 80000) # y轴范围
    plt.ylabel("数量")
    plt.xticks([index + 0.1 for index in x], label_list)
    plt.xticks(rotation=45) # x轴的标签旋转45度
    plt.xlabel("三元组关系")
    plt.title("三元组关系频数统计图")
    
    # 条形图的文字说明
    for rect in rects:
        height = rect.get_height()
        plt.text(rect.get_x() + rect.get_width() / 2, height+1, str(height), ha="center", va="bottom")
    
    plt.savefig('./relation_bar_chart.png')
    plt.show()
    

      输出结果如下:
    在这里插入图片描述
    在这里插入图片描述

      句子的平均长度为54,最大长度为300;每句话中的三元组数量的平均值为2.1,最大值为25
      每句话中的三元组数量的分布图如下:
    在这里插入图片描述

      关系数量的分布图如下:
    在这里插入图片描述

    序列标注模型

      我们将句子中的主体和客体作为实体,分别标注为SUBJ和OBJ,标注体系采用BIO。一个简单的标注例子如下:

    如 O
    何 O
    演 O
    好 O
    自 O
    己 O
    的 O
    角 O
    色 O
    , O
    请 O
    读 O
    《 O
    演 O
    员 O
    自 O
    我 O
    修 O
    养 O
    》 O
    《 O
    喜 B-SUBJ
    剧 I-SUBJ
    之 I-SUBJ
    王 I-SUBJ
    》 O
    周 B-OBJ
    星 I-OBJ
    驰 I-OBJ
    崛 O
    起 O
    于 O
    穷 O
    困 O
    潦 O
    倒 O
    之 O
    中 O
    的 O
    独 O
    门 O
    秘 O
    笈 O
    

      序列标注的模型采用ALBERT+Bi-LSTM+CRF结构图如下:
    在这里插入图片描述

      模型方面的代码不再具体给出,有兴趣的同学可以参考文章信息抽取实战:命名实体识别NER【ALBERT+Bi-LSTM模型 vs. ALBERT+Bi-LSTM+CRF模型】(附代码),也可以参考文章最后给出的Github项目网址。
      模型设置文本最大长度为128,利用ALBERT做特征提取,在自己的电脑上用CPU训练5个epoch,结果如下:

    
    Train on 173109 samples, validate on 21639 samples
    Epoch 1/10
    173109/173109 [==============================] - 422s 2ms/step - loss: 0.4460 - crf_viterbi_accuracy: 0.8710 - val_loss: 0.1613 - val_crf_viterbi_accuracy: 0.9235
    Epoch 2/10
    173109/173109 [==============================] - 417s 2ms/step - loss: 0.1170 - crf_viterbi_accuracy: 0.9496 - val_loss: 0.0885 - val_crf_viterbi_accuracy: 0.9592
    Epoch 3/10
    173109/173109 [==============================] - 417s 2ms/step - loss: 0.0758 - crf_viterbi_accuracy: 0.9602 - val_loss: 0.0653 - val_crf_viterbi_accuracy: 0.9638
    Epoch 4/10
    173109/173109 [==============================] - 415s 2ms/step - loss: 0.0586 - crf_viterbi_accuracy: 0.9645 - val_loss: 0.0544 - val_crf_viterbi_accuracy: 0.9651
    Epoch 5/10
    173109/173109 [==============================] - 422s 2ms/step - loss: 0.0488 - crf_viterbi_accuracy: 0.9663 - val_loss: 0.0464 - val_crf_viterbi_accuracy: 0.9654
    Epoch 6/10
    173109/173109 [==============================] - 423s 2ms/step - loss: 0.0399 - crf_viterbi_accuracy: 0.9677 - val_loss: 0.0375 - val_crf_viterbi_accuracy: 0.9660
    Epoch 7/10
    173109/173109 [==============================] - 415s 2ms/step - loss: 0.0293 - crf_viterbi_accuracy: 0.9687 - val_loss: 0.0265 - val_crf_viterbi_accuracy: 0.9664
    Epoch 8/10
    173109/173109 [==============================] - 414s 2ms/step - loss: 0.0174 - crf_viterbi_accuracy: 0.9695 - val_loss: 0.0149 - val_crf_viterbi_accuracy: 0.9671
    Epoch 9/10
    173109/173109 [==============================] - 422s 2ms/step - loss: 0.0049 - crf_viterbi_accuracy: 0.9703 - val_loss: 0.0036 - val_crf_viterbi_accuracy: 0.9670
    Epoch 10/10
    173109/173109 [==============================] - 429s 2ms/step - loss: -0.0072 - crf_viterbi_accuracy: 0.9709 - val_loss: -0.0078 - val_crf_viterbi_accuracy: 0.9674
               precision    recall  f1-score   support
    
          OBJ     0.9593    0.9026    0.9301     44598
         SUBJ     0.9670    0.9238    0.9449     25521
    
    micro avg     0.9621    0.9104    0.9355     70119
    macro avg     0.9621    0.9104    0.9355     70119
    

      利用seqeval模块做评估,在验证集上的F1值约为93.55%
    在这里插入图片描述

    关系分类模型

      需要对关系做一下说明,因为会对句子(sent)中的主体(S)和客体(O)组合起来,加上句子,形成训练数据。举个例子,在句子历史评价李氏朝鲜的创立并非太祖大王李成桂一人之功﹐其五子李芳远功不可没,三元组为[{“predicate”: “父亲”, “object_type”: “人物”, “subject_type”: “人物”, “object”: “李成桂”, “subject”: “李芳远”}, {“predicate”: “国籍”, “object_type”: “国家”, “subject_type”: “人物”, “object”: “朝鲜”, “subject”: “李成桂”}]},在这句话中主体有李成桂,李芳远,客体有李成桂和朝鲜,关系有父亲(关系类型:2)和国籍(关系类型:22)。按照的思路,这句话应组成4个关系分类样本,如下:

    2 李芳远$李成桂$历史评价李氏朝鲜的创立并非太祖大王###一人之功﹐其五子###功不可没
    0 李芳远$朝鲜$历史评价李氏##的创立并非太祖大王李成桂一人之功﹐其五子###功不可没
    0 李成桂$李成桂$历史评价李氏朝鲜的创立并非太祖大王###一人之功﹐其五子李芳远功不可没
    22 李成桂$朝鲜$历史评价李氏##的创立并非太祖大王###一人之功﹐其五子李芳远功不可没
    

      因此,就会出现关系0(表示“未知”),这样我们在提取三元组的时候就可以略过这条关系,形成真正有用的三元组。
      因此,关系一共为51个(加上未知关系:0)。关系分类模型采用ALBERT+Bi-GRU+ATT,结构图如下:
    在这里插入图片描述

      模型方面的代码不再具体给出,有兴趣的同学可以参考文章信息抽取实战:人物关系抽取【BERT模型】(附代码),也可以参考文章最后给出的Github项目网址。
      模型设置文本最大长度为128,利用ALBERT做特征提取,在自己的电脑上用CPU训练30个epoch(实际上,由于有early stopping机制,训练不到30个eopch),在验证集上的评估结果如下:

    Epoch 23/30
    396766/396766 [==============================] - 776s 2ms/step - loss: 0.1770 - accuracy: 0.9402 - val_loss: 0.2170 - val_accuracy: 0.9308
    
    Epoch 00023: val_accuracy did not improve from 0.93292
    49506/49506 [==============================] - 151s 3ms/step
    
    在测试集上的效果: [0.21701653493155634, 0.930776059627533]
        precision    recall  f1-score   support
    
              未知       0.87      0.76      0.81      5057
              祖籍       0.92      0.73      0.82       181
              父亲       0.79      0.88      0.83       609
            总部地点       0.95      0.95      0.95       310
             出生地       0.94      0.95      0.94      23301.00      1.00      1.00      1271
              面积       0.90      0.92      0.91        79
              简称       0.97      0.99      0.98       138
            上映时间       0.94      0.98      0.96       463
              妻子       0.91      0.83      0.87       680
            所属专辑       0.97      0.97      0.97      1282
            注册资本       1.00      1.00      1.00        63
              首都       0.92      0.96      0.94        47
              导演       0.92      0.94      0.93      26030.96      0.97      0.97       339
              身高       0.98      0.98      0.98       393
            出品公司       0.96      0.96      0.96       851
            修业年限       1.00      1.00      1.00         2
            出生日期       0.99      0.99      0.99      2892
             制片人       0.69      0.88      0.77       127
              母亲       0.75      0.88      0.81       425
              编剧       0.82      0.80      0.81       771
              国籍       0.92      0.92      0.92      1621
              海拔       1.00      1.00      1.00        43
            连载网站       0.98      1.00      0.99      1658
              丈夫       0.84      0.91      0.87       678
              朝代       0.85      0.92      0.88       419
              民族       0.98      0.99      0.99      14340.95      0.99      0.97       197
             出版社       0.98      0.99      0.99      2272
             主持人       0.82      0.86      0.84       200
            专业代码       1.00      1.00      1.00         3
              歌手       0.89      0.94      0.91      2857
              作词       0.85      0.81      0.83       884
              主角       0.86      0.77      0.81        39
             董事长       0.81      0.74      0.78        47
            毕业院校       0.99      0.99      0.99      1433
            占地面积       0.89      0.89      0.89        61
            官方语言       1.00      1.00      1.00        15
            邮政编码       1.00      1.00      1.00         4
            人口数量       1.00      1.00      1.00        45
            所在城市       0.90      0.94      0.92        77
              作者       0.97      0.97      0.97      4359
            成立日期       0.99      0.99      0.99      1608
              作曲       0.78      0.77      0.78       849
              气候       1.00      1.00      1.00       103
              嘉宾       0.76      0.72      0.74       158
              主演       0.94      0.97      0.95      7383
             改编自       0.95      0.82      0.88        71
             创始人       0.86      0.87      0.86        75
    
        accuracy                           0.93     49506
       macro avg       0.92      0.92      0.92     49506
    weighted avg       0.93      0.93      0.93     49506
    

    在这里插入图片描述

    三元组提取

      最后一部分,也是本次比赛的最终目标,就是三元组提取
      三元组提取采用Pipeline模式先用序列标注模型预测句子中的实体,然后再用关系分类模型判断实体关系的类别,过滤掉关系为未知的情形,就得到提取的三元组了
      三元组提取的代码如下:

    # -*- coding: utf-8 -*-
    import os, re, json, traceback
    
    import json
    import numpy as np
    from keras_contrib.layers import CRF
    from keras_contrib.losses import crf_loss
    from keras_contrib.metrics import crf_accuracy, crf_viterbi_accuracy
    from keras.models import load_model
    from collections import defaultdict
    from pprint import pprint
    from text_classification.att import Attention
    
    from albert_zh.extract_feature import BertVector
    
    # 读取label2id字典
    with open("./sequence_labeling/ccks2019_label2id.json", "r", encoding="utf-8") as h:
        label_id_dict = json.loads(h.read())
    
    id_label_dict = {v: k for k, v in label_id_dict.items()}
    # 利用ALBERT提取文本特征
    bert_model = BertVector(pooling_strategy="NONE", max_seq_len=128)
    f = lambda text: bert_model.encode([text])["encodes"][0]
    
    # 载入NER模型
    custom_objects = {'CRF': CRF, 'crf_loss': crf_loss, 'crf_viterbi_accuracy': crf_viterbi_accuracy}
    ner_model = load_model("./sequence_labeling/ccks2019_ner.h5", custom_objects=custom_objects)
    
    # 载入分类模型
    best_model_path = './text_classification/models/per-rel-19-0.9329.h5'
    classification_model = load_model(best_model_path, custom_objects={"Attention": Attention})
    
    # 分类与id的对应关系
    with open("./data/relation2id.json", "r", encoding="utf-8") as g:
        relation_id_dict = json.loads(g.read())
    
    id_relation_dict = {v: k for k, v in relation_id_dict.items()}
    
    
    # 从预测的标签列表中获取实体
    def get_entity(sent, tags_list):
    
        entity_dict = defaultdict(list)
        i = 0
        for char, tag in zip(sent, tags_list):
            if 'B-' in tag:
                entity = char
                j = i+1
                entity_type = tag.split('-')[-1]
                while j < min(len(sent), len(tags_list)) and 'I-%s' % entity_type in tags_list[j]:
                    entity += sent[j]
                    j += 1
    
                entity_dict[entity_type].append(entity)
    
            i += 1
    
        return dict(entity_dict)
    
    class TripleExtract(object):
    
        def __init__(self, text):
            self.text = text.replace(" ", "")    # 输入句子
    
        # 获取输入句子中的实体(即:主体和客体)
        def get_entity(self):
            train_x = np.array([f(self. text)])
            y = np.argmax(ner_model.predict(train_x), axis=2)
            y = [id_label_dict[_] for _ in y[0] if _]
    
            # 输出预测结果
            return get_entity(self.text, y)
    
        # 对实体做关系判定
        def relation_classify(self):
            entities = self.get_entity()
            subjects = list(set(entities.get("SUBJ", [])))
            objs = list(set(entities.get("OBJ", [])))
    
            spo_list = []
    
            for subj in subjects:
                for obj in objs:
                    sample = '$'.join([subj, obj, self.text.replace(subj, '#'*len(subj)).replace(obj, "#"*len(obj))])
                    vec = bert_model.encode([sample])["encodes"][0]
                    x_train = np.array([vec])
    
                    # 模型预测并输出预测结果
                    predicted = classification_model.predict(x_train)
                    y = np.argmax(predicted[0])
    
                    relation = id_relation_dict[y]
                    if relation != "未知":
                        spo_list.append([subj, relation, obj])
    
            return spo_list
    
        # 提取三元组
        def extractor(self):
    
            return self.relation_classify()
    

      运行三元组提取脚本,代码如下:

    # -*- coding: utf-8 -*-
    import os, re, json, traceback
    from pprint import pprint
    
    from triple_extract.triple_extractor import TripleExtract
    
    text = "真人版的《花木兰》由新西兰导演妮基·卡罗执导,由刘亦菲、甄子丹、郑佩佩、巩俐、李连杰等加盟,几乎是全亚洲阵容。"
    # text = "《冒险小王子》作者周艺文先生,教育、文学领域的专家学者以及来自全国各地的出版业从业者参加了此次沙龙,并围绕儿童文学创作这一话题做了精彩的分享与交流。"
    # text = "宋应星是江西奉新人,公元1587年生,经历过明朝腐败至灭亡的最后时期。"
    # text = "韩愈,字退之,河阳(今河南孟县)人。"
    # text = "公开资料显示,李强,男,汉族,出生于1971年12月,北京市人,北京市委党校在职研究生学历,教育学学士学位,1996年11月入党,1993年7月参加工作。"
    # text = "杨牧,本名王靖献,早期笔名叶珊,1940年生于台湾花莲,著名诗人、作家。"
    # text = "杨广是隋文帝杨坚的第二个儿子。"
    # text = "此次权益变动后,何金明与妻子宋琦、其子何浩不再拥有对上市公司的控制权。"
    # text = "线上直播发布会中,谭维维首次演绎了新歌《章存仙》,这首歌由钱雷作曲、尹约作词,尹约也在直播现场透过手机镜头跟网友互动聊天。"
    # text = "“土木之变”后,造就了明代杰出的民族英雄于谦。"
    # text = "真纳大学坐落在伊斯兰堡市,是一所创建于1967年7月的公立研究型大学。"
    # text = "黄书豪毕业于泰国博仁大学,并签约北京经纪公司,2018年参加《偶像练习生》,曾在节目中表演洗脑神曲《容易动情的人》,让全场嗨到又唱又跳,节目最终排名第43位。"
    # text = "浙江金裕包装有限公司坐落于杭州湾畔金国最大的铝氧化生产基地----江南古镇沥海工业园区,公司西近杭州,紧靠杭州湾世纪大道,距上海100公里余,是一家专业生产氧化铝化妆品配套产品,兼产酒瓶盖、小家电等铝包装产品的制造企业"
    # text = "另外,哈尔滨历史博物馆也是全国面积最小的国有博物馆,该场馆面积只有50平方米,可称之“微缩博物馆”。"
    # text = "孙杨的妈妈叫杨明,孙杨的名字后面一个字也是来源于她的名字。"
    # text = "企查查显示,达鑫电子成立于1998年6月,法定代表人张高圳,注册资本772.33万美元,股东仅新加坡达鑫控股有限公司一名。"
    
    
    triple_extract = TripleExtract(text)
    print("原文: %s" % text)
    entities = triple_extract.get_entity()
    print("实体: ", end='')
    pprint(entities)
    
    spo_list = triple_extract.extractor()
    print("三元组: ", end='')
    pprint(spo_list)
    

      我们在网上找几条样本进行测试,测试的结果如下:
    在这里插入图片描述

    总结

      本项目标题为限定领域的三元组抽取,之所以取名为限定领域,是因为该任务的实体关系是确定,一共为50种关系
      当然,上述方法还存在着诸多不足,参考苏建林的文章基于DGCNN和概率图的轻量级信息抽取模型 ,我们发现不足之处如下:

    • 主体和客体的标注策略有问题,因为句子中有时候主体和客体会重叠在一起;
    • 新引入了一类关系:未知,是否有办法避免引入;
    • 其他(暂时未想到)

      从比赛的角度将,本项目的办法效果未知,应该会比联合模型的效果差一些。但是,这是作为自己的模型,算法是一种尝试,之所以采用这种方法,是因为一开始是从开放领域的三元组抽取入手的,而这种方法方便扩展至开放领域。关于开放领域的三元组抽取,稍后就会写文章介绍。
      本项目的源代码已经公开至Github,网址为:https://github.com/chenlian-zhou/ccks_triple_extract/tree/master/limite_extract_platform

    二、开放领域的三元组抽取

      关于三元组抽取的基本介绍和常用办法,之前已经在不少文章中描述过,这里不再过多介绍,有兴趣的读者可以参考文章利用关系抽取构建知识图谱的一次尝试 。本文将会介绍在开放领域做三元组抽取的一次尝试。
      本项目已经开源至Github,文章最后会给出相应的网址。本项目的项目结构如下:
    在这里插入图片描述

      本项目一共分为四部分,主要模块介绍如下:

    • extract_example: 利用训练好的模型对基本小说和新闻进行三元组抽取,形成知识图谱例子
    • sequence_labeling训练标注,对标注的实体数据进行序列标注算法训练
    • spo_tagging_platform标注平台,标注subject,predicate和object以及三元组是否有效
    • text_classification文本分类,用于判别抽取的三元组是否有效

      本项目的抽取系统流程图如下:
    在这里插入图片描述

    标注平台

      用tornado搭建了简易的标注平台,在标注页面中,标注人员需要输入标注的句子(句子级别的抽取)以及subject,predicate,object,点击“显示SPO”,将有效的三元组标注为1,无效的三元组标注为0。之所以采取这种标注方法,是因为我们可以在句子中标注subject,predicate,object,这些标注的实体就会形成可能的三元组组合,再利用0,1来标注这种三元组是否有效,这样就能做到在开放领域进行三元组抽取。
      一个简单的标注例子如下:
    在这里插入图片描述

      再对以上的标注结果做一些说明,我们的标注是以句子为单位,进行句子级别的标注,不同要素在标注的时候加 # 区分,标注了两个subject,1个predicate(共用)和2个object,其中predidate是这些subject和object公用的,所以只需要标注一次。这样,点击“显示SPO”,一共会显示4个三元组,s,p,o用#隔开,0,1表示是否是有效三元组,默认为0
      利用空余时间,一共标注了3200多个样本,对于序列标注来说,就是3200多个样本,对于文本分类来说,就是9000多个样本了

    序列标注

      对于上述的标注例子,会形成如下的标注序列

    美	B-SUBJ
    国	I-SUBJ
    疾	I-SUBJ
    控	I-SUBJ
    中	I-SUBJ
    心	I-SUBJ
    主	B-PRED
    任	I-PRED
    雷	B-OBJ
    德	I-OBJ
    菲	I-OBJ
    尔	I-OBJ
    德	I-OBJ
    (	O
    左	O
    圈	O
    )	O
    和	O
    美	B-SUBJ
    国	I-SUBJ
    国	I-SUBJ
    立	I-SUBJ
    卫	I-SUBJ
    生	I-SUBJ
    研	I-SUBJ
    究	I-SUBJ
    院	I-SUBJ
    过	I-SUBJ
    敏	I-SUBJ
    和	I-SUBJ
    传	I-SUBJ
    染	I-SUBJ
    病	I-SUBJ
    研	I-SUBJ
    究	I-SUBJ
    所	I-SUBJ
    主	B-PRED
    任	I-PRED
    福	B-OBJ
    西	I-OBJ
    (	O
    右	O
    圈	O
    )	O
    

      将数据集分为训练集和测试集,比例为8:2。采用经典的深度学习模型ALBERT+Bi-LSTM+CRF进行实体识别,设置最大文本长度为128,训练100个epoch。关于该模型的介绍,可以参考文章信息抽取实战:命名实体识别NER【ALBERT+Bi-LSTM模型 vs. ALBERT+Bi-LSTM+CRF模型】(附代码)
      在测试集上的训练结果如下:

    accuracy:  93.69%; precision:  76.26%; recall:  82.33%; FB1:  79.18
    
    OBJ: precision:  80.47%; recall:  88.81%; FB1:  84.44  927
    PRED: precision:  76.89%; recall:  83.69%; FB1:  80.14  1021
    SUBJ: precision:  71.72%; recall:  75.32%; FB1:  73.48  983
    

      在测试集上的总体F1值接近80%

    文本分类

      关于文本分类,需要多做一些说明。
      虽然本文的题目是关于在开发领域的三元组抽取的尝试,但实际我在标注的时候,还是更多地标注人物头衔,人物关系,公司与人的关系,影视剧主演、导演信息等。形成的有效的文本分类的样本为9000多个,一共有关系1365个,数量最多的前20个关系,如下图:
    在这里插入图片描述

      以上述的标注数据为例,形成的标注数据如下:

    美国疾控中心#主任#雷德菲尔德#1#美国疾控中心主任雷德菲尔德(左圈)和美国国立卫生研究院过敏和传染病研究所主任福西(右圈)
    美国疾控中心#主任#福西#0#美国疾控中心主任雷德菲尔德(左圈)和美国国立卫生研究院过敏和传染病研究所主任福西(右圈)
    美国国立卫生研究院过敏和传染病研究所#主任#雷德菲尔德#0#美国疾控中心主任雷德菲尔德(左圈)和美国国立卫生研究院过敏和传染病研究所主任福西(右圈)
    美国国立卫生研究院过敏和传染病研究所#主任#福西#1#美国疾控中心主任雷德菲尔德(左圈)和美国国立卫生研究院过敏和传染病研究所主任福西(右圈)
    

      在实际模型训练的时候,会将原文中的subject用S*len(subject)代替,predicate用P,object用O
      将数据集分为训练集和测试集,比例为8:2。采用经典的深度学习模型ALBERT+Bi-GRU+ATT+FC,设置文本的最大长度为为128,训练30个epoch,采用early stopping机制,训练过程的loss和acc图像如下:
    在这里插入图片描述

      最终在测试集上的accuracy约为96%

    新数据进行三元组抽取

      上述的模型训练完毕后,我们就可以将其封装成HTTP服务。对于新输入的句子,我们先利用序列标注模型预测出其中的subject,predicate和object,组合成三元组与句子的拼接,输入到文本分类模型,判别该三元组是否有效,0为无效,1为有效
      从网上找几个例子,预测的结果如下:
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

      extract_example目录中为抽取的效果,包括几本小说和一些新闻上的效果,关于这方面的演示,可以参考另一个项目:https://github.com/percent4/knowledge_graph_demo 。也可以参考文章知识图谱构建举例 https://blog.csdn.net/jclian91/article/details/104685424 中给出的几个知识图谱的建构的例子。

    总结

      本文写的过程较为简单,也没有代码,这是因为在之前的文章中做了大量的铺垫,主要是集中在模型方面。况且,这个项目比较大,也不适合在这里详细讲述,只在这里给出思路和大概的处理流程,具体的实现代码可以参考下方的Github地址。
      在实际的抽取过程中,一些句子也存在抽取出大量无用的三元组的情况,导致召回率高,这是因为本项目针对的是开放领域的三元组抽取,因此效果比不会有想象中的那么好,提升抽取效果的办法如下:

    • 增加数据标注量,目前序列标注算法的样本仅3200多个
    • 模型方面:现在是pipeline形式,各自的效果还行,但总体上不如Joint形式好
    • 对于自己想抽的其他三元组的情形,建议增加这方面的标注
    • 文本预测耗时长(该问题已经解决)。

      本项目作为在开放领域的三元组抽取的一次尝试,在此之前关于这方面的文章或者项目还很少,因此可以说是探索阶段。
      源码和数据已经在Github项目中给出,网址为 https://github.com/chenlian-zhou/ccks_triple_extract/tree/master/spo_extract_platform/spo_extract_platform

    参考文献

    1. 信息抽取实战:命名实体识别NER【ALBERT+Bi-LSTM模型 vs. ALBERT+Bi-LSTM+CRF模型】(附代码)
    2. 信息抽取实战:人物关系抽取【BERT模型】(附代码)
    3. 基于DGCNN和概率图的轻量级信息抽取模型
    4. 利用关系抽取构建知识图谱的一次尝试: https://www.cnblogs.com/jclian91/p/11107323.html
    5. 《知识图谱 方法、实践与应用》 王昊奋、漆桂林、陈华钧著,中国工信出版集团、电子工业出版社出版。
    展开全文
  • 这个 Triplet Extraction(三元组抽取)任务旨在抽取评论中出现的所有 aspect,对应的 sentiment 以及对应的 opinion term,并完成三者的匹配工作,形成(aspect, sentiment, opinion term)的三元组,如上例中的...
  • 关系抽取的主要任务就是,给定一段句子文本,抽取句子中的两个实体以及实体之间的关系,以次来构成一个三元组(s,p,o),s是subject表示主实体,o为object表示客实体,p为predicate表示两实体间的关系。...
  • 一种用于实体关系三元组抽取的位置辅助分布标记方法 该方法是一种属于共享参数的联合抽取方式,本论文将关系作为预设属性,通过分布标记出主、客实体得到三元组。模型有两类抽取器,一类用于确定主实体S,另一种用于...
  • 基于Transformer的三元组抽取和实践

    千次阅读 2021-03-02 14:02:53
    实体识别和关系抽取是最核心的内容 而关系抽取也隶属于三元组抽取的一部分,所以研究三元组的抽取对知识图谱的构建有比较重要的意义。 2.Bert 原理 模型介绍 代码实践 bert 原理 Bert的全名是Bidirectional Encoder ...
  • NLP(二十六)限定领域的三元组抽取的一次尝试

    千次阅读 热门讨论 2020-03-15 18:39:14
      本文将会介绍笔者在2019语言与智能技术竞赛的三元组抽取比赛方面的一次尝试。由于该比赛早已结束,笔者当时也没有参加这个比赛,因此没有测评成绩,我们也只能拿到训练集和验证集。但是,这并不耽误我们在这方面...
  • 这里使用一个多任务模型抽取三元组。任务1是抽取subjects, 任务2是同时抽取objects 和 predictions。抽取的方式并不是BIO标注的方式而是采用半指针半标注的方法。 一、模型整体思路 1、模型大体描述如下:基于Bert...
  • A Novel Cascade Binary Tagging Framework for Relational Triple Extraction 此文为论文笔记,非本人论文哟! ...论文特点 将关系建模为S到O的映射,...三元组抽取问题就被分解为如下的两步过程:确定句子中所有可能的头
  • 数据显示CasRel表 现较好 四、论文总结 1、关键点 新的标注策略 新的模型框架 三元组重叠 2、创新点 引入指针标注 级联式联合抽取 3、启发点 将离散的label识别问题转化为subject,(relation,object)。 Instead of ...
  • 深度学习-自然语言处理(NLP)-文本预处理:关系抽取【基于命名实体识别、依存句法分析】
  • 该任务来源于2019年百度举办的一个竞赛"2019语言与智能技术竞赛",其实它是一个信息抽取的任务,更精确地说是“三元组抽取任务,示例数据如下: { "text": "杜秉离 男,1948年8月生,河南商水县巴村镇娄庄人", ...
  • 爬取百度百科中文页面,抽取三元组信息,构建中文知识图谱
  • 二、基于依存句法和语义角色标注的事件三元组抽取 句法分析是自然语言中关键技术之一,其主要任务时确定句法结构、句子中的词汇之间的依存关系;因而主要包括两方面的内容:一、确定语言的语法体系,即对句子结构...
  • deepdive系统可以实现高质量:PaleoDeepDive比志愿者更高质量在提取复杂的知识科学领域和获奖的性能进入实体关系抽取的比赛 deepdive知道数据往往是嘈杂和不准确的:名字拼错的,自然语言是模糊的,人会犯错误。以...
  • 二、基于依存句法的三元组抽取  1、对于每个词生成一个该词的依存句法的儿子节点,主要存储关系和对应儿子词的位置;  2、对没歌词生成一个该词的父子数组的依存结构,主要是记录该词的词性、父节点的词性...
  • 论文笔记整理:王中昊,天津大学。来源:ACL2020链接:https://arxiv.org/pdf/1909.03227.pdf摘要从非结构化文本中提取关系三元组是构建大规模知识图的关...
  • 知识图谱三元组抽取

    万次阅读 2017-11-03 17:54:06
    http://blog.csdn.net/u013412066/article/details/68065518
  • 3.2 基于联合抽取 联合模型只提取有效的关系三联体,它们不需要提取None的三元组。 根据实体的overlap情况,可以分为NEO(No Entity Overlap),EPO(Entity Pair Overlap),SEO(Single Entity Overlap )三种情况: 4. ...
  • 爬取百度百科中文页面,抽取三元组信息,构建中文知识图谱

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,040
精华内容 2,816
关键字:

三元组抽取

友情链接: TimeManagerEvent.rar