免费POC, 零成本试错
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


怎样将任意文本转换为知识图谱

发布日期:2025-08-25 17:23:14 浏览次数: 1536
作者:三人行AI

微信搜一搜,关注“三人行AI”

推荐语

从文本到知识图谱的转换技术揭秘,探索AI研究智能体的前沿应用。

核心内容:
1. 知识图谱的基本构成与核心价值解析
2. 基于Mistral 7B模型的本地化实现方案
3. 交互式可视化工具链的完整搭建指南

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家


不久前,基于知识的问答(Knowledge-based QnA,简称 KBQA)还是一种新鲜事物。
如今,借助 检索增强生成(Retrieval Augmented Generation,简称 RAG),
KBQA 已经成为任何 AI 爱好者的“家常便饭”。

令人着迷的是,随着大语言模型(LLMs)的发展,
自然语言处理(NLP)的可能性正在迅速扩展,
并且每天都在变得更好。

研究智能体:应对大规模文本语料问答的挑战

我创建了一个 自主 AI 研究智能体(Autonomous AI Research Agent), 它能够凭借 深度多跳推理能力 来回答复杂问题。

👉 towardsdatascience.com[1]

有不少人尝试了该方法并给我反馈。
感谢大家的意见!

我收集了这些建议,并对代码进行了改进,
以解决原始实现中的一些问题。
我计划写一篇独立的文章来介绍这些改进。

在本文中,
我想分享另一个想法:
当它与递归式 RAG 结合时,
可能有助于创建一个更强大的研究型智能体。

这个想法来源于我在小型 LLM 上进行的递归 RAG 实验,
以及在 Medium 上阅读的一些思路,
特别是 知识图谱增强生成(Knowledge-Graph Augmented Generation)

摘要

知识图谱(Knowledge Graph,简称 KG)或任何图结构,
由 节点(Nodes) 和 边(Edges) 组成。

每个 节点 代表一个概念每条  表示一对概念之间的关系

在本文中,
我将分享一种方法,
可以将任意文本语料转换为 概念图(Graph of Concepts,GC)

我在这里将“概念图(GC)”和“知识图谱(KG)”交替使用,
以更好地描述我要演示的内容。

本实现中使用的所有组件都可以在本地搭建,
因此该项目能够轻松在个人电脑上运行。

我采取了一种 不依赖 GPT 的方法, 因为我更倾向于使用小型开源模型。

在这里,
我使用了强大的 Mistral 7B OpenOrca instruct 和 Zephyr 模型。
这些模型可以通过 Ollama 在本地运行。

像 Neo4j 这样的数据库,
可以轻松存储和检索图数据。
但在这里,为了保持简单,
我使用了 Pandas 内存数据框 和 NetworkX Python 库

本文目标

将任意文本语料转换为概念图(GC)将其可视化,就像本文横幅图片中那样美观支持交互操作:拖动节点和边、缩放视图、修改图的物理属性

👉 GitHub 项目页面(效果展示): https://rahulnyk.github.io/knowledge_graph/

在开始介绍方法之前,
我们需要先理解 知识图谱的基本思想,以及我们为什么需要它。 如果你已经熟悉这些概念,
可以跳过下一节。

知识图谱示例

来看以下文本:

Mary had a little lamb,You’ve heard this tale before;But did you know she passed her plate,And had a little more!

下面是该文本作为知识图谱的一种可能表示:


下面这篇来自 IBM 的文章,非常贴切地解释了知识图谱的基本概念:

什么是知识图谱? | IBM[2]
了解知识图谱:语义元数据网络,用来表示一组相互关联的实体。

引用文章中的一段话来总结知识图谱的核心思想:

知识图谱(Knowledge Graph),又称语义网络(Semantic Network),
表示由现实世界中的实体(即对象、事件、情境或概念)组成的网络,
并说明它们之间的关系。
这些信息通常存储在图数据库中,并以图结构的形式可视化,
因此被称为“图谱”。


为什么需要知识图谱?

知识图谱的用途非常广泛。

我们可以运行图算法,计算任意节点的中心性,
以理解某个概念(节点)在整体工作中的重要性。
我们可以分析相连或不相连的概念集合,
或计算概念的社群(communities),
从而对主题有更深入的理解。
我们可以理解看似无关的概念之间的联系。

此外,知识图谱还可以用来实现 图检索增强生成(Graph Retrieval Augmented Generation,简称 GRAG 或 GAG),
让我们能够“和文档对话”。

这比传统的 RAG 效果更好,因为传统 RAG 存在一些缺陷。
例如,仅依赖语义相似度来检索最相关的上下文并不总是有效:

当查询没有提供足够的上下文来表达真实意图时;当相关上下文分散在庞大的语料库中时;
RAG 就可能难以发挥作用。

举个例子

假设我们有这样一个问题:

请告诉我在《百年孤独》一书中,José Arcadio Buendía 的家族谱系。

这本书记录了 José Arcadio Buendía 家族的 7 代人, 而且其中有一半的人物都叫 José Arcadio Buendía。
在这种情况下,想要用一个简单的 RAG 流程回答这个问题,几乎是不可能的挑战。

RAG 并不能告诉你该问什么问题。
然而,很多时候问对问题比得到答案更重要

图增强生成(Graph Augmented Generation,GAG)
在一定程度上可以解决这些问题。

更进一步,我们还可以结合两者, 构建一个 图增强的检索增强生成(Graph Augmented RAG) 流程,
从而获得两者的优势。

总结

图谱不仅有趣,而且非常有用。它能带来更强大的信息分析与推理能力。并且,它们的可视化效果往往非常美观。


创建概念图(Graph of Concepts)

如果你问 GPT:“如何从给定文本中创建一个知识图谱?”
它可能会建议如下流程:

1.提取文本中的概念和实体 —— 这些就是节点(nodes);2.提取概念之间的关系 —— 这些就是边(edges);3.将节点(概念)和边(关系)存储到图数据结构或图数据库中4.可视化 —— 即使只是为了美观。

步骤 3 和 4 很容易理解。
但 步骤 1 和 2 该如何实现呢?

方法流程图

下面是我设计的一个方法流程图,用来从任意文本语料中提取概念图。
它与上面的方法类似,但有一些细微差别。


主要步骤:

1.将文本语料分割为若干块(chunks),并为每个块分配一个 chunk_id2.对每个文本块,使用 LLM 提取概念及其语义关系给这种关系分配权重 W1相同的一对概念之间可以有多种关系。每种关系都表示为一条边。3.考虑上下文邻近性:同一文本块中出现的概念,默认也存在一定关系。给这种“上下文关系”分配权重 W2注意:相同的概念对可能出现在多个块中。4.合并相似的概念对累加它们的权重;合并它们的关系;最终,每对不同概念之间只保留一条边,边上既有权重,又有关系描述。

👉 本方法的 Python 实现代码可以在本文分享的 GitHub 仓库中查看。
接下来,我们将简要走读实现的关键思想。

示例语料

为了演示方法,这里我选用了一篇 在 PubMed/Cureus 上发表的综述文章(遵循 Creative Commons 署名协议)。
作者的署名在本文末尾致谢。

印度应对医疗卫生人力资源挑战的机遇 | Cureus[3]

印度的健康指标近年来有所改善,但仍落后于同类国家……

使用 Mistral 模型与提示词

在上面流程图中的 步骤 1 很容易:
Langchain 提供了丰富的 文本分割器(text splitters),
我们可以直接用来将文本分割为块。

真正有趣的是 步骤 2。 为了提取概念及其关系,我使用了 Mistral 7B 模型

在最终确定最佳变体之前,我尝试了以下几种:

Mistral InstructMistral OpenOrcaZephyr(Hugging Face 上基于 Mistral 的衍生模型)

我使用了这些模型的 4-bit 量化版本 ——
这样我的 Mac 就不会“崩溃”了 🤣 ——
并通过 Ollama 在本地运行。

👉 Ollama 官网[4]

一个可以在本地快速运行大语言模型的平台。

这些模型都是 指令微调(instruction-tuned) 模型,
包含系统提示(system prompt)和用户提示(user prompt)。
只要我们要求,它们通常能很好地遵循指令,并将结果整齐地格式化为 JSON

经过多次尝试,我最终选择了 Zephyr 模型,并使用如下提示词:

SYS_PROMPT =("You are a network graph maker who extracts terms and their relations from a given context. ""You are provided with a context chunk (delimited by ```) Your task is to extract the ontology ""of terms mentioned in the given context. These terms should represent the key concepts as per the context. \n""Thought 1: While traversing through each sentence, Think about the key terms mentioned in it.\n""\tTerms may include object, entity, location, organization, person, \n""\tcondition, acronym, documents, service, concept, etc.\n""\tTerms should be as atomistic as possible\n\n""Thought 2: Think about how these terms can have one on one relation with other terms.\n""\tTerms that are mentioned in the same sentence or the same paragraph are typically related to each other.\n""\tTerms can be related to many other terms\n\n""Thought 3: Find out the relation between each such related pair of terms. \n\n""Format your output as a list of json. Each element of the list contains a pair of terms""and the relation between them, like the follwing: \n""[\n""   {\n"'       "node_1""A concept from extracted ontology",\n''       "node_2""A related concept from extracted ontology",\n''       "edge""relationship between the two concepts, node_1 and node_2 in one or two sentences"\n'"   }, {...}\n""]")
USER_PROMPT = f"context: ```{input}``` \n\n output: "

如果我们把之前那首小诗丢进提示词中,
模型输出的结果如下:

[{"node_1":"Mary","node_2":"lamb","edge":"owned by"},{"node_1":"plate","node_2":"food","edge":"contained"},...]

请注意,模型甚至推断出了 “food(食物)” 这个概念, 虽然在原始文本片段中并没有明确提到。 是不是很神奇!

转换为 Pandas DataFrame 如果我们将示例文章的每个文本块都跑一遍, 然后把得到的 JSON 转换为 Pandas DataFrame, 结果大致如下:

这里 每一行 都表示一对概念之间的一种关系。 在图中,每一行对应 两个节点之间的一条边;同一对概念之间可以存在多条边/多种关系。 上面数据框中的 count 列,是我任意设为 4 的权重。

上下文邻近性

我假设:在文本语料中彼此位置接近出现的概念是相关的。
我们把这种关系称为 “上下文邻近性(contextual proximity)”

为了计算“上下文邻近性”的边:

1.melt 数据框: 将 node_1 与 node_2 “熔化”为同一列,使节点落到一个统一的列中。2.自连接(self-join): 以 chunk_id 作为键,对上述数据框做自连接; 这样,相同 chunk_id 的节点会两两成对,形成行(即潜在的边)。3.移除自环(self-loop): 这一步也会生成“节点与自身配对”的行(自环),
边的起点和终点是同一节点。 为了去除自环,我们删除所有 node_1 == node_2 的行。

最终,我们得到的这个数据框,与最初的语义关系数据框在结构上非常相似

countnode_1 与 node_2 共同出现的文本块(chunk)数量chunk_id:包含了所有这些共同出现的 chunk 列表

到目前为止,我们有了两个数据框:

1.语义关系(semantic relation)的数据框;2.上下文邻近性(contextual proximity)关系的数据框(基于同块共现)。

我们可以将两者合并,以形成网络图的数据框


可视化目标

至此,我们已经为文本构建好了概念图(Graph of Concepts)。 但如果就到这里戛然而止,未免意犹未尽。 我们的目标是将这个图可视化——就像本文开头的主图那样。
好消息是:我们离这个目标,已经不远了


创建概念网络

NetworkX 是一个 Python 库,使得图的处理变得非常简单。
如果你还不熟悉这个库,可以点击下方链接了解更多:

👉 NetworkX 官方文档[5]

将 DataFrame 转换为 NetworkX 图

把我们之前得到的数据框(DataFrame)加入到 NetworkX 图里,只需要几行代码。

import networkx as nx
# 创建一个空图G = nx.Graph()
# 添加节点for node in nodes:    G.add_node(str(node))
# 添加边for index, row in dfg.iterrows():    G.add_edge(        str(row["node_1"]),        str(row["node_2"]),        title=row["edge"],# 边的关系描述        weight=row["count"]# 边的权重(出现次数/强度))

NetworkX 自带了大量可直接调用的网络算法。 可在此查看算法清单与用法:

👉 Algorithms - NetworkX 3.2.1 文档[6]

这里我使用社区发现算法给节点分组并着色。 社区指的是:与图中其他节点相比,内部连接更紧密的一组节点。
在概念图中,社区往往对应文本中被讨论的主题簇,能帮助我们把握宏观主题

我对本文示例的综述文章运行 Girvan–Newman 算法后,检测到 17 个概念社区。 下面是其中一个社区的示例:

['digital technology','EVIN','medical devices','online training management information systems','wearable, trackable technology']

这立刻让我们对该综述论文中健康技术相关的宏观主题有了直观认识,并且还能据此提出更有针对性的问题,再用我们的 RAG 流程来回答。是不是很棒?🎉

接下来计算图中每个概念(节点)的度(degree)。 节点度指的是一个节点连接的边的总数。 在我们的场景里,度越高,说明该概念在整篇文本的主题中越居于中心。 在可视化中,我们将用节点度作为节点大小的依据(度越高,节点越大)。

图可视化

可视化是这项工作的最有趣的部分,它带来一种艺术层面的满足感

我使用 PyVis 库来创建交互式网络图。 PyVis 是一个用于网络可视化的 Python 库[7]

PyVis 内置了 NetworkX Helper,可以把我们的 NetworkX 图直接转换成 PyVis 对象, 因此几乎不需要额外编码——太省心啦!

回顾一下,我们已经准备好了以下用于可视化的要素:

边的权重:用于控制边的粗细节点的社区:用于控制节点的颜色节点的度:用于控制节点的大小

把这些“铃铛与口哨”(bells and whistles)都装上,我们的图就呈现在眼前了。

👉 点击查看互动图谱[8]

在这里,我们可以自由缩放,并随意拖动节点和边。 在页面底部还有一个滑块面板,用来调整图的物理效果。

通过这种方式,我们不仅能更好地理解主题,
还能帮助我们提出正确的问题,从而更深入地研究内容。

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

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

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

联系我们

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

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询