End-to-End从混沌到秩序:基于LLM的Pipeline将非结构化数据转化为知识图谱

news2025/4/21 1:17:36

摘要:本文介绍了一种将非结构化数据转换为知识图谱的端到端方法。通过使用大型语言模型(LLM)和一系列数据处理技术,我们能够从原始文本中自动提取结构化的知识。这一过程包括文本分块、LLM 提示设计、三元组提取、归一化与去重,最终利用 NetworkX 和 ipycytoscape 构建并可视化知识图谱。该方法不仅能够高效地从文本中提取知识,还能通过交互式可视化帮助用户更好地理解和分析数据。通过实验,我们展示了该方法在处理复杂文本时的有效性和灵活性,为知识图谱的自动化构建提供了新的思路。

🧠 向所有学习者致敬!

“学习不是装满一桶水,而是点燃一把火。” —— 叶芝


我的博客主页: https://lizheng.blog.csdn.net

🌐 欢迎点击加入AI人工智能社区!

🚀 让我们一起努力,共创AI未来! 🚀


从纯文本构建知识图谱是一项挑战。它通常需要识别重要术语,弄清楚它们之间的关系,并使用自定义代码或机器学习工具来提取这种结构。我们将创建一个由大型语言模型(LLM)驱动的端到端流水线,自动将原始文本转换为交互式知识图谱。
我们将使用几个关键的 Python 库来完成这项工作。让我们先安装它们。

# 安装库(只运行一次)

pip install openai networkx "ipycytoscape>=1.3.1" ipywidgets pandas

安装完成后,你可能需要重启 Jupyter 内核或运行时,以便更改生效。

现在我们已经安装好了,让我们将所有内容导入到脚本中。

import openai             # 用于 LLM 交互
import json               # 用于解析 LLM 响应
import networkx as nx     # 用于创建和管理图数据结构
import ipycytoscape       # 用于交互式笔记本中的图可视化
import ipywidgets         # 用于交互式元素
import pandas as pd       # 用于以表格形式显示数据
import os                 # 用于访问环境变量(API 密钥更安全)
import math               # 用于基本数学运算
import re                 # 用于基本文本清理(正则表达式)
import warnings           # 抑制潜在的弃用警告

完美!我们的工具箱已经准备好了。所有必要的库都已加载到我们的环境中。

什么是知识图谱?

想象一个网络,有点像社交网络,但除了人之外,它还连接事实和概念。这基本上就是一个知识图谱(KG)。它有两个主要部分:

  • 节点(或实体):这些是“事物”——比如“居里夫人”、“物理学”、“巴黎”、“诺贝尔奖”。在我们的项目中,我们提取的每个独特的主语或宾语都将变成一个节点。
  • 边(或关系):这些是事物之间的连接,显示它们如何关联。关键在于,这些连接有意义,并且通常有方向。例如:“居里夫人” — 获得 → “诺贝尔奖”。其中的“获得”部分是关系,定义了边。

最简单的知识图谱示例

一个简单的图,显示两个节点(例如,“居里夫人”和“镭”)通过一个标记为“发现”的有向边连接。再添加一个小集群,如(“巴黎” — 位于 → “索邦大学”)。这可视化了节点-边-节点的概念。

知识图谱之所以强大,是因为它们以更接近我们思考连接的方式结构化信息,使我们更容易发现见解,甚至推断出新的事实。

主语-谓语-宾语(SPO)三元组

那么,我们如何从纯文本中获取这些节点和边呢?我们寻找简单的事实陈述,通常以 主语-谓语-宾语(SPO) 三元组的形式出现。

  • 主语:事实是关于谁或什么的(例如,“居里夫人”)。将成为一个节点。
  • 谓语:连接主语和宾语的动作或关系(例如,“发现”)。将成为边的标签。
  • 宾语:主语相关的事物(例如,“镭”)。将成为另一个节点。

示例:句子 “居里夫人发现了镭” 完美地分解为三元组:(居里夫人, 发现, 镭)。

这直接翻译到我们的图中:

  • (居里夫人) -[发现]-> (镭)。

我们的 LLM 的工作就是读取文本并为我们识别这些基本的 SPO 事实。

配置我们的 LLM 连接

要使用 LLM,我们需要告诉脚本如何与之通信。这意味着提供一个 API 密钥,有时还需要一个特定的 API 端点(URL)。

我们将使用 NebiusAI LLM 的 API,但你可以使用 Ollama 或任何其他在 OpenAI 模块下工作的 LLM 提供商。

# 如果使用标准 OpenAI
export OPENAI_API_KEY='your_openai_api_key_here'# 如果使用本地模型,如 Ollama
export OPENAI_API_KEY='ollama' # 对于 Ollama,可以是任何非空字符串
export OPENAI_API_BASE='http://localhost:11434/v1'# 如果使用其他提供商,如 Nebius AI
export OPENAI_API_KEY='your_provider_api_key_here'
export OPENAI_API_BASE='https://api.studio.nebius.com/v1/' # 示例 URL

首先,让我们指定我们想要使用的 LLM 模型。这取决于你的 API 密钥和端点可用的模型。

# --- 定义 LLM 模型 ---

# 选择在你的配置端点可用的模型。

# 示例:'gpt-4o', 'gpt-3.5-turbo', 'llama3', 'mistral', 'deepseek-ai/DeepSeek-Coder-V2-Lite-Instruct', 'gemma'

llm_model_name = "deepseek-ai/DeepSeek-V3" # <-- **_ 更改为你使用的模型 _**

好的,我们已经记录下了目标模型。现在,让我们从之前设置的环境变量中获取 API 密钥和基础 URL(如果需要)。

# --- 获取凭据 ---

api_key = os.getenv("OPENAI_API_KEY")
base_url = os.getenv("OPENAI_API_BASE") # 如果未设置,则为 None(例如,对于标准 OpenAI)

客户端已准备好与 LLM 通信。

最后,让我们设置一些控制 LLM 行为的参数:

  • 温度:控制随机性。较低的值意味着更专注、更确定性的输出(适合事实提取!)。我们将温度设置为 0.0,以实现最大的可预测性。
  • 最大令牌数:限制 LLM 响应的长度。
# --- 定义 LLM 调用参数 ---

llm_temperature = 0.0 # 较低的温度用于更确定性、事实性的输出。0.0 是提取的最佳选择。
llm_max_tokens = 4096 # LLM 响应的最大令牌数(根据模型限制调整)

定义我们的输入文本(原材料)

现在,我们需要将要转换为知识图谱的文本。我们将使用居里夫人的传记作为示例。

unstructured_text = """
Marie Curie, born Maria Skłodowska in Warsaw, Poland, was a pioneering physicist and chemist.
She conducted groundbreaking research on radioactivity. Together with her husband, Pierre Curie,
she discovered the elements polonium and radium. Marie Curie was the first woman to win a Nobel Prize,
the first person and only woman to win the Nobel Prize twice, and the only person to win the Nobel Prize
in two different scientific fields. She won the Nobel Prize in Physics in 1903 with Pierre Curie
and Henri Becquerel. Later, she won the Nobel Prize in Chemistry in 1911 for her work on radium and
polonium. During World War I, she developed mobile radiography units, known as 'petites Curies',
to provide X-ray services to field hospitals. Marie Curie died in 1934 from aplastic anemia, likely
caused by her long-term exposure to radiation."""

让我们打印出来,看看它的长度。

print("--- 输入文本已加载 ---")
print(unstructured_text)
print("-" \* 25)

# 基本统计信息可视化

char_count = len(unstructured_text)
word_count = len(unstructured_text.split())
print(f"总字符数:{char_count}")
print(f"大约单词数:{word_count}")
print("-" \* 25)#### 输出结果 ####
--- 输入文本已加载 ---
Marie Curie, born Maria Skłodowska in Warsaw, Poland, was a pioneering physicist and chemist.
She conducted groundbreaking research on radioactivity. Together with her husband, Pierre Curie,

# [... 文本其余部分在此打印 ...]

includes not only her scientific discoveries but also her role in breaking gender barriers in academia
and science.-------------------------
总字符数:1995
大约单词数:324

---

所以,我们有大约 324 个单词的居里夫人的文本,虽然在生产环境中不太理想,但足以看到知识图谱构建的过程。

切分它:文本分块

LLM 通常有一个处理文本的限制(它们的“上下文窗口”)。

我们的居里夫人文本相对较短,但对于更长的文档,我们肯定需要将它们分解为更小的部分,或分块。即使是这种文本,分块有时也能帮助 LLM 更专注于特定部分。

我们将定义两个参数:

  • 分块大小:每个分块中我们希望的最大单词数。
  • 重叠:一个分块的末尾与下一个分块的开头之间应该有多少单词重叠。这种重叠有助于保留上下文,避免事实被尴尬地截断在分块之间。

文本分块过程

我们的完整文本被划分为三个重叠的段(分块)。清晰标记“分块 1”、“分块 2”、“分块 3”。突出显示分块 1 与 2 之间以及分块 2 与 3 之间的重叠部分。标记“分块大小”和“重叠大小”。

让我们设置我们期望的大小和重叠。

# --- 分块配置 ---

chunk_size = 150 # 每个分块的单词数(根据需要调整)
overlap = 30 # 分块之间的重叠单词数(必须小于分块大小)print(f"分块大小设置为:{chunk_size} 单词")
print(f"重叠设置为:{overlap} 单词")# --- 基本验证 ---
if overlap >= chunk_size and chunk_size > 0:
print(f"错误:重叠 ({overlap}) 必须小于分块大小 ({chunk_size})。")
raise SystemExit("分块配置错误。")
else:
print("分块配置有效。")### 输出结果 ###
分块大小设置为:150 单词
重叠设置为:30 单词
分块配置有效。

好的,计划是将分块大小设置为 150 个单词,分块之间的重叠为 30 个单词。

首先,我们需要将文本拆分为单独的单词。

words = unstructured_text.split()
total_words = len(words)print(f"文本拆分为 {total_words} 个单词。")

# 显示前 20 个单词

print(f"前 20 个单词:{words[:20]}")### 输出结果 ###
文本拆分为 324 个单词。
前 20 个单词:['Marie', 'Curie,', 'born', 'Maria', 'Skłodowska', 'in',
'Warsaw,', 'Poland,', 'was', 'a', 'pioneering', 'physicist', 'and',
'chemist.', 'She', 'conducted', 'groundbreaking', 'research', 'on',
'radioactivity.']

输出确认我们的文本有 324 个单词,并显示了前几个单词。现在,让我们应用我们的分块逻辑。

我们将逐步遍历单词列表,每次抓取 chunk_size 个单词,然后回退 overlap 个单词以开始下一个分块。

chunks = []
start_index = 0
chunk_number = 1print(f"开始分块过程...")
while start_index < total_words:
    end_index = min(start_index + chunk_size, total_words)
    chunk_text = " ".join(words[start_index:end_index])
    chunks.append({"text": chunk_text, "chunk_number": chunk_number})    # print(f"  Created chunk {chunk_number}: words {start_index} to {end_index-1}") # Uncomment for detailed log    # 计算下一个分块的起始位置
    next_start_index = start_index + chunk_size - overlap    # 确保有进展
    if next_start_index <= start_index:
        if end_index == total_words:
             break # 已经处理了最后一部分
        next_start_index = start_index + 1    start_index = next_start_index
    chunk_number += 1    # 安全中断(可选)
    if chunk_number > total_words: # 简单安全检查
        print("警告:分块循环超出总单词数,中断。")
        breakprint(f"\n文本成功拆分为 {len(chunks)} 个分块。")#### 输出结果 ####
开始分块过程...文本成功拆分为 3 个分块。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2339108.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySql 三大日志(redolog、undolog、binlog)详解

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/aa730ab3f84049638f6c9a785e6e51e9.png 1. redo log&#xff1a;“你他妈别丢数据啊&#xff01;” 干啥的&#xff1f; 这货是InnoDB的“紧急备忘录”。比如你改了一条数据&#xff0c;MySQL怕自己突然断电嗝屁了&am…

HTTP:九.WEB机器人

概念 Web机器人是能够在无需人类干预的情况下自动进行一系列Web事务处理的软件程序。人们根据这些机器人探查web站点的方式,形象的给它们取了一个饱含特色的名字,比如“爬虫”、“蜘蛛”、“蠕虫”以及“机器人”等!爬虫概述 网络爬虫(英语:web crawler),也叫网络蜘蛛(…

2025妈妈杯数学建模C题完整分析论文(共36页)(含模型建立、可运行代码、数据)

2025 年第十五届 MathorCup 数学建模C题完整分析论文 目录 摘 要 一、问题分析 二、问题重述 三、模型假设 四、 模型建立与求解 4.1问题1 4.1.1问题1思路分析 4.1.2问题1模型建立 4.1.3问题1代码&#xff08;仅供参考&#xff09; 4.1.4问题1求解结果&#xff08;仅…

数据结构排序算法全解析:从基础原理到实战应用

在计算机科学领域&#xff0c;排序算法是数据处理的核心技术之一。无论是小规模数据的简单整理&#xff0c;还是大规模数据的高效处理&#xff0c;选择合适的排序算法直接影响着程序的性能。本文将深入解析常见排序算法的核心思想、实现细节、特性对比及适用场景&#xff0c;帮…

UMG:ListView

1.创建WBP_ListView,添加Border和ListView。 2.创建Object,命名为Item(数据载体&#xff0c;可以是其他类型)。新增变量name。 3.创建User Widget&#xff0c;命名为Entry(循环使用的UI载体).添加Border和Text。 4.设置Entry继承UserObjectListEntry接口。 5.Entry中对象生成时…

每天学一个 Linux 命令(18):mv

​​可访问网站查看&#xff0c;视觉品味拉满&#xff1a; http://www.616vip.cn/18/index.html 每天学一个 Linux 命令&#xff08;18&#xff09;&#xff1a;mv 命令功能 mv&#xff08;全称&#xff1a;move&#xff09;用于移动文件/目录或重命名文件/目录&#xff0c;是…

ubuntu24.04上使用qemu和buildroot模拟vexpress-ca9开发板构建嵌入式arm linux环境

1 准备工作 1.1 安装qemu 在ubuntu系统中使用以下命令安装qemu。 sudo apt install qemu-system-arm 安装完毕后&#xff0c;在终端输入: qemu- 后按TAB键&#xff0c;弹出下列命令证明安装成功。 1.2 安装arm交叉编译工具链 sudo apt install gcc-arm-linux-gnueabihf 安装之…

IntelliSense 已完成初始化,但在尝试加载文档时出错

系列文章目录 文章目录 系列文章目录前言一、原因二、使用步骤 前言 IntelliSense 已完成初始化&#xff0c;但在尝试加载文档时出错 File path: E:\QtExercise\DigitalPlatform\DigitalPlatform\main\propertyWin.ui Frame GUID:96fe523d-6182-49f5-8992-3bea5f7e6ff6 Frame …

【更新完毕】2025泰迪杯数据挖掘竞赛A题数学建模思路代码文章教学:竞赛论文初步筛选系统

完整内容请看文末最后的推广群 基于自然语言处理的竞赛论文初步筛选系统 基于多模态分析的竞赛论文自动筛选与重复检测模型 摘要 随着大学生竞赛规模的不断扩大&#xff0c;参赛论文的数量激增&#xff0c;传统的人工筛选方法面临着工作量大、效率低且容易出错的问题。因此&…

服务器内存规格详解

服务器内存规格详解 一、内存安装原则与配置规范 1. 内存槽位安装规则 规则描述CPU1对应的内存槽位至少需配置一根内存禁止混用不同规格&#xff08;容量/位宽/rank/高度&#xff09;内存条&#xff0c;需保持相同Part No.推荐完全平衡的内存配置&#xff0c;避免通道/处理器…

Vue3+Vite+TypeScript+Element Plus开发-22.客制Table组件

系列文档目录 Vue3ViteTypeScript安装 Element Plus安装与配置 主页设计与router配置 静态菜单设计 Pinia引入 Header响应式菜单缩展 Mockjs引用与Axios封装 登录设计 登录成功跳转主页 多用户动态加载菜单 Pinia持久化 动态路由 -动态增加路由 动态路由-动态删除…

江苏广电HC2910-创维代工-Hi3798cv200-2+8G-海美迪安卓7.0-强刷包

江苏广电HC2910-创维代工-Hi3798cv200-28G-海美迪安卓7.0-强刷包 说明 1、由于原机的融合网关路由不能设置&#xff0c;原网口无法使用&#xff0c;需要用usb2.0的RJ45usb网卡接入。 通过usb接口网卡联网可以实现百兆网口连接。原机usb3.0的接口可以以接入硬盘&#xff0c;播放…

nvm切换node版本后,解决npm找不到的问题

解决方法如下 命令行查看node版本 node -v找到node版本所对应的npm版本 点击进入node版本 npm对应版本下载 点击进入npm版本 下载Windows 压缩包 下载完成后&#xff0c;解压&#xff0c;文件改名为npm 复制到你nvm对应版本的node_modules 下面 将下载的npm /bin 目录…

Windows系统安装MySQL安装实战分享

以下是在 Windows 系统上安装 MySQL 的详细实战步骤&#xff0c;涵盖下载、安装、配置及常见问题处理。 一、准备工作 下载 MySQL 安装包 访问 MySQL 官网。选择 MySQL Community Server&#xff08;免费版本&#xff09;。根据系统位数&#xff08;32/64位&#xff09;下载 …

Vue 人看 React useRef:它不只是替代 ref

如果你是从 Vue 转到 React 的开发者&#xff0c;初见 useRef 可能会想&#xff1a;这不就是 React 版的 ref 吗&#xff1f;但真相是 —— 它能做的&#xff0c;比你想象得多得多。 &#x1f440; Vue 人初见 useRef 在 Vue 中&#xff0c;ref 是我们访问 DOM 或响应式数据的…

零成本自建企业级SD-WAN!用Panabit手搓iWAN实战

我们前面提到过&#xff0c;最开始了解到Panabit&#xff0c;是因为他的SD-WAN产品&#xff08;误以为是外国货&#xff1f;这家国产SD-WAN神器竟能免费白嫖&#xff0c;附Panabit免费版体验全记录&#xff09;&#xff1b;现在发现&#xff0c;其SD-WAN的技术基础是iWAN&#…

Unity-微信截图功能简单复刻-03绘制空心矩形

思路-绘制空心矩形 拓展UGUI的Graphic类,实现拖拽接口。 开始拖拽时记录鼠标位置&#xff0c; 使用拖拽中的鼠标位置和记录的位置&#xff0c;计算矩形顶点&#xff0c;绘制矩形。 两个三角形合并为一个矩形&#xff0c;作为空心矩形的一条边&#xff0c;四个边合并为空心矩形…

国产品牌芯洲科技100V降压芯片系列

SCT2A25采用带集成环路补偿的恒导通时间(COT)模式控制&#xff0c;大大简化了转换器的片外配置。SCT2A25具有典型的140uA低静态电流&#xff0c;采用脉冲频率调制(PFM)模式&#xff0c;它使转换器在轻载或空载条件下实现高转换效率。 芯洲科技100V降压芯片系列提供丰富的48V系…

研一自救指南 - 07. CSS面向面试学习

最近的前端面试多多少少都会遇到css的提问&#xff0c;感觉还是要把重点内容记记背背。这里基于b站和我自己面试的情况整理。 20250418更新&#xff1a; 1. BFC Block Formatting Context&#xff0c;一个块级的盒子&#xff0c;可以创建多个。里面有很多个块&#xff0c;他们…

图灵奖得主LeCun:DeepSeek开源在产品层是一种竞争,但在基础方法层更像是一种合作;新一代AI将情感化

图片来源&#xff1a;This is World 来源 | Z Potential Z Highlights&#xff1a; 新型的AI系统是以深度学习为基础&#xff0c;能够理解物理世界并且拥有记忆、推理和规划能力的。一旦成功构建这样的系统&#xff0c;它们可能会有类似情感的反应&#xff0c;但这些情感是基…