ChatGPT结合知识图谱构建医疗问答应用 (二) - 构建问答流程

文章介绍了如何结合ChatGPT和知识图谱构建医疗问答应用。通过opencypher_llm.py生成OpenCypher检索语句,然后使用GCLLM根据检索结果回答用户问题。系统处理用户输入,执行图谱查询,并提供答案。目前的流程仍有优化空间,如处理疾病名称错别字和多名称情况。
摘要由CSDN通过智能技术生成

一、ChatGPT结合知识图谱

上篇文章对医疗数据集进行了整理,并写入了知识图谱中,本篇文章将结合 ChatGPT 构建基于知识图谱的问答应用。

下面是上篇文章的地址:

ChatGPT结合知识图谱构建医疗问答应用 (一) - 构建知识图谱

在这里插入图片描述

这里实现问答的流程如下所示:

在这里插入图片描述

二、问答流程构建

opencypher_llm.py 根据问题理解生成 opencypher 语句

import os
from langchain.chat_models import ChatOpenAI
from langchain.schema import HumanMessage, SystemMessage
from langchain.output_parsers import StructuredOutputParser, ResponseSchema
import json


class OpenCypherLLM():

    def __init__(self):
        # 输出格式化
        self.response_schemas = [
            ResponseSchema(name="openCypher", description="生成的 OpenCypher 检索语句")
        ]
        self.output_parser = StructuredOutputParser.from_response_schemas(self.response_schemas)
        self.format_instructions = self.output_parser.get_format_instructions()

        # prompt 模版
        self.prompt = """
        你是一个知识图谱方面的专家, 现有一个医疗相关的知识图谱,图谱中的实体解释如下:\n
        --------------
        disease:疾病,存储着各种疾病的基础信息\n
        department:科室,疾病所对应的科室\n
        symptom:疾病的症状\n
        cureWay:疾病的治疗方式\n
        check:疾病的检查项目\n
        drug:疾病的用药\n
        crowd:疾病易感染人群\n
        food:食物,包括宜吃和忌吃食物\n
        --------------\n
        实体与实体之间的关系如下,每个关系都可以是双向的,v表示实体、e表示关系:\n
        --------------\n
        疾病科室关系:(v:disease)-[e:diseaseDepartmentRelations]->(v:department);
        疾病症状关系:(v:disease)-[e:diseaseSymptomRelation]->(v:symptom);
        疾病治疗关系:(v:disease)-[e:diseaseCureWayRelation]->(v:cureWay);
        疾病检查项目关系:(v:disease)-[e:diseaseCheckRelation]->(v:check);
        疾病用药关系:(v:disease)-[e:diseaseDrugRelation]->(v:drug);
        疾病易感染人群关系:(v:disease)-[e:diseaseCrowdRelation]->(v:crowd);
        疾病宜吃食物关系:(v:disease)-[e:diseaseSuitableFoodRelation]->(v:food);
        疾病忌吃食物关系:(v:disease)-[e:diseaseTabooFoodRelation]->(v:food);
        疾病并发症关系:(v:disease)-[e:diseaseDiseaseRelation]->(v:disease);
        --------------\n
        实体中的主要属性信息如下:\n
        --------------\n
        disease: {name:疾病名称,desc:疾病简介,prevent:预防措施,cause:疾病病因,get_prob:发病率,get_way:传染性,cure_lasttime:治疗周期,cured_prob:治愈概率,cost_money:大概花费}\n
        department: {name:科室名称}\n
        symptom: {name:疾病症状}\n
        cureWay: {name:治疗方式}\n
        check: {name:检查项目}\n
        drug: {name:药物名称}\n
        crowd: {name:感染人群}\n
        food: {name:食物}\n
        --------------
        根据以上背景结合用户输入的问题,生成 OpenCypher 图谱检索语句,可以精准检索到相关的知识信息作为背景。\n
        注意: 仅使用上述提供的实体、关系、属性信息,不要使用额外未提供的内容。实体与实体之间的关系仅使用背景给出的关系\n
        """
        self.prompt = self.prompt + self.format_instructions
        self.chat = ChatOpenAI(temperature=1, model_name="gpt-3.5-turbo")

    def run(self, questions):
        res = self.chat(
            [
                SystemMessage(content=self.prompt),
                HumanMessage(content="用户输入问题:" + questions)
            ]
        )
        res = res.content
        res = res.replace("```json", "").replace("```", "")
        res = json.loads(res)
        return res["openCypher"]
        

gc_llm.py 根据检索结果总结答案

import os
from langchain.chat_models import ChatOpenAI
from langchain.schema import HumanMessage, SystemMessage
from langchain import PromptTemplate

class GCLLM():

    def __init__(self):
        # prompt 模版
        self.template = """
        你是一个知识图谱方面的专家,图谱中的基本信息如下:\n
        --------------
        disease:疾病实体,存储着各种疾病的基础信息\n
        department:科室,疾病所对应的科室\n
        symptom:疾病的症状\n
        cureWay:疾病的治疗方式\n
        check:疾病的检查项目\n
        drug:疾病的用药\n
        crowd:疾病易感染人群\n
        food:食物,存吃包括宜吃和忌吃食物\n
        --------------\n
        上一步你生成的 OpenCypher 语句为:
        --------------\n
        {OpenCypher}
        --------------\n
        OpenCypher 语句查询的结果如下:
        --------------\n
        {content}
        --------------\n
        结合上述背景,并回答用户问题,如果提供的背景和用户问题没有相关性,则回答 “这个问题我还不知道怎么回答”
        注意:最后直接回复用户问题即可,不要添加 "根据查询结果" 等类似的修饰词
        """
        self.prompt = PromptTemplate(
            input_variables=["OpenCypher", "content"],
            template=self.template,
        )
        self.chat = ChatOpenAI(temperature=1, model_name="gpt-3.5-turbo")

    def run(self, OpenCypher, content, questions):
        res = self.chat(
            [
                SystemMessage(content=self.prompt.format(OpenCypher=OpenCypher, content=content)),
                HumanMessage(content="用户输入问题:" + questions)
            ]
        )
        return res.content


过程整合

from py2neo import Graph
from opencypher_llm import OpenCypherLLM
from gc_llm import GCLLM
import os


class QA():
    def __init__(self, kg_host, kg_port, kg_user, kg_password):
        self.graph = Graph(
            host=kg_host,
            http_port=kg_port,
            user=kg_user,
            password=kg_password)
        self.openCypherLLM = OpenCypherLLM()
        self.gcLLM = GCLLM()

    def execOpenCypher(self, cql):
        if "limit" not in cql and "LIMIT" not in cql:
            cql = cql + " LIMIT 10 "
        res = self.graph.run(cql)
        list = []
        for record in res:
            list.append(str(record))
        if len(list) == 0:
            return ""
        return "\n".join(list)

    def run(self, questions):
        if not questions or questions == '':
            return "输入问题为空,无法做出回答!"
        # 生成检索语句
        openCypher = self.openCypherLLM.run(questions)
        if not openCypher or openCypher == '':
            return "这个问题我还不知道怎么回答"
        print("========生成的CQL==========")
        print(openCypher)
        # 执行检索
        res = self.execOpenCypher(openCypher)
        print("========查询图谱结果==========")
        print(res)
        if not res or res == "":
            return "这个问题我还不知道怎么回答"
        return self.gcLLM.run(openCypher, res, questions)


if __name__ == '__main__':
    kg_host = "127.0.0.1"
    kg_port = 7474
    kg_user = "neo4j"
    kg_password = "123456"
    qa = QA(kg_host, kg_port, kg_user, kg_password)

    while True:
        questions = input("请输入问题: \n ")
        if questions == "q":
            break
        res = qa.run(questions)
        print("========问题回答结果==========")
        print(res)

三、效果测试

1. 鼻炎的症状有哪些

在这里插入图片描述

2. 鼻炎的治疗周期多久

在这里插入图片描述

3. 鼻炎不适合吃什么东西

在这里插入图片描述

3. 和鼻炎有类似症状的病有哪些

在这里插入图片描述

4. 鼻炎应该检查哪些项目

在这里插入图片描述

四、总结

上面基于医疗的知识图谱大致实现了问答的过程,可以感觉出加入ChatGPT后实现的流程非常简单,但上述流程也还有需要优化的地方,例如用户输入疾病错别字的情况如果 ChatGPT 没有更正有可能导致检索为空,还有就是有些疾病可能有多个名称但名称不在图谱中导致检索失败等等,后面可以考虑加入语义相似度的检索。

  • 13
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
转自CCF:https://dl.ccf.org.cn/lecture/lectureDetail?id=4663480272078848。 张勇,剑桥大学博士后。 摘要:健康医疗大数据是健康医疗活动的产物,同时也是进行健康医疗业务优化和辅助决策的基础。健康医疗大数据分散在多个主体管理的多个系统中,所以在应用健康医疗大数据的时候往往需要先进行数据釉合。然而由于生成数据的系统所采用的标准或规范不同,不同来源的数据之间经常存在数据不一致的情况,同时由于应用水平等题,数据的质量也存在较大题。数据不一 致和数据质量等题大大阻碍了数据融合的效率和效果。知识图谱作为作为一种灵活的数据模型,通过一张图来集成所有相关的数据,同时利用对齐等技术来解决数据中存在的题。本报告将从健康医疗大数据融合的数据模型、过程、工具和应用的角度来介绍如何应用知识图谱来进行健康医疗大数据融合。我们把健康医疗知识图谱分为概念图谱和实例图谱,定义了各 自的数据模型,然后分别介绍了各自的建立过程,以及两者之间如何建立关联。我们提出了“ 医在回路 ”的概念,对医生在构建健康领域知识图谱中的角色和职责进行了定义。基于这些数据模型,我们研发了健康知识图谱构建工具 HKGB 。该工具是一个易于扩展的、跨语言的、智能的知识图谱构建平台。基于该平台,我们构建了面向心血管疾病的知识图谱。最后本报告介绍了健康医疗知识图谱的应用情况。
ChatGPT知识图谱结合可以产生更加强大和智能的对话系统。ChatGPT作为一个基于大规模预训练的语言生成模型,具有很强的生成能力和语言理解能力。而知识图谱则是一种结构化的知识表示方式,可以用于存储和表示大量的实体、属性和关系。 通过将ChatGPT知识图谱结合,我们可以利用知识图谱中的丰富信息来辅助对话系统的生成。具体来说,可以通过以下几种方式实现结合: 1. 实体识别与链接:通过使用知识图谱中的实体识别和链接技术,将对话中的实体与知识图谱中的实体进行匹配和链接,从而丰富对话模型对实体的理解和回答。 2. 关系抽取与推理:利用知识图谱中的关系信息,可以帮助对话系统进行关系抽取和推理。例如,对于一个题“某电影的导演是谁?”,可以根据知识图谱中的电影-导演关系进行推理并给出回答。 3. 上下文感知:知识图谱可以作为对话系统的上下文信息,为模型提供更多背景知识。通过引入知识图谱的结构和关系,可以帮助对话系统更好地理解和生成上下文相关的回答。 4. 错误修正与一致性检查:知识图谱中的数据可以用于帮助对话系统进行错误修正和一致性检查。例如,如果ChatGPT生成的回答与知识图谱中的事实不一致,可以通过对比和校验来修正生成结果。 综上所述,通过将ChatGPT知识图谱结合,可以提升对话系统的知识表示能力、推理能力和上下文感知能力,使其更加智能和准确地回答用户的题。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小毕超

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值