2026年7月9日 周四晚上19:30,报名腾讯会议了解“如何构建自进化的动态知识库(Brain)”(限30人)
免费POC, 零成本试错
FDE知识库

FDE知识库

学习大模型的前沿技术与行业落地应用


收藏

使用 LLM 将 CSV 转换为知识图谱:医疗保健领域的案例

发布日期:2024-08-09 08:54:48 浏览次数: 2784
作者:码农大牛毛

微信搜一搜,关注“码农大牛毛”


R最近我读了一篇介绍neo4j-runway的文章。根据他们的Github 页面,“Neo4j Runway 是一个 Python 库,它简化了将关系数据迁移到图形中的过程。它提供了抽象与 OpenAI 通信的工具,以对数据运行发现并生成数据模型,以及生成提取代码并将数据加载到 Neo4j 实例中的工具”。翻译一下,通过上传 CSV,LLM 将找到节点和关系并自动生成知识图谱。

医疗保健领域的知识图谱是组织和分析复杂医疗数据的强大工具。这些图谱以一种更容易理解不同实体(例如疾病、治疗、患者和医疗保健提供者)之间关系的方式构建信息。

医疗保健领域的 KG 提供了一些有用的应用:

  • 多种数据源的整合:知识图谱可以整合来自各种来源的数据,例如电子健康记录 (EHR)、医学研究论文、临床试验结果、基因组数据和患者历史记录。

  • 改善临床决策支持:通过将症状、诊断、治疗和结果联系起来,知识图谱可以增强临床决策支持系统 (CDSS),因为它们考虑了大量相互关联的医学知识,有可能提高诊断准确性和治疗效果。在本文中,我将探讨这个话题。

  • 个性化医疗:知识图谱通过将患者特定数据与更广泛的医学知识关联起来,可以制定个性化治疗计划。这包括了解遗传信息、疾病机制和治疗反应之间的关系,从而制定更有针对性的医疗干预措施。

  • 药物发现与开发:在药物研究中,知识图谱可以通过识别潜在的药物靶点和了解疾病所涉及的生物学途径来加速药物发现。

  • 公共卫生和流行病学:知识图谱在公共卫生领域非常有用,可以追踪疾病爆发、了解流行病学趋势和规划干预措施,因为它们可以整合来自各种公共卫生数据库、社交媒体和其他来源的数据,提供对公共卫生威胁的实时洞察。



eo4j Runway是Alex Gilmore创建的开源库。您可以在此处找到该存储库,并在此处找到描述该库的博客

目前,该库仅支持 OpenAI LLM 解析 CSV,并提供以下功能:

  • 数据发现:利用 OpenAI LLM 从您的数据中提取有意义的见解。

  • 图形数据建模:使用 OpenAI 和 Instructor Python 库来开发精确的图形数据模型。

  • 代码生成:根据您喜欢的数据加载方法创建定制的提取代码。

  • 数据提取:利用 Runway 内置的 PyIngest 实现(一种广泛使用的 Neo4j 提取工具)来加载您的数据。

  • 不需要 Cypher 写作,因为 LLM 可以完成所有工作。

在这里,除了让 LLM 将所有 CSV 转换为知识图谱之外,我还使用了 Langchain 的GraphCypherQAChain作为最后一步从提示中生成密码,以便我们无需编写一行密码即可查询图表(用于查询 Neo4j 图表数据库的类似 SQL 的语言)。

该库的 Github 页面上有一个财务示例,但我想测试它是否适用于医疗保健情况。从 Kaggle 上一个非常简单的数据集(疾病症状和患者资料数据集)开始,只有 10 列(疾病、发烧、咳嗽、疲劳、呼吸困难、年龄、性别、血压、胆固醇水平和结果变量),我希望能够向 LLM 提供医疗报告以获得诊断假设。



大号让我们直接进入代码。首先是库:

sudo apt 安装 python3-pydot graphviz
pip 安装 neo4j-runway
导入numpy作为np
导入pandas作为pd
neo4j_runway导入 DiscoveryGraphDataModelerIngestionGeneratorLLMPyIngest
IPython导入。显示 导入display、MarkdownImage

加载环境变量:您可以阅读我的另一篇文章,了解如何在 Neo4j Aura 中创建实例并进行身份验证。

load_dotenv() 
OPENAI_API_KEY = os.getenv ( ' sk-openaiapikeyhere' ) NEO4J_URL = os.getenv ( 'neo4j+s://your.databases.neo4j.io ' ) NEO4J_PASSWORD = os.getenv ( ' yourneo4jpassword ' )

现在,让我们加载医疗数据。从Kaggle 网站下载 CSV并加载到 Jupyter 笔记本中。这是一个非常简单的数据集,但对于测试概念很有用。

disease_df = pd.read_csv( '/home/user/Disease_symptom.csv' ) 
disease_df



例如,我们可以创建一个导致呼吸困难的所有疾病的列表,这不仅对于选择图中的节点非常有趣,而且对于制定诊断假设也非常有趣:

disease_df[disease_df[ '呼吸困难' ]== '是' ]

让我们继续。所有变量都必须是字符串(库就是这样创建的),甚至是整数。然后,我们保存 CSV:

disease_df.columns = disease_df.columns. str .strip() 
for i in disease_df.columns:
disease_df[i] = disease_df[i].astype( str )
disease_df.to_csv( '/home/user/disease_prepared.csv' , index= False )

现在,我们将描述 LLM 的数据,包括每个字段的可能值:

DATA_DESCRIPTION = { 
'疾病''疾病或医疗状况的名称。'
'发烧''表示患者是否发烧(是/否)。'
'咳嗽''表示患者是否咳嗽(是/否)。'
'疲劳''表示患者是否感到疲劳(是/否)。'
'呼吸困难''表示患者是否呼吸困难(是/否)。'
'年龄''患者的年龄。'
'性别''患者的性别(男/女)。'
'血压''患者的血压水平(正常/高)。'
'胆固醇水平''患者的胆固醇水平(正常/高)。' ,
'结果变量' : '表示特定疾病的诊断或评估结果的结果变量(阳性/阴性)。'
}

下一步是要求 LLM 分析表格数据,以识别对生成图形数据模型很重要的数据元素。

disc = Discovery(llm=llm,user_input=DATA_DESCRIPTION,data=disease_df)
disc.run()

这将生成数据分析的 Markdown 输出:



太好了。现在,让我们创建初始模型:

# 实例化图形数据建模器
gdm = GraphDataModeler(llm=llm, discovery=disc)

# 生成模型
gdm.create_initial_model()

# 可视化数据模型
gdm.current_model.visualize()



在这里,我的重点是疾病,因此我们将重新排序一些关系。

gdm.iterate_model(user_corrections= '''
让我们一步一步思考。 请对数据模型进行以下更新:
1. 删除患者与疾病、患者与症状以及患者与结果之间的关系。
2. 将患者节点更改为人口统计。
3. 创建从疾病到人口统计的关系 HAS_DEMOGRAPHICS。
4. 创建从疾病到症状的关系 HAS_SYMPTOM。如果症状值为否,请删除此关系。
5. 创建从疾病到健康指标的关系 HAS_LAB。
6. 创建从疾病到结果的关系 HAS_OUTCOME。
'''
)

from IPython.display import Image, display
gdm.current_model.visualize().render( 'output' , format = 'png' )
# 加载并以特定宽度显示图像
img = Image( 'output.png' , width= 1200 ) # 调整宽度根据需要
显示(img)



现在我们可以生成 Cypher 代码和 YAML 文件来将数据加载到 Neo4j 中。以防万一,如果您只是测试或第二次执行此操作,您可能需要将实例重置为空白(删除所有内容)。

# 实例化摄取生成器
gen = IngestionGenerator(data_model=gdm.current_model,
username= "neo4j" ,
password= 'yourneo4jpasswordhere' ,
uri= 'neo4j+s://123654888.databases.neo4j.io' ,
database= "neo4j" ,
csv_dir= "/home/user/" ,
csv_name= "disease_prepared.csv" )

# 创建摄取 YAML
pyingest_yaml = gen.generate_pyingest_yaml_string()

# 保存 YAML 的本地副本
gen.generate_pyingest_yaml_file(file_name= "disease_prepared" )

一切准备就绪。让我们将数据加载到实例中:

PyIngest(yaml_string=pyingest_yaml,数据框=disease_df)

转到Neo4j Aura 实例打开,添加您的密码并通过密码运行此查询:

匹配(n)
其中n:人口统计数据n:疾病n:症状n:结果n:健康指标
可选匹配(n) - [r] - > (m)
返回n、r、m



按 CTRL + ENTER 你将得到以下结果:



通过检查节点和关系,我们发现症状、健康指标和人口统计数据之间存在着巨大的相互联系:



让我们看看糖尿病:由于没有应用任何过滤器,因此会出现男性和女性,以及所有的实验室、人口统计和结果可能性。

匹配(n:疾病 {name:'糖尿病' })
其中n:人口统计资料n:疾病n:症状n:结果n:健康指标
可选匹配(n) - [r] - > (m)
返回n、r、m



或者可能是所有在临床检查中表现为高血压的疾病:

//匹配疾病节点MATCH (d:Disease) //疾病节点 HAS_LAB关系实验室节点匹配MATCH (d) - [r:HAS_LAB] - > (l) MATCH (d) - [r2:HAS_OUTCOME] - > (o) //确保实验室节点的 bloodPressure 属性设置High” WHERE l.bloodPressure = 'High' AND o.result = 'Positive' RETURN d, properties(d) AS disease_properties, r, properties(r) AS relationship_properties, l, properties(l) AS lab_properties








现在我的目标很清楚了:我想向谷歌的 LLM(在本例中为Gemini-1.5-Flash)提交一份医疗报告,以便它通过 Langchain(GraphCypherQAChain)自动创建密码查询,根据症状、健康指标等返回患者可能患有的疾病。让我们这样做:

导入警告langchain_community
导入json 导入带有警告的Neo4 jGraph。catch_warnings ():警告。simplefilter 'ignore'NEO4J _USERNAME = “neo4j” NEO4J _DATABASE = ' neo4j'NEO4J _URI = 'neo4j+s://1236547.databases.neo4j.io'NEO4J _PASSWORD = ' yourneo4jdatabasepasswordhere '








从实例和模式中获取知识图谱:这里有节点属性和关系属性。

kg = Neo4jGraph(
url=NEO4J_URI,用户名=NEO4J_USERNAME,密码=NEO4J_PASSWORD,数据库=NEO4J_DATABASE


kg.refresh_schema()
打印(textwrap.fill(kg.schema,60))
schema=kg.schema



让我们初始化 Vertex AI Gemini-1.5-Flash:

langchain.prompts.prompt导入PromptTemplate
langchain.chains导入GraphCypherQAChain
langchain.llms导入VertexAI

# 初始化 Vertex AI
vertexai.init(project= "your-project" , location= "us-west4" )

llm = VertexAI(model= "gemini-1.5-flash" )

现在,最难的部分是:为 Gemini-1.5-Flash 创建一个详细的指令,以自动生成密码来查询图形数据库并获取我们需要的结果。我们需要一个 MASTER 提示!???? CoT + 少量提示。

prompt_template = """
让我们一步一步思考:

步骤1: 任务:
生成一个有效且简洁的 Cypher 语句,该语句少于 256 个字符,用于查询图形数据库
不要注释代码。

步骤2:了解数据库模式:{schema}

步骤3:说明:
- 在 Cypher 查询中,仅使用模式中和用户问题中出现的关系类型和属性。
- 在 Cypher 查询中,请勿使用用户问题中未包含在所提供模式中的任何其他关系类型或属性。
- 关于年龄,永远不要使用年龄本身。例如:24 岁,使用间隔:超过 20 岁。
- 对年龄仅使用一个语句,始终使用“大于”,永远不要使用“小于”或“等于”。
- 请勿使用数据库中没有的属性键。

步骤4:示例:
以下是针对特定问题生成的 Cypher 语句的几个示例:

4.1 哪些疾病会导致高血压压力?
MATCH (d:Disease)
MATCH (d)-[r:HAS_LAB]->(l)
WHERE l.bloodPressure = 'High'
RETURN d.name

4.2 哪些疾病的表现为高血压?
// 匹配疾病节点
MATCH (d:Disease)
// 将疾病节点与实验室节点的 HAS_LAB 关系匹配
MATCH (d)-[r:HAS_LAB]->(l)
MATCH (d)-[r2:HAS_OUTCOME]->(o)
// 确保实验室节点的 bloodPressure 属性设置为 'High'
WHERE l.bloodPressure = 'High' AND o.result='Positive'
RETURN d, properties(d) AS disease_properties, r, properties(r) AS relationship_properties, l, properties(l) AS lab_properties

4.3 老年患者出现高血压、高胆固醇、发烧、疲劳等症状的疾病名称是什么
MATCH (d:Disease)
MATCH (d)-[r1:HAS_LAB]->(lab)
MATCH (d)-[r2:HAS_SYMPTOM]->(symptom)
MATCH (symptom)-[r3:HAS_DEMOGRAPHICS]->(demo)
WHERE lab.bloodPressure = 'High' AND lab.cholesterolLevel = 'High' AND symptom.fever = 'Yes' AND symptom.fatigue = 'Yes' AND TOINTEGER(demo.age) >40
RETURN d.name

4.4 什么疾病会导致高胆固醇患者发烧、疲劳、不咳嗽、不呼吸短促?
匹配 (d:Disease)-[r:HAS_SYMPTOM]->(s:Symptom)
其中 s.fever = '是' 并且 s.fatigue = '是' 并且 s.difficultyBreathing = '否' 并且 s.cough = '否'
匹配 (d:Disease)-[r1:HAS_LAB]->(lab:HealthIndicator)
匹配 (d)-[r2:HAS_OUTCOME]->(o:Outcome)
其中 lab.cholesterolLevel='高' 并且 o.result='Positive'
返回 d,属性(d)作为 disease_properties,r,属性(r)作为 relationship_properties


步骤 5. 每个实体允许的值如下:
- 发烧:表示患者是否发烧(是/否)。
- 咳嗽:表示患者是否咳嗽(是/否)。
- 疲劳:表示患者是否感到疲劳(是/否)。
- 呼吸困难:表示患者是否呼吸困难(是/否)。
- 年龄:患者的年龄。
- 性别:患者的性别(男/女)。
- 血压:患者的血压水平(正常/高)。
- 胆固醇水平:患者的胆固醇水平(正常/高)。
- 结果变量:表示特定疾病的诊断或评估结果的结果变量(阳性/阴性)。

步骤 6. 回答问题 {question}。"""

我们建立了 GraphCypherQAChain……

cypher_prompt = PromptTemplate( 
input_variables=[ "schema" , "question" ],
template=prompt_template
)

cypherChain = GraphCypherQAChain.from_llm(
VertexAI(temperature= 0.1 ),
graph=kg,
verbose= True ,
cypher_prompt=cypher_prompt,
top_k= 10 # 这也可以调整
)

…并提交医疗报告:

cypherChain.run( """
患者信息:
Jane Doe,58 岁女性,于 2024 年 6 月 15 日入院。

主诉和现病史:
Jane 报告高烧高达 104°F,身体疼痛,皮疹,
从入院前五天开始。

既往病史:
Jane 没有重大既往病史,也没有已知的过敏症。

体格检查:
Jane 的体温为 102.8°F,心率为 110 bpm,血压为 100/70 mmHg,呼吸频率为
每分钟 20 次。未发现瘀点或紫癜。

她可能患有什么疾病?"""
)

输出:这里Gemini-.5-Flash生成密码来查询图形数据库,通过 JSON 返回 LLM 的结果,LLM 对其进行解释并返回可读的响应:



这个结果没有考虑Gemini-1.5-Flash的知识库,而只考虑了它正在查询的知识图谱。想象一下,如果我们有一个包含 300 个特征的漂亮数据集!

请注意,我们可以将GraphCypherQAChain中的top_k调整为1或任何其他值:



如果我们运行最后一个查询,我们将获得具有这些症状的 77 种疾病的列表,但top_k设置为1



当前neo4j-runway项目处于测试阶段,存在以下限制:

  • 单一 CSV 输入仅用于数据模型生成

  • 节点只能有一个标签

  • 仅支持唯一性和节点/关系键约束

  • 关系可能没有唯一性约束

  • 模型生成不支持引用相同节点属性的 CSV 列

  • 目前只能使用 OpenAI 模型

  • Runway 中包含的修改后的 PyIngest 函数仅支持加载本地 Pandas DataFrame 或 CSV


53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询

扫码登录
登录即表示您同意《53AI网站服务协议》
服务协议

欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。

在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。

一、 定义

本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。

会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。

知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。

二、 账号注册与登录

登录方式:本网站支持以下登录方式,您可根据实际情况选择:

微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。

手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。

账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。

实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。

未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。

三、 服务内容与规范

知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。

服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。

禁止行为:您在使用服务时不得实施以下行为:

利用技术手段批量爬取、下载、转存知识库内容;

将知识库内容用于商业目的或未经授权地向第三方传播;

干扰本网站正常运行或侵犯其他用户合法权益;

发布违法违规信息或从事违反公序良俗的活动。

四、 知识产权声明

权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。

有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。

侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。

五、 个人信息保护

我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。

您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。

您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。

六、 免责声明

内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。

不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。

第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。

七、 违约责任

如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。

如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。

八、 法律适用与争议解决

本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。

因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。

九、 其他

本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。

本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。

我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。


已查阅