自动信息抽取发展了几十年,虽然模型很多,但是泛化能力很难用满意来形容,直到LLM的诞生。虽然最终信息抽取质量部分还是需要专家审核,但是已经极大的提高了信息抽取的效率。因为传统方法需要大量时间来完成数据清洗、标注和训练,然后来实体抽取、实体属性抽取、实体关系抽取、事件抽取、实体链接和指代消解等等。现在有了LLM,可以实现Zero/One/Few-Shot信息抽取构建知识图谱。

一.ChatIE实现过程

  ChatIE本质上是将零样本IE任务转变为一个两阶段框架的多轮问答问题(使用的ChatGPT,也可以修改为ChatGLM2),问题是第一阶段和第二阶段如何设计?本质上还是Prompt的设计。接下来都是以RE(关系抽取)为例进行说明,NER(命名实体识别)和EE(事件抽取)以此类推。下面看一个例子,如下所示:

df_ret = {
    'chinese': {'所属专辑': ['歌曲', '音乐专辑'], '成立日期': ['机构', 'Date'], '海拔': ['地点', 'Number'], '官方语言': ['国家', '语言'], '占地面积': ['机构', 'Number'], '父亲': ['人物', '人物'], 
                '歌手': ['歌曲', '人物'], '制片人': ['影视作品', '人物'], '导演': ['影视作品', '人物'], '首都': ['国家', '城市'], '主演': ['影视作品', '人物'], '董事长': ['企业', '人物'], '祖籍': ['人物', '地点'], 
                '妻子': ['人物', '人物'], '母亲': ['人物', '人物'], '气候': ['行政区', '气候'], '面积': ['行政区', 'Number'], '主角': ['文学作品', '人物'], '邮政编码': ['行政区', 'Text'], '简称': ['机构', 'Text'], 
                '出品公司': ['影视作品', '企业'], '注册资本': ['企业', 'Number'], '编剧': ['影视作品', '人物'], '创始人': ['企业', '人物'], '毕业院校': ['人物', '学校'], '国籍': ['人物', '国家'], 
                '专业代码': ['学科专业', 'Text'], '朝代': ['历史人物', 'Text'], '作者': ['图书作品', '人物'], '作词': ['歌曲', '人物'], '所在城市': ['景点', '城市'], '嘉宾': ['电视综艺', '人物'], '总部地点': ['企业', '地点'], 
                '人口数量': ['行政区', 'Number'], '代言人': ['企业/品牌', '人物'], '改编自': ['影视作品', '作品'], '校长': ['学校', '人物'], '丈夫': ['人物', '人物'], '主持人': ['电视综艺', '人物'], '主题曲': ['影视作品', '歌曲'], 
                '修业年限': ['学科专业', 'Number'], '作曲': ['歌曲', '人物'], '号': ['历史人物', 'Text'], '上映时间': ['影视作品', 'Date'], '票房': ['影视作品', 'Number'], '饰演': ['娱乐人物', '人物'], '配音': ['娱乐人物', '人物'], '获奖': ['娱乐人物', '奖项']
                }
}

1.第一阶段

  第一阶段的模板,如下所示:

re_s1_p = {
    'chinese': '''给定的句子为:"{}"\n\n给定关系列表:{}\n\n在这个句子中,可能包含了哪些关系?\n请给出关系列表中的关系。\n如果不存在则回答:无\n按照元组形式回复,如 (关系1, 关系2, ……):''',
}

2.第二阶段

  第二段的模板,如下所示:

re_s2_p = {
    'chinese': '''根据给定的句子,两个实体的类型分别为({},{})且之间的关系为{},请找出这两个实体,如果有多组,则按组全部列出。\n如果不存在则回答:无\n按照表格形式回复,表格有两列且表头为({},{}):''',
}

  ChatIE通过两阶段的ChatGPT多轮问答来解决Zero-Shot信息抽取构建知识图谱。但有个问题是可能或一定会出现错误关系抽取,这该如何办呢?工程有个解决方案就是引入多个裁判,比如ChatGPT是一个裁判,文心一言是一个裁判,BERT实体关系抽取是一个裁判,规则实体关系抽取是一个裁判。可根据知识精度要求,比如4个裁判都一致了,才会自动更新到知识库中,否则需要人工来审核实体关系抽取是否正确。知识图谱自动化更新是一个工程活,需要一个人工审核的功能,来确保模型识别不一致时的最终审核。

3.测试效果

  ChatIE在不同任务(RE、NER和EE)和不同数据集上的测试效果,如下所示:

二.使用ChatGLM2来信息抽取[1]

  这部分替换ChatGPT为ChatGLM2来做多轮问答。ChatGLM2进行金融知识抽取实践中,在ChatGLM前置了两轮对话达到了较好的效果,具体代码实现参考[9]。基本思路是加载ChatGLM2模型,然后初始化Prompt(分类和信息抽取),最后根据输入和模型完成推理过程。简单理解,整体思路是通过Few-Shot信息抽取构建知识图谱。

(1)加载ChatGLM2模型

tokenizer = AutoTokenizer.from_pretrained(r"L:/20230713_HuggingFaceModel/chatglm2-6b", trust_remote_code=True) # 指定使用的tokenizer
model = AutoModel.from_pretrained(r"L:/20230713_HuggingFaceModel/chatglm2-6b", trust_remote_code=True).half().cuda() # 指定使用的model
model = model.eval() # 指定model为eval模式

(2)初始化Prompt

def init_prompts():
    """
    初始化前置prompt,便于模型做 incontext learning。
    """
    class_list = list(class_examples.keys()) # 获取分类的类别,class_list = ['基金', '股票']
    cls_pre_history = [
        (
            f'现在你是一个文本分类器,你需要按照要求将我给你的句子分类到:{class_list}类别中。',
            f'好的。'
        )
    ]

    for _type, exmpale in class_examples.items(): # 遍历分类的类别和例子
        cls_pre_history.append((f'“{exmpale}”是 {class_list} 里的什么类别?', _type)) # 拼接前置prompt

    ie_pre_history = [
        (
            "现在你需要帮助我完成信息抽取任务,当我给你一个句子时,你需要帮我抽取出句子中三元组,并按照JSON的格式输出,上述句子中没有的信息用['原文中未提及']来表示,多个值之间用','分隔。",
            '好的,请输入您的句子。'
        )
    ]

    for _type, example_list in ie_examples.items(): # 遍历分类的类别和例子
        for example in example_list: # 遍历例子
            sentence = example['content'] # 获取句子
            properties_str = ', '.join(schema[_type]) # 拼接schema
            schema_str_list = f'“{_type}”({properties_str})' # 拼接schema
            sentence_with_prompt = IE_PATTERN.format(sentence, schema_str_list) # 拼接前置prompt
            ie_pre_history.append(( # 拼接前置prompt
                f'{sentence_with_prompt}',
                f"{json.dumps(example['answers'], ensure_ascii=False)}"
            ))

    return {'ie_pre_history': ie_pre_history, 'cls_pre_history': cls_pre_history} # 返回前置prompt

  custom_settings数据结构中的内容如下所示:

(3)根据输入和模型完成推理过程

def inference(
        sentences: list,
        custom_settings: dict
    ):
    """
    推理函数。

    Args:
        sentences (List[str]): 待抽取的句子。
        custom_settings (dict): 初始设定,包含人为给定的few-shot example。
    """
    for sentence in sentences: # 遍历句子
        with console.status("[bold bright_green] Model Inference..."): # 显示推理中
            sentence_with_cls_prompt = CLS_PATTERN.format(sentence) # 拼接前置prompt
            cls_res, _ = model.chat(tokenizer, sentence_with_cls_prompt, history=custom_settings['cls_pre_history']) # 推理

            if cls_res not in schema: # 如果推理结果不在schema中,报错并退出
                print(f'The type model inferenced {cls_res} which is not in schema dict, exited.')
                exit()

            properties_str = ', '.join(schema[cls_res]) # 拼接schema
            schema_str_list = f'“{cls_res}”({properties_str})' # 拼接schema
            sentence_with_ie_prompt = IE_PATTERN.format(sentence, schema_str_list) # 拼接前置prompt
            ie_res, _ = model.chat(tokenizer, sentence_with_ie_prompt, history=custom_settings['ie_pre_history']) # 推理
            ie_res = clean_response(ie_res) # 后处理
        print(f'>>> [bold bright_red]sentence: {sentence}') # 打印句子
        print(f'>>> [bold bright_green]inference answer: ') # 打印推理结果
        print(ie_res) # 打印推理结果

如果实体关系抽取搞定了,那么自动更新到NebulaGraph就比较简单了,可参考NebulaGraph实战:2-NebulaGraph手工和Python操作

参考文献:

[1]利用ChatGLM构建知识图谱:https://discuss.nebula-graph.com.cn/t/topic/13029

[2]ChatGPT+SmartKG 3分钟生成"哈利波特"知识图谱:https://www.msn.cn/zh-cn/news/technology/chatgpt-smartkg-3分钟生成-哈利波特-知识图谱/ar-AA17ykNr

[3]ChatIE:https://github.com/cocacola-lab/ChatIE

[4]ChatIE:http://124.221.16.143:5000/

[5]financial_chatglm_KG:https://github.com/zhuojianc/financial_chatglm_KG

[6]Creating a Knowledge Graph From Video Transcripts With ChatGPT 4:https://neo4j.com/developer-blog/chatgpt-4-knowledge-graph-from-video-transcripts/

[7]GPT4IE:https://github.com/cocacola-lab/GPT4IE

[8]GPT4IE:http://124.221.16.143:8080/

[9]https://github.com/ai408/nlp-engineering/blob/main/20230917_NLP工程化公众号文章\NebulaGraph教程\NebulaGraph实战:3-信息抽取构建知识图谱

NebulaGraph实战:3-信息抽取构建知识图谱的更多相关文章

  1. ACL2016信息抽取与知识图谱相关论文掠影

    实体关系推理与知识图谱补全 Unsupervised Person Slot Filling based on Graph Mining 作者:Dian Yu, Heng Ji 机构:Computer ...

  2. springboot2.0+Neo4j+d3.js构建知识图谱

    Welcome to the Neo4j wiki! 初衷这是一个知识图谱构建工具,最开始是对产品和领导为了做ppt临时要求配合做图谱展示的不厌其烦,做着做着就抽出一个目前看着还算通用的小工具 技术栈 ...

  3. Redis闲谈(1):构建知识图谱

    场景:Redis面试 (图片来源于网络) 面试官: 我看到你的简历上说你熟练使用Redis,那么你讲一下Redis是干嘛用的? 小明: (心中窃喜,Redis不就是缓存吗?)Redis主要用作缓存,通 ...

  4. 中文维基百科分类提取(jwpl)--构建知识图谱数据获取

    首先感谢 : 1.https://blog.csdn.net/qq_39023569/article/details/88556301 2.https://www.cnblogs.com/Cheris ...

  5. [知识图谱]Neo4j知识图谱构建(neo4j-python-pandas-py2neo-v3)

    neo4j-python-pandas-py2neo-v3 利用pandas将excel中数据抽取,以三元组形式加载到neo4j数据库中构建相关知识图谱 Neo4j知识图谱构建 1.运行环境: pyt ...

  6. Task1:知识图谱介绍(1天)

    一.知识图谱简介 "知识图谱本质上是语义网络(Semantic Network)的知识库".但这有点抽象,所以换个角度,从实际应用的角度出发其实可以简单地把知识图谱理解成多关系图( ...

  7. Atitit 知识图谱的数据来源

    Atitit 知识图谱的数据来源   2. 知识图谱的数据来源1 a) 百科类数据2 b) 结构化数据3 c) 半结构化数据挖掘AVP (垂直站点爬虫)3 d) 通过搜索日志(query record ...

  8. Atitit 知识图谱解决方案:提供完整知识体系架构的搜索与知识结果overview

    Atitit 知识图谱解决方案:提供完整知识体系架构的搜索与知识结果overview   知识图谱的表示和在搜索中的展1 提升Google搜索效果3 1.找到最想要的信息.3 2.提供最全面的摘要.4 ...

  9. 1. 通俗易懂解释知识图谱(Knowledge Graph)

    1. 通俗易懂解释知识图谱(Knowledge Graph) 2. 知识图谱-命名实体识别(NER)详解 3. 哈工大LTP解析 1. 前言 从一开始的Google搜索,到现在的聊天机器人.大数据风控 ...

  10. 百度大脑UNIT3.0详解之知识图谱与对话

    如今,越来越多的企业想要在电商客服.法律顾问等领域做一套包含行业知识的智能对话系统,而行业或领域知识的积累.构建.抽取等工作对于企业来说是个不小的难题,百度大脑UNIT3.0推出「我的知识」版块专门为 ...

随机推荐

  1. 关于linq Where中的”或者“运算只查询出来满足一种条件的数据的问题,本质是IEnumerable和IQuerable之间的区别

    如下代码所示,其中的"query"返回值类型为IQuerable var query = _deviceRepository.GetAll().AsNoTracking() .Wh ...

  2. 前端仿今日头条、网易新闻 tabs组件,根据文字多少自适应tab项宽度,支持自定义标题栏

    快速实现 前端仿今日头条网易新闻 tabs 组件标签页,根据文字多少自适应 tab项宽度, 详情请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id ...

  3. 手写数字识别系统Python+CNN卷积神经网络算法【完整代码】

    一.介绍 手写数字识别系统,使用Python语言,基于TensorFlow搭建CNN卷积神经网络算法对数据集进行训练,最后得到模型,并基于FLask搭建网页端界面,基于Pyqt5搭建桌面端可视化界面. ...

  4. 6. SpringMVC的视图

    SpringMVC 中的视图是 View 接口,视图的作用渲染数据,将模型 Model 中的数据展示给用户 SpringMVC 视图的种类很多,默认有转发视图和重定向视图 当工程引入 jstl 的依赖 ...

  5. 精讲Mybatis··#{}和${}

    题目 笔记Notes 面试题目:#{}和${}的区别是什么? 网上的答案是:#{}是预编译处理,${}是字符串替换.mybatis在处理#{}时, 会将sql中的#{}替换为?号,调用Prepared ...

  6. Vue + Volo.Abp 实现Auth2.0客户端授权模式认证

    @ 目录 注册Client Auth2.0授权 创建vue-oidc-client 创建Auth2.0认证跳转 获取令牌 创建回调页面 创建退出登录 最终效果 Volo.Abp的身份服务器模块默认使用 ...

  7. CodeTON Round 5 (Div. 1 + Div. 2, Rated, Prizes!) A-E

    比赛链接 A 代码 #include <bits/stdc++.h> using namespace std; using ll = long long; bool solve() { i ...

  8. 2023年ccpc大学生程序设计竞赛-crf

    第一次参加这种大型线下程序设计比赛,心情自然是很激动,但比赛中并没有想象中那么顺利,甚至可以说有些惊险,比赛开始的时候,我们三人随便看看题,顺便等着跟榜,对于签到题我们自然是相信clk可以很快地独立完 ...

  9. Mysql基础7-约束

    一.约束的基本概念 1.概念:约束是作用于表中字段上的规则,用于限制储存在表中的数据 2.目的:保证数据库中的数据的正确性,有效性和完整性 3.分类 非空约束(not null):限制该字段的数据不能 ...

  10. 前端Vue自定义开屏启动广告组件,点击广告图跳转广告详情

    随着技术的发展,开发的复杂度也越来越高,传统开发方式将一个系统做成了整块应用,经常出现的情况就是一个小小的改动或者一个小功能的增加可能会引起整体逻辑的修改,造成牵一发而动全身. 通过组件化开发,可以有 ...