[RAG]喂饭教程!Neo4J可视化GraphRAG索引

news2024/11/19 3:41:56

GraphRAG通过结合知识图谱,增加RAG的全局检索能力。今天我将讲解如何使用Neo4J可视化GraphRAG索引的结果,以便进一步的处理、分析,以小说提取的实体《仙逆》为例,一图胜千言。本文分为4小节,安装neo4j、导入GraphRAG索引文件、Neo4J可视化分析和总结,所有坑都已经帮你趟过啦,放心食用。

在这里插入图片描述

Neo4j 是由 Neo4j Inc. 开发的图数据库管理系统,是图数据库技术领域的领导者——强大的原生图存储、数据科学和分析,具备企业级的安全性。无约束地扩展您的事务和分析工作负载。已下载超过1.6亿次。Neo4j 存储的数据元素包括节点、连接它们的边以及节点和边的属性。

在这里插入图片描述

1. 安装Neo4j

Neo4j支持使用云端服务和本地社区开源版本,使用如下Docker命令启动Neo4J实例。

docker run \
    -p 7474:7474 -p 7687:7687 \
    --name neo4j-apoc \
    -e NEO4J_apoc_export_file_enabled=true \
    -e NEO4J_apoc_import_file_enabled=true \
    -e NEO4J_apoc_import_file_use__neo4j__config=true \
    -e NEO4J_PLUGINS=\[\"apoc\"\] \
    neo4j:5.21.2

浏览器打开http://localhost:7474,然后输入默认用户名neo4j,默认密码neo4j即可登录,登录之后要求重设密码。

接下来,安装neo4j的依赖包

pip install --quiet pandas neo4j-rust-ext

2. 导入GraphRAG的索引结果

为了更好的支持中文提取,本次采用deepseeker的deep-seek-chat模型(为啥不用qwen2?因为我的免费额度使用完了)。注册之后免费500万Token,索引一次通过,支持128K上下文,最大输出Tokens为4096。所以设置LLM的时候,务必把max_tokens设置为4096,未明确说明TPM和RPM,根据平台符合自动调整。

  • 导入依赖库
import pandas as pd
from neo4j import GraphDatabase
import time

  • 联结本地Neo4j实例
NEO4J_URI = "neo4j://localhost"  # or neo4j+s://xxxx.databases.neo4j.io
NEO4J_USERNAME = "neo4j"
NEO4J_PASSWORD = "password" #你自己的密码
NEO4J_DATABASE = "neo4j"

# Create a Neo4j driver
driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USERNAME, NEO4J_PASSWORD))

  • 配置本次索引目录
GRAPHRAG_FOLDER = "./output/20240716-192226/artifacts"

  • 创建Neo4j索引

在Neo4j中,索引仅用于查找图查询的起始点,例如快速查找两个节点以进行连接。约束用于避免重复,主要在实体类型的id上创建。我们使用带有两个下划线的类型作为标记,以区分它们与实际的实体类型。

statements = """
create constraint chunk_id if not exists for (c:__Chunk__) require c.id is unique;
create constraint document_id if not exists for (d:__Document__) require d.id is unique;
create constraint entity_id if not exists for (c:__Community__) require c.community is unique;
create constraint entity_id if not exists for (e:__Entity__) require e.id is unique;
create constraint entity_title if not exists for (e:__Entity__) require e.name is unique;
create constraint entity_title if not exists for (e:__Covariate__) require e.title is unique;
create constraint related_id if not exists for ()-[rel:RELATED]->() require rel.id is unique;
""".split(";")

for statement in statements:
    if len((statement or "").strip()) > 0:
        print(statement)
        driver.execute_query(statement)

  • 创建批量导入函数
def batched_import(statement, df, batch_size=1000):
    """
    Import a dataframe into Neo4j using a batched approach.
    Parameters: statement is the Cypher query to execute, df is the dataframe to import, and batch_size is the number of rows to import in each batch.
    """
    total = len(df)
    start_s = time.time()
    for start in range(0,total, batch_size):
        batch = df.iloc[start: min(start+batch_size,total)]
        result = driver.execute_query("UNWIND $rows AS value " + statement, 
                                      rows=batch.to_dict('records'),
                                      database_=NEO4J_DATABASE)
        print(result.summary.counters)
    print(f'{total} rows in { time.time() - start_s} s.')    
    return total

  • 导入文档
doc_df = pd.read_parquet(f'{GRAPHRAG_FOLDER}/create_final_documents.parquet', columns=["id", "title"])
doc_df.head(2)

# import documents
statement = """
MERGE (d:__Document__ {id:value.id})
SET d += value {.title}
"""

batched_import(statement, doc_df)

  • 导入text units
text_df = pd.read_parquet(f'{GRAPHRAG_FOLDER}/create_final_text_units.parquet',
                          columns=["id","text","n_tokens","document_ids"])
text_df.head(2)

statement = """
MERGE (c:__Chunk__ {id:value.id})
SET c += value {.text, .n_tokens}
WITH c, value
UNWIND value.document_ids AS document
MATCH (d:__Document__ {id:document})
MERGE (c)-[:PART_OF]->(d)
"""

batched_import(statement, text_df)


  • 加载实体
entity_df = pd.read_parquet(f'{GRAPHRAG_FOLDER}/create_final_entities.parquet',
                            columns=["name", "type", "description", "human_readable_id", "id", "description_embedding",
                                     "text_unit_ids"])
entity_df.head(2)

entity_statement = """
MERGE (e:__Entity__ {id:value.id})
SET e += value {.human_readable_id, .description, name:replace(value.name,'"','')}
WITH e, value
CALL db.create.setNodeVectorProperty(e, "description_embedding", value.description_embedding)
CALL apoc.create.addLabels(e, case when coalesce(value.type,"") = "" then [] else [apoc.text.upperCamelCase(replace(value.type,'"',''))] end) yield node
UNWIND value.text_unit_ids AS text_unit
MATCH (c:__Chunk__ {id:text_unit})
MERGE (c)-[:HAS_ENTITY]->(e)
"""

batched_import(entity_statement, entity_df)


  • 导入关系
rel_df = pd.read_parquet(f'{GRAPHRAG_FOLDER}/create_final_relationships.parquet',
                         columns=["source", "target", "id", "rank", "weight", "human_readable_id", "description",
                                  "text_unit_ids"])
rel_df.head(2)

rel_statement = """
    MATCH (source:__Entity__ {name:replace(value.source,'"','')})
    MATCH (target:__Entity__ {name:replace(value.target,'"','')})
    // not necessary to merge on id as there is only one relationship per pair
    MERGE (source)-[rel:RELATED {id: value.id}]->(target)
    SET rel += value {.rank, .weight, .human_readable_id, .description, .text_unit_ids}
    RETURN count(*) as createdRels
"""

batched_import(rel_statement, rel_df)


  • 导入社区
community_df = pd.read_parquet(f'{GRAPHRAG_FOLDER}/create_final_communities.parquet',
                               columns=["id", "level", "title", "text_unit_ids", "relationship_ids"])

community_df.head(2)

statement = """
MERGE (c:__Community__ {community:value.id})
SET c += value {.level, .title}
/*
UNWIND value.text_unit_ids as text_unit_id
MATCH (t:__Chunk__ {id:text_unit_id})
MERGE (c)-[:HAS_CHUNK]->(t)
WITH distinct c, value
*/
WITH *
UNWIND value.relationship_ids as rel_id
MATCH (start:__Entity__)-[:RELATED {id:rel_id}]->(end:__Entity__)
MERGE (start)-[:IN_COMMUNITY]->(c)
MERGE (end)-[:IN_COMMUNITY]->(c)
RETURn count(distinct c) as createdCommunities
"""

batched_import(statement, community_df)


  • 导入社区报告
community_report_df = pd.read_parquet(f'{GRAPHRAG_FOLDER}/create_final_community_reports.parquet',
                                      columns=["id", "community", "level", "title", "summary", "findings", "rank",
                                               "rank_explanation", "full_content"])
community_report_df.head(2)
# import communities
community_statement = """MATCH (c:__Community__ {community: value.community})
SET c += value {.level, .title, .rank, .rank_explanation, .full_content, .summary}
WITH c, value
UNWIND range(0, size(value.findings)-1) AS finding_idx
WITH c, value, finding_idx, value.findings[finding_idx] as finding
MERGE (c)-[:HAS_FINDING]->(f:Finding {id: finding_idx})
SET f += finding"""
batched_import(community_statement, community_report_df)


以上我们导入了文档、TextUnits、实体、关系、社区和社区报告后,打开浏览器后就可可视化分析这些实体关系和社区之间的信息了。Here we go~

3. 可视化分析

打开浏览器输入地址http://localhost:7474/browser/。

  • 实体

每个实体可点开,查看进一步的关联关系,王林和铁柱的关系也是一目了然。

  • 社区

社区有很多,基本上是对某一个特定事件进行整合,比如测试事件都关联了哪些人、那些测试。

  • 地点

点开洞穴可以进一步查看该洞穴关联的实体和人物、文本单元。

4. 总结

本文通过使用Neo4J可视化分析GraphRAG索引结果,让我们能够更为直观的了解整个GraphRAG索引结果,需要完整脚本的同学发送消息neo4j即可领取。

在这里插入图片描述

如何学习AI大模型?

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。

在这里插入图片描述

👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。

在这里插入图片描述

1.AI大模型学习路线图
2.100套AI大模型商业化落地方案
3.100集大模型视频教程
4.200本大模型PDF书籍
5.LLM面试题合集
6.AI产品经理资源合集

👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

在这里插入图片描述

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

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

相关文章

如何做服务端渲染?

node server 接收客户端请求,得到当前的请求url 路径,然后在已有的路由表内查找到对应的组件,拿到需要请求的数据,将数据作为 props、context或者store 形式传入组件 然后基于 react 内置的服务端渲染方法 renderToString()把组件…

vue一键打不同环境的包

1.配置package.json 主要看的是 "build:all": "vue-cli-service build && vue-cli-service build --mode test && vue-cli-service build --mode development", "scripts": {"dev": "vue-cli-service serve"…

【SpringBoot源码】SpringBoot监听机制分析

目录 一、简介 二、SpringBoot事件监听机制 1)加载ApplicationListener监听器实现类 2)获取运行监听器EventPublishingRunListener 3)发布事件 4)Spring事件发布multicastEvent() 一、简介 接下来我们分析下SpringBoot的事件监听机制的源码。 二、SpringBoot事件监…

Android系统安全 — 1-OpenSSL支持的常用加解密算法介绍

常用加解密算法介绍 1. 哈希算法 常见的函数包含MD系列、SHA-1、SHA-2家族、SHA-3家族、SM3等。 1.1 MD5(单向散列算法) 全称是Message-Digest Algorithm 5(信息-摘要算法),经MD2、MD3和MD4发展而来。MD5算法的使用…

线索精细化管理实践:线上推广渠道线索管理的8个要点

在如今线索获取成本越来越高的情况下,如何获取增量线索、经营好存量线索、实现精细化、高效率线索管理对于企业来说至关重要。获取线索是一切行动的开始,与其建立起稳定、持续的信任关系,达成合作甚至引导复购,是整个线索管理链路…

泛微eteams OA对接金蝶云星空写入数据

需求: 公司需要先在OA上对准备生产的订单进行一次量产评审,所有相关人员评审通过后才可以进行生产,导致下工单的人员每次需要把OA上的信息复制到ERP进行审批。 为什么不直接在ERP上审批呢? 首先该节点涉及到很多不用ERP的用户&am…

盘点八月份最好用的五款报表制作工具,涵盖各功能,你都听说过吗?

一、报表制作软件的重要性 在现代企业运营中,数据的处理和分析是至关重要的。如何将复杂的数据信息以直观、易懂的方式展现出来,是提升决策效率和准确性的关键。因此报表制作软件成为企业必备的工具之一,它们通过图表化的方式,帮…

加速网络体验,Squid缓存代理:让浏览如飞,畅享无限网络速度!

作者简介:我是团团儿,是一名专注于云计算领域的专业创作者,感谢大家的关注 座右铭: 云端筑梦,数据为翼,探索无限可能,引领云计算新纪元 个人主页:团儿.-CSDN博客 目录 前言: squ…

低代码表单引擎的核心不仅仅是拖拉拽,深入解析表单的高级功能

作为一名专业的低代码产品经理,我们主要以 to B 的企业级系统为配置化对象,我深知在构建高效、用户友好的企业应用系统时,表单引擎扮演着核心基础的角色。当然拖拉拽快速创建页面是最简单直接的用户体验,然而,在享受拖…

Maven: 更新依赖索引清理maven仓库

文章目录 更新依赖索引清理maven仓库 更新依赖索引 有时候给 idea 配置完 maven 仓库信息后,在 idea 中依然搜索不到仓库中的 jar 包。这是因为仓库中的 jar 包索引尚未更新到 idea 中。这个时候我们就需要更新 idea 中 maven 的索引了,具体做法如下&am…

企业如何防止重要数据泄露?10个重要的小技巧!

在当今数字化时代,企业数据已成为其最宝贵的资产之一,但同时也面临着前所未有的泄露风险。数据泄露不仅可能导致财务损失,还可能损害企业声誉和客户信任。因此,采取有效措施防止重要数据泄露至关重要。以下是十个重要的小技巧&…

武威市旅游资源管理系统/旅游网站的设计与实现

摘要 经济快速发展带动下的旅游产业发展,在我国越来越被更多的人所追求。人们对获取旅游信息有很高的需求,在互联网发达的今天,制作一个旅游资源管理十分有必要。该设计根据基于jsp技术和MySQL数据库设计一个武威市旅游资源管理系统。系统的前…

自动化持续测试策略

目录 重新确定手动测试和自动化测试的关系 充分考虑自动化的可测性 尽量将自动化测试的粒度做细 策略实施的关键点 1.跨职能团队合作 2.持续学习 3.自动化测试的可测性 4.测试优化 在持续测试中,我们希望将每个测试分层上的测试都用自动化的方式来进行&…

C语言-内存管理

内存区间 在C语言中,内存被划分为以下几个区间: 栈(stack):用于存储局部变量和函数的参数。栈是由编译器自动分配和释放的,栈的大小通常是固定的。 堆(heap):用于存储动…

【Qt】输入类控件QComboBox

目录 输入类控件QComboBox 例子:使用下拉框模拟点餐 例子:从文件中加载下拉框的选项 输入类控件QComboBox QComboBox表示下拉框 核心属性 属性说明 currentText 当前选中的⽂本 currentIndex 当前选中的条⽬下标. 从 0 开始计算. 如果当前没有条…

秋招力扣Hot100刷题总结——栈和队列

1. 有效的括号 题目链接 题目要求:给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。…

Linux安装并配置Hadoop

目录 一、安装并配置JDK二、安装并配置Hadoop三、安装过程中遇到的问题总结 一、安装并配置JDK Linux上一般会安装Open JDK,关于OpenJDK和JDK的区别:http://www.cnblogs.com/sxdcgaq8080/p/7487369.html 准备Open JDK 1.8 查询可安装的java版本 yum -y list jav…

Swin-Transformer论文阅读

在此前,transformer已经通过ViT等作品展现出了它在cv领域的无限可能性,但是,vit主要针对的是图像分类问题的讨论,而分类只是cv众多问题中最基础的问题之一。那么,怎么用transformer进行物体检测,语义分割这…

vscode中使用官方推荐的编程字体Cascadia Code字体

字体样式 > 和 有特殊效果 很多字体都支持使用连字,Cascadia Code 、Jetbrains Mono 、Fira Code 等 安装Cascadia Code 下载完成后解压安装 选中右键安装,static文件里也一样安装 VS Code 中配置设置字体和连字设置 Cascadia Code, Consolas, Couri…

基于协同过滤算法的私人诊所管理系统_6t4o8

TOC springboot571基于协同过滤算法的私人诊所管理系统_6t4o8--论文 绪 论 1.1研究背景 自改革开放以来,国内的基础网络设施的不断进步和终端电子设备的高度普及,互联网用户规模越来越大[1]。现在人们越来越离不开计算机网络、互联网所带来的好处了&…