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

摘要:本文介绍了一种将非结构化数据转换为知识图谱的端到端方法。通过使用大型语言模型(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_indexchunk_number += 1    # 安全中断(可选)if chunk_number > total_words: # 简单安全检查print("警告:分块循环超出总单词数,中断。")breakprint(f"\n文本成功拆分为 {len(chunks)} 个分块。")#### 输出结果 ####
开始分块过程...文本成功拆分为 3 个分块。

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

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

相关文章

Leetcode 3523. Make Array Non-decreasing

Leetcode 3523. Make Array Non-decreasing 1. 解题思路2. 代码实现 题目链接&#xff1a;3523. Make Array Non-decreasing 1. 解题思路 这一题思路上来说就是一个栈的问题&#xff0c;就是从后往前依次考察每一个元素&#xff0c;显然&#xff0c;当前位置要么被舍弃&…

探秘STM32如何成为现代科技的隐形引擎

STM32单片机原理与应用 前言&#xff1a;微型计算机的硅脑 在我们身边的每一个智能设备中&#xff0c;都隐藏着一个小小的"硅脑"——单片机。它们体积微小&#xff0c;却能执行复杂的运算和控制功能&#xff0c;就像是现代科技世界的"神经元"。STM32系列…

机制的作用

“机制”是一个广泛使用的概念&#xff0c;其含义和应用范围因领域而异。在不同的学科和实际应用中&#xff0c;机制有着不同的定义和功能。以下从几个主要领域对“机制”进行详细解释&#xff1a; 一、自然科学中的机制 &#xff08;一&#xff09;物理学 定义 在物理学中&…

prim最小生成树+最大生成树【C++】板子题

什么是最小生成树&#xff1f; 在一给定的无向图G (V, E) 中&#xff0c;(u, v) 代表连接顶点 u 与顶点 v 的边&#xff0c;而 w(u, v) 代表此的边权重&#xff0c;若存在 T 为 E 的子集&#xff08;即&#xff09;且为无循环图&#xff0c;使得的 w(T) 最小&#xff0c;则此 …

读书笔记--MySQL索引

索引(在 MySQL 中也叫做“键(key)”)是存储引擎用于快速找到记录的一种数据结构。 索引对于良好的性能非常关键。尤其是当表中的数据量越来越大时&#xff0c;索引对性能的影响愈发重要。在数据量较小且负载较低时&#xff0c;不恰当的索引对性能的影响可能还不明显&#xff0c…

VS Code 远程连接服务器:Anaconda 环境与 Python/Jupyter 运行全指南。研0大模型学习(第六、第七天)

VS Code 远程连接服务器&#xff1a;Anaconda 环境与 Python/Jupyter 运行全指南 在使用 VS Code 通过 SSH 远程连接到服务器进行开发时&#xff0c;尤其是在进行深度学习等需要特定环境的工作时&#xff0c;正确配置和使用 Anaconda 环境以及理解不同的代码运行方式非常关键。…

字节头条golang二面

docker和云服务的区别 首先明确Docker的核心功能是容器化&#xff0c;它通过容器技术将应用程序及其依赖项打包在一起&#xff0c;确保应用在不同环境中能够一致地运行。而云服务则是由第三方提供商通过互联网提供的计算资源&#xff0c;例如计算能力、存储、数据库等。云服务…

数据结构和算法(七)--树

一、树 树是我们计算机中非常重要的一种数据结构&#xff0c;同时使用树这种数据结构&#xff0c;可以描述现实生活中的很多事物&#xff0c;例如家谱、单位的组织架构、等等。 树是由n(n>1)个有限结点组成一个具有层次关系的集合。把它叫做"树"是因为它看起来像一…

状态管理最佳实践:Provider使用技巧与源码分析

状态管理最佳实践&#xff1a;Provider使用技巧与源码分析 前言 Provider是Flutter官方推荐的状态管理解决方案&#xff0c;它简单易用且功能强大。本文将从实战角度深入讲解Provider的使用技巧和源码实现原理&#xff0c;帮助你更好地在项目中应用Provider进行状态管理。 基…

使用 NEAT 进化智能体解决 Gymnasium 强化学习环境

使用 NEAT 进化智能体解决 Gymnasium 强化学习环境 0. 前言1. 环境定义2. 配置 NEAT3. 解决强化学习问题小结系列链接0. 前言 在本节中,我们使用 NEAT 解决经典强化学习 (reinforcement learning, RL) Gym 问题。但需要注意的是,我们用于推导网络和解决方程的方法不是 RL,而…

Pandas高级功能

在数据科学与机器学习的广阔天地中&#xff0c;Pandas宛如一把瑞士军刀&#xff0c;以其强大的数据处理和分析能力&#xff0c;成为众多数据从业者的得力助手。从基础的数据读写、清洗到复杂的数据聚合、转换&#xff0c;Pandas的功能丰富多样。本文将深入探索Pandas的一些高级…

英语学习4.15

amateur amateur &#x1f524; 读音&#xff1a;/ˈmətər/ 或 /ˈmətʃʊr/ ✅ 词性&#xff1a;名词 / 形容词 ✅ 中文释义&#xff1a; &#xff08;名词&#xff09;业余爱好者   &#x1f449; 指不是以此为职业的人&#xff0c;通常出于兴趣而从事某项活动。   …

Java开发软件

Main.java // 主类&#xff0c;用于测试学生管理系统 public class Main { public static void main(String[] args) { StudentManagementSystem sms new StudentManagementSystem(); // 添加学生 sms.addStudent(new Student(1, "Alice", 20)…

多Agent框架及协作机制详解

文章目录 一、多智能体系统介绍1.1 多智能体系统定义1.2 多智能体协作1.3 协作类型1.4 协作策略1.5 通信结构1.6 协调与编排 1.3 多智能体与单智能体对比1.4 应用场景 二、多Agent开发框架AutoGenMetaGPTLangGraphSwarmCrewAI 三、多智能体协作方式3.1 MetaGPT&#xff1a;SOP驱…

AI Agent破局:智能化与生态系统标准化的颠覆性融合!

Hi&#xff01;好久不见 云边有个稻草人-个人主页 热门文章_云边有个稻草人的博客-本篇文章所属专栏~ 目录 一、引言 二、AI Agent的基本概念 2.1 定义与分类 2.2 AI Agent的工作原理 2.3 示例代码&#xff1a;AI Agent的基本实现 三、AI Agent在企业数字化转型中的应用 …

在阿里云和树莓派上编写一个守护进程程序

目录 一、阿里云邮件守护进程 1. 安装必要库 2. 创建邮件发送脚本 mail_daemon.py 3. 设置后台运行 二、树莓派串口守护进程 1. 启用树莓派串口 2. 安装依赖库 3. 创建串口输出脚本 serial_daemon.py 4. 设置开机自启 5. 使用串口助手接收 一、阿里云邮件守护进程 1.…

Python----深度学习(全连接与链式求导法则)

一、机器学习和深度学习的区别 机器学习&#xff1a;利用计算机、概率论、统计学等知识&#xff0c;输入数据&#xff0c;让计算机学会新知 识。机器学习的过程&#xff0c;就是训练数据去优化目标函数。 深度学习&#xff1a;是一种特殊的机器学习&#xff0c;具有强大的能力和…

Python爬虫实战:获取网易新闻数据

一、引言 随着互联网的飞速发展,网络上蕴含着海量的信息资源。新闻数据作为其中的重要组成部分,对于舆情分析、市场研究、信息传播等多个领域具有重要价值。网易新闻作为国内知名的新闻平台,拥有丰富多样的新闻内容。使用 Python 的 Scrapy 框架进行网易新闻数据的爬取,可…

matlab论文图一的地形区域图的球形展示Version_1

matlab论文图一的地形区域图的球形展示Version_1 图片 此图来源于&#xff1a; ![Jieqiong Zhou, Ziyin Wu, Dineng Zhao, Weibing Guan, Chao Zhu, Burg Flemming, Giant sand waves on the Taiwan Banks, southern Taiwan Strait: Distribution, morphometric relationship…

蓝桥杯:连连看

本题大意要我们在一个给定的nxm的矩形数组中找出符合条件的格子 条件如下&#xff1a; 1.数值相同 2.两个横坐标和纵坐标的差值相等&#xff08;由此可得是一个对角线上的格子&#xff09; 那么根据以上条件我们可以用HashMap来解决这个问题&#xff0c;统计对角线上数值相同…