当前位置: 首页 > article >正文

玩转大语言模型——配置图数据库Neo4j(含apoc插件)并导入GraphRAG生成的知识图谱

系列文章目录

玩转大语言模型——使用langchain和Ollama本地部署大语言模型
玩转大语言模型——ollama导入huggingface下载的模型
玩转大语言模型——langchain调用ollama视觉多模态语言模型
玩转大语言模型——使用GraphRAG+Ollama构建知识图谱
玩转大语言模型——完美解决GraphRAG构建的知识图谱全为英文的问题
玩转大语言模型——配置图数据库Neo4j(含apoc插件)并导入GraphRAG生成的知识图谱
玩转大语言模型——本地部署带聊天界面deepseek R1的小白教程


文章目录

  • 系列文章目录
  • 前言
  • 安装JDK
  • 安装Neo4j
    • 下载Neo4j
    • 配置环境变量
    • 安装apoc插件
  • 导入知识图谱
    • 启动Neo4j
    • 使用Python导入知识图谱
    • 显示知识图谱


前言

在之前的文章中笔者解决了使用本地模型部署GraphRAG并生成知识图谱的过程,并且解决了原本提示词只生成英文知识图谱的问题,在本篇中,笔者将配置Neo4j图数据库并导入GraphRAG生成的知识图谱数据。以往的内容参照:玩转大语言模型——使用GraphRAG+Ollama构建知识图谱、玩转大语言模型——完美解决GraphRAG构建的知识图谱全为英文的问题。


安装JDK

Neo4j使用Java开发的,所以首先需要安装JDK。如果没有安装过JDK,需要先到官网下载安装。
官网:https://www.oracle.com/java/technologies/downloads/?er=221886#java11-windows
选择合适的版本下载
在这里插入图片描述
跟随指引安装即可。


安装Neo4j

下载Neo4j

Neo4j官网:https://neo4j.com/deployment-center/
在这里插入图片描述
下载好后是个压缩包,将其解压到你的目标安装目录即可,注意记一下解压后的地址,需要配置环境变量,笔者的地址是D:\neo4j-community-5.26.1,配置时可以做参考

配置环境变量

打开编辑环境变量,新建系统环境变量:名为NEO4J_HOME,值为D:\neo4j-community-5.26.1
在这里插入图片描述
在这里插入图片描述

修改Path变量:在其值中增加
在这里插入图片描述
双击后点新建

%NEO4J_HOME%\bin

在这里插入图片描述

安装apoc插件

导入知识图谱时,会用到apoc插件的部分功能,所以首先要安装apoc。
apoc版本地址:https://github.com/neo4j/apoc/releases?page=1

在这里插入图片描述

点击下载后放到路径:neo4j路径/plugins
在这里插入图片描述
找到路径:neo4j路径/conf下的neo4j.conf,在文件内容的末尾添加以下配置并保存。

dbms.security.procedures.unrestricted=apoc.*
dbms.security.procedures.allowlist=apoc.*
server.jvm.additional=-Dapoc.export.file.enabled=true
server.jvm.additional=-Dapoc.import.file.enabled=true
dbms.security.allow_csv_import_from_file_urls=true

neo4j路径/conf下新建一个apoc.conf文件
在文件中写入以下配置并保存。

apoc.export.file.enabled=true
apoc.import.file.use_neo4j_config=false
apoc.import.file.enabled=true
apoc.import.file.directory=D:/Neo4j/neo4j-community-5.13.0-windows/neo4j-community-5.13.0/import
apoc.export.file.directory=D:/Neo4j/neo4j-community-5.13.0-windows/neo4j-community-5.13.0/export

导入知识图谱

启动Neo4j

在命令行输入

neo4j console

之后在浏览器搜索:http://localhost:7474 进行用户创建。
初始用户名及密码都是neo4j,之后会让重置密码。
如果想持续在后台运行数据库,可以使用以下命令

neo4j start

如果neo4j start 时报错,可以执行以下命令安装service。

neo4j windows-service install 

安装成功后重新使用命令neo4j start 即可,但使用neo4j start 命令开启的服务在停止时需要调用neo4j stop停止运行

使用Python导入知识图谱

使用pip安装相关包

pip install --quiet pandas neo4j-rust-ext

不确定是由于使用的模型的问题还是GraphRAG本身的问题,实际导入的方式与官方提供的方式略有差距,主要体现在某些字段的命名上。如果笔者已经足够熟悉Neo4j可以自行修改,但如果只是想看一下知识图谱生成的效果可以参照笔者的方式修改。尽管在笔者看来,他的构建方式导入的图数据库展示效果并不会,实际上人工处理一下,自己构建会更加准确。
导入包

import time
import pandas as pd
from neo4j import GraphDatabase

设置数据库参数

GRAPHRAG_FOLDER = "ragtest/output"
NEO4J_URI = "neo4j://localhost"  # or neo4j+s://xxxx.databases.neo4j.io
NEO4J_USERNAME = "neo4j"
NEO4J_PASSWORD = "your password"
NEO4J_DATABASE = "neo4j"

实例化Neo4j driver

driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USERNAME, NEO4J_PASSWORD))

构建批量导入函数

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

创建constraints, idempotent操作

statements = ["\ncreate constraint chunk_id if not exists for (c:__Chunk__) require c.id is unique","\ncreate constraint document_id if not exists for (d:__Document__) require d.id is unique","\ncreate constraint entity_id if not exists for (c:__Community__) require c.community is unique","\ncreate constraint entity_id if not exists for (e:__Entity__) require e.id is unique","\ncreate constraint entity_title if not exists for (e:__Entity__) require e.name is unique","\ncreate constraint entity_title if not exists for (e:__Covariate__) require e.title is unique","\ncreate constraint related_id if not exists for ()-[rel:RELATED]->() require rel.id is unique","\n",
]for statement in statements:if len((statement or "").strip()) > 0:print(statement)driver.execute_query(statement)

导入create_final_documents.parquet

doc_df = pd.read_parquet(f"{GRAPHRAG_FOLDER}/create_final_documents.parquet", columns=["id", "title"]
)# Import documents
statement = """
MERGE (d:__Document__ {id:value.id})
SET d += value {.title}
"""batched_import(statement, doc_df)

导入create_final_text_units.parquet

text_df = pd.read_parquet(f"{GRAPHRAG_FOLDER}/create_final_text_units.parquet",columns=["id", "text", "n_tokens", "document_ids"],
)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)

导入create_final_entities.parquet

entity_df = pd.read_parquet(f"{GRAPHRAG_FOLDER}/create_final_entities.parquet",columns=["title","type","description","human_readable_id","id",# "description_embedding","text_unit_ids",],
)
entity_df.rename(columns={"title": "name"}, inplace=True)entity_statement = """
MERGE (e:__Entity__ {id:value.id})
SET e += value {.human_readable_id, .description, name:replace(value.name,'"','')}
WITH e, value
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)

导入create_final_relationships.parquet

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_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 pairMERGE (source)-[rel:RELATED {id: value.id}]->(target)SET rel += value {.weight, .human_readable_id, .description, .text_unit_ids}RETURN count(*) as createdRels
"""batched_import(rel_statement, rel_df)

导入create_final_communities.parquet

community_df = pd.read_parquet(f"{GRAPHRAG_FOLDER}/create_final_communities.parquet",columns=["id", "level", "title", "text_unit_ids", "relationship_ids"],
)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)

导入create_final_community_reports.parque

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",],
)# Import communities
community_statement = """
MERGE (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)

导入create_final_nodes.parquet

nodes_df = pd.read_parquet(f"{GRAPHRAG_FOLDER}/create_final_nodes.parquet")nodes_statement = """
MERGE (c:__Covariate__ {id:value.id})
SET c += apoc.map.clean(value, ["text_unit_id", "document_ids", "n_tokens"], [NULL, ""])
WITH c, value
MATCH (ch:__Chunk__ {id: value.text_unit_id})
MERGE (ch)-[:HAS_COVARIATE]->(c)
"""
batched_import(nodes_statement, nodes_df)

显示知识图谱

启动Neo4j后访问http://localhost:7474
在这里插入图片描述
可以看到效果还可以,不过可能由于使用的是本地模型,逻辑能力较差,所以有些实体之间的关系并没有理清,需要通过人工去做一下知识图谱的数据。不过从做数据的角度来看,如果没有知识图谱的需求,通过事件和实体查找的话应该可以找全相关的信息,只能说当前的这种方式差强人意。
在这里插入图片描述

相关文章:

玩转大语言模型——配置图数据库Neo4j(含apoc插件)并导入GraphRAG生成的知识图谱

系列文章目录 玩转大语言模型——使用langchain和Ollama本地部署大语言模型 玩转大语言模型——ollama导入huggingface下载的模型 玩转大语言模型——langchain调用ollama视觉多模态语言模型 玩转大语言模型——使用GraphRAGOllama构建知识图谱 玩转大语言模型——完美解决Gra…...

如何进行API版本控制?

一、URI路径版本控制(Path Versioning) 通过在API的URL路径中包含版本号来实现。例如: /api/v1/products /api/v2/products 这种方法最为直观,用户可以根据URL判断版本。它的优点是简单易懂,容易实现。但如果接口变动频繁,可能会导致大量的路径不同版本的接口需要维护…...

计算机毕业设计Python+CNN卷积神经网络考研院校推荐系统 考研分数线预测 考研推荐系统 考研爬虫 考研大数据 Hadoop 大数据毕设 机器学习

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...

### 2024 江西省赛题解(A,C,D,G,H,J,K,L) BEFI待补

A. 输出 a b c abc abc 即可。 void slove () {int a, b, c;cin >> a >> b >> c;cout << (a b c) << endl; }B. C. 如果 ∑ i 1 n a i S \sum_{i1}^{n}a_iS ∑i1n​ai​S 那么存在所有人说的都是真话的可能。 否则&#xff0c;我们…...

Ruby 类和对象

Ruby 类和对象 引言 在软件开发中,类和对象是面向对象编程(OOP)的核心概念。Ruby 作为一种动态、解释型编程语言,也以简洁的方式支持面向对象编程。本文将深入探讨 Ruby 中的类和对象,包括它们的定义、创建、使用以及一些高级特性。 类与对象的定义 类 在 Ruby 中,类…...

【自学笔记】JavaWeb的重点知识点-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 JavaWeb知识点一、基础概念二、项目结构三、Tomcat服务器四、数据库连接&#xff08;JDBC&#xff09;五、前端技术六、高级技术 总结 以下是JavaWeb知识点的MD格式…...

OpenCV:闭运算

目录 1. 简述 2. 用膨胀和腐蚀实现闭运算 2.1 代码示例 2.2 运行结果 3. 闭运算接口 3.1 参数详解 3.2 代码示例 3.3 运行结果 4. 闭运算的应用场景 5. 注意事项 相关阅读 OpenCV&#xff1a;图像的腐蚀与膨胀-CSDN博客 OpenCV&#xff1a;开运算-CSDN博客 1. 简述…...

智云-一个抓取web流量的轻量级蜜罐-k8s快速搭建教程

智云-一个抓取web流量的轻量级蜜罐-k8s快速搭建教程 github地址 https://github.com/xiaoxiaoranxxx/POT-ZHIYUN k8s搭建教程 首先下载代码文件 git clone https://github.com/xiaoxiaoranxxx/POT-ZHIYUN.git cd POT-ZHIYUN编译镜像 代码相关文件在github https://github.com/x…...

万物皆有联系:驼鸟和布什

布什&#xff1f;一块布十块钱吗&#xff1f;不是&#xff0c;大家都知道&#xff0c;美国有两个总统&#xff0c;叫老布什和小布什&#xff0c;因为两个布什总统&#xff08;父子俩&#xff09;&#xff0c;大家就这么叫来着&#xff0c;目的是为了好区分。 布什总统的布什&a…...

nodejs:js-mdict 的下载、安装、测试、build

js-mdict 项目的目录结构&#xff1a;js-mdict 项目教程 js-mdict 下载地址: js-mdict-master.zip 先解压到 D:\Source\ js-mdict 6.0.2 用了 ts (TypeScript) 和 Jest&#xff0c;增加了应用开发的难度&#xff0c;因为先要了解 ts 和 Jest。 参阅&#xff1a;测试与开发&a…...

< OS 有关 > 阿里云:轻量应用服务器 的使用 :轻量化 阿里云 vpm 主机

原因&#xff1a; &#xff1c; OS 有关 &#xff1e; 阿里云&#xff1a;轻量应用服务器 的使用 &#xff1a;从新开始 配置 SSH 主机名 DNS Tailscale 更新OS安装包 最主要是 清除阿里云客户端这个性能杀手-CSDN博客 防止 I/O 祸害系统 操作&#xff1a; 查看进程&#x…...

sqlzoo答案4:SELECT within SELECT Tutorial

sql练习&#xff1a;SELECT within SELECT Tutorial - SQLZoo world表&#xff1a; namecontinentareapopulationgdpAfghanistanAsia6522302550010020343000000AlbaniaEurope28748283174112960000000AlgeriaAfrica238174137100000188681000000AndorraEurope46878115371200000…...

Ubuntu全面卸载mysql

如果你已经看到whereis mysql输出了与MySQL相关的路径&#xff0c;说明MySQL仍然存在于系统中。要卸载MySQL&#xff0c;可以按照以下步骤操作&#xff0c;确保完全删除所有相关的文件和配置&#xff1a; 1. 停止MySQL服务 首先&#xff0c;停止MySQL服务&#xff1a; sudo …...

SOME/IP--协议英文原文讲解3

前言 SOME/IP协议越来越多的用于汽车电子行业中&#xff0c;关于协议详细完全的中文资料却没有&#xff0c;所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块&#xff1a; 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 Note: Thi…...

350.两个数组的交集 ②

目录 题目过程解法 题目 给你两个整数数组 nums1 和 nums2 &#xff0c;请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数&#xff0c;应与元素在两个数组中都出现的次数一致&#xff08;如果出现次数不一致&#xff0c;则考虑取较小值&#xff09;。可以不考虑…...

药店药品销售管理系统的设计与实现

标题:药店药品销售管理系统的设计与实现 内容:1.摘要 摘要&#xff1a;本文介绍了药店药品销售管理系统的设计与实现。该系统旨在提高药店的运营效率和管理水平&#xff0c;通过信息化手段实现药品销售、库存管理、财务管理等功能。本文详细阐述了系统的需求分析、设计思路、技…...

汽车蓝牙钥匙定位仿真小程序

此需求来自于粉丝的真实需求,假期没事,牛刀小试。 一、项目背景 如今,智能车钥匙和移动端定位技术已经相当普及。为了探索蓝牙 Beacon 在短距离定位场景下的可行性,我们搭建了一个简易原型:利用 UniApp 在移动端采集蓝牙信标的 RSSI(信号强度),通过三边定位算法估算钥…...

unity学习24:场景scene相关生成,加载,卸载,加载进度,异步加载场景等

目录 1 场景数量 SceneManager.sceneCount 2 直接代码生成新场景 SceneManager.CreateScene 3 场景的加载 3.1 用代码加载场景&#xff0c;仍然build setting里先加入配置 3.2 卸载场景 SceneManager.UnloadSceneAsync(); 3.3 同步加载场景 SceneManager.LoadScene 3.3.…...

四.4 Redis 五大数据类型/结构的详细说明/详细使用( zset 有序集合数据类型详解和使用)

四.4 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; zset 有序集合数据类型详解和使用&#xff09; 文章目录 四.4 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; zset 有序集合数据类型详解和使用&#xff09;1. 有序集合 Zset(sorted set)2. zset 有序…...

S4 HANA税码科目确定(OB40)

本文主要介绍在S4 HANA OP中税码科目确定(OB40)相关设置。具体请参照如下内容&#xff1a; 税码科目确定(OB40) 在以上界面维护“Transaction Key”的记账码。 在以上界面进一步维护“Transaction Key”确定科目的规则。 Chart of Account:用于明确该规则适用于什么科目表。 …...

DeepSeek的崛起与OpenAI的守擂:AI大模型时代的竞争新格局

DeepSeek的崛起与OpenAI的守擂&#xff1a;AI大模型时代的竞争新格局 近年来&#xff0c;全球生成式AI领域风起云涌&#xff0c;中国初创公司DeepSeek&#xff08;深度求索&#xff09;凭借一系列创新动作异军突起&#xff0c;引发行业热议。从发布对标GPT-4的MoE模型到开源轻量…...

CSDN的历史

CSDN(中国开发者网络,China Software Developer Network)是中国最具影响力的IT技术社区之一,其历史可追溯至1999年。以下是其发展历程和关键节点: --- **一、创立背景(1999年)** - **创始人**:蒋涛(国内知名技术人,曾参与金山软件早期开发)。 - **初衷**:为国内程…...

vim的特殊模式-可视化模式

可视化模式&#xff1a;按 v进入可视化模式 选中 y复制 d剪切/删除 可视化块模式: ctrlv 选中 y复制 d剪切/删除 示例&#xff1a; &#xff08;vim可视化模式的进阶使用&#xff1a;vim可视化模式的进阶操作-CSDN博客&#xff09;...

鸿蒙HarmonyOS实战-ArkUI动画(页面转场动画)_鸿蒙arkui tab 切换动画

PageTransitionExit({type?: RouteType,duration?: number,curve?: Curve | string,delay?: number}) 在HarmonyOS中&#xff0c;PageTransitionEnter和PageTransitionExit是用于控制页面切换动画的参数。它们分别表示页面进入和退出时的动画。1. type&#xff08;动画类型…...

UE5制作视差图

双目深度估计开源数据集很多都是用UE制作的&#xff0c;那么我们自己能否通过UE制作自己想要的场景的数据集呢。最近花了点时间研究了一下&#xff0c;分享给需要的小伙伴。 主要使用的是UnrealCV插件&#xff0c;UnrealCV是一个开源项目&#xff0c;旨在帮助计算机视觉研究人…...

根据每月流量和市场份额排名前20 的AI工具列表

ChatGPT&#xff1a;由Open AI研发&#xff0c;是一款对话式大型语言模型。它能够理解自然语言输入&#xff0c;生成连贯且符合逻辑的回复。可用于文本创作&#xff0c;如撰写文章、故事、诗歌&#xff1b;还能解答各种领域的知识问题&#xff0c;提供翻译、代码解释等服务&…...

前端学习-事件委托(三十)

目录 前言 课前思考 for循环注册事件 语法 事件委托 1.事件委托的好处是什么? 2.事件委托是委托给了谁&#xff0c;父元素还是子元素 3.如何找到真正触发的元素 示例代码 总结 前言 才子佳人&#xff0c;自是白衣卿相 课前思考 1.如果同时给多个元素注册事件&…...

记忆化搜索(5题)

是什么&#xff1f; 是一个带备忘录的递归 如何实现记忆化搜索 1.添加一个备忘录&#xff08;建立一个可变参数和返回值的映射关系&#xff09; 2.递归每次返回的时候把结果放到备忘录里 3.在每次进入递归的时候往备忘录里面看看。 目录 1.斐波那契数列 2.不同路径 3.最…...

【游戏设计原理】96 - 成就感

成就感是玩家体验的核心&#xff0c;它来自完成一件让自己满意的任务&#xff0c;而这种任务通常需要一定的努力和挑战。游戏设计师的目标是通过合理设计任务&#xff0c;不断为玩家提供成就感&#xff0c;保持他们的参与热情。 ARCS行为模式&#xff08;注意力、关联性、自信…...

Java小白入门教程:内置数据类型(四类八种)和引用数据类型

目录 一、内置数据类型&#xff08;四类八种&#xff09; 1. 整数类型&#xff08;四种子类型&#xff09; 2. 浮点类型&#xff08;两种子类型&#xff09; 3. 字符类型&#xff08;一种子类型&#xff09; 4. 布尔类型&#xff08;一种子类型&#xff09; 二、引用数据类…...