我们首先要知道什么是人物关系三元组以及它的作用:
人物关系三元组是构建知识图谱的核心数据结构,格式为:**人物A,人物B,关系,阵营A,阵营B**。例如:"郭靖,黄蓉,夫妻,丐帮,丐帮"。
其作用体现在:
1. **结构化数据**:将非结构化的文本(如小说/剧本)转化为机器可处理的标准化关系链,明确角色间的关联属性
2. **可视化基础**:为D3.js等工具提供节点(node)与连接线(link)的绘制依据,人物作为节点,关系作为连接线属性
3. **阵营划分**:通过第四、第五字段实现角色分组,在力导向图中自动聚类显示(如武林门派、家族势力)
4. **关系去重**:确保单向关系表达(如已定义"张无忌->赵敏:倾慕"则不再重复定义逆向关系)
5. **数据校验**:通过校验层过滤无效节点(如未定义的人物ID),保证图谱数据的完整性和渲染稳定性
这种三元组结构如同建筑图纸,决定了知识图谱的拓扑结构、交互逻辑和视觉呈现效果。
我们在代码中如何呢:首先是要构建一个人物关系三元组数据集,我们以红楼梦为例
可以看到,其格式为人物A,人物B,关系,阵营A,阵营B,符合要求
接下来,启动和连接Neo4j社区版,这段代码主要用于连接Neo4j图数据库并设置一些常量配置,下面我将详细解释各个部分的作用:
from py2neo import Graph
graph = Graph("bolt://localhost:7687", auth=("neo4j", "12345678"))
CA_LIST = {"贾家荣国府":0,"贾家宁国府":1,"王家":2,"史家":3,"薛家":4,"其他":5,"林家":6}
similar_words = {
"爸爸": "父亲",
"妈妈": "母亲",
"爸": "父亲",
"妈": "母亲",
"父亲": "父亲",
"母亲": "母亲",
"儿子":"儿子",
"女儿":"女儿",
"丫环":"丫环",
"兄弟":"兄弟",
"妻":"妻",
"老婆":"妻",
"哥哥":"哥哥",
"表妹":"表兄妹",
"弟弟":"弟弟",
"妾":"妾",
"养父":"养父",
"姐姐":"姐姐",
"娘":"母亲",
"爹":"父亲",
"father":"父亲",
"mother":"母亲",
"朋友":"朋友",
"爷爷":"爷爷",
"奶奶":"奶奶",
"孙子":"孙子",
"老公":"丈夫",
'岳母': '岳母',
"表兄妹":"表兄妹",
"孙女": "孙女",
"嫂子":"嫂子",
"暧昧":"暧昧"
}
from py2neo import Graph
graph = Graph("bolt://localhost:7687", auth=("neo4j", "12345678"))
from py2neo import Graph
: 从py2neo库中导入Graph类。py2neo是一个Python库,用于与Neo4j图数据库交互。graph = Graph(...)
: 创建Graph对象,建立与Neo4j数据库的连接。"bolt://localhost:7687"
: 指定Neo4j数据库的连接地址和端口。Bolt是Neo4j的高性能二进制协议。auth=("neo4j", "12345678")
: 提供认证信息,用户名"neo4j"和密码"12345678"。CA_LIST = {"贾家荣国府":0,"贾家宁国府":1,"王家":2,"史家":3,"薛家":4,"其他":5,"林家":6}
这是一个字典,定义了《红楼梦》中主要家族的分类编码:
键:家族/势力名称(如"贾家荣国府"、"王家"等)
值:对应的数字编码(0-6)
用途:在数据库中标记人物所属家族,或进行家族相关的统计分析。
similar_words = { "爸爸": "父亲", "妈妈": "母亲", # ...其他映射... "暧昧":"暧昧" }
这是一个关系类型的同义词标准化字典,将不同表达方式的亲属关系映射到标准名称:
例如:"爸爸"、"爹"、"father"都会映射到标准名称"父亲"
包含多种亲属关系:父母子女、兄弟姐妹、夫妻、祖孙等
也包含一些特殊关系如"朋友"、"暧昧"等
用途:在处理文本数据时,将不同表述的关系统一为标准化名称,便于后续分析和查询。
这段代码主要完成了三件事:
建立与Neo4j数据库的连接,为后续的图数据操作做准备
定义了《红楼梦》中主要家族的分类体系
这些配置在一个人物关系分析系统中使用,用于存储和查询《红楼梦》中的人物及其关系网络。
提供了关系类型的标准化映射,用于统一不同表述的亲属关系
接下来,启动neo4j
将准备好的人物关系三元组存入一个TXT文件里面,命名为Hrelation.txt,为方便后续其他人物关系三人组的构建将它存入一个人物关系三元组文件夹里面(如raw_data):
接下来进行数据库节点的连接与构建:
A方案:如果想让节点可以显示图片可用下面这段代码,将图片上传到本地Python服务器里面.再传给neo4j使其能够构建图片节点
from py2neo import Graph from config import graph BASE_IMAGE_URL = "http://localhost:8000" # 本地图片服务器地址 with open("../raw_data/Hrelation.txt", encoding='utf-8') as f: for line in f.readlines(): rela_array = line.strip("\n").split(",") print(rela_array) # 生成图片 URL image_url_1 = f"{BASE_IMAGE_URL}/{rela_array[0]}.png" image_url_2 = f"{BASE_IMAGE_URL}/{rela_array[1]}.png" # 创建或更新节点(带图片 URL) graph.run( """ MERGE (p:Person {Name: $name}) ON CREATE SET p.cate = $cate, p.image_url = $image_url ON MATCH SET p.image_url = $image_url """, name=rela_array[0], cate=rela_array[3], image_url=image_url_1 ) graph.run( """ MERGE (p:Person {Name: $name}) ON CREATE SET p.cate = $cate, p.image_url = $image_url ON MATCH SET p.image_url = $image_url """, name=rela_array[1], cate=rela_array[4], image_url=image_url_2 ) # 创建关系 graph.run( """ MATCH (a:Person {Name: $name1}), (b:Person {Name: $name2}) MERGE (a)-[r:RELATION {relation: $relation}]->(b) """, name1=rela_array[0], name2=rela_array[1], relation=rela_array[2] )
接下来我将详细介绍每一个地方是干什么的:
from py2neo import Graph from config import graph BASE_IMAGE_URL = "http://localhost:8000" # 本地图片服务器地址
from py2neo import Graph
: 导入py2neo库的Graph类,用于与Neo4j交互from config import graph
: 从config模块导入已配置好的graph对象(包含数据库连接信息)BASE_IMAGE_URL
: 定义本地图片服务器的基础URL,用于构建人物头像的完整URLwith open("../raw_data/Hrelation.txt", encoding='utf-8') as f: for line in f.readlines(): rela_array = line.strip("\n").split(",") print(rela_array)
打开
../raw_data/Hrelation.txt
文件(包含《红楼梦》人物关系数据)逐行读取文件内容
每行去除换行符后按逗号分割成数组
rela_array
打印当前处理的行内容(用于调试)
# 生成图片 URL image_url_1 = f"{BASE_IMAGE_URL}/{rela_array[0]}.png" image_url_2 = f"{BASE_IMAGE_URL}/{rela_array[1]}.png" # 创建或更新节点(带图片 URL) graph.run( """ MERGE (p:Person {Name: $name}) ON CREATE SET p.cate = $cate, p.image_url = $image_url ON MATCH SET p.image_url = $image_url """, name=rela_array[0], cate=rela_array[3], image_url=image_url_1 )
图片URL生成:
为两个人物的头像构造完整URL(假设图片以人物名+.png格式存储)
MERGE操作:
MERGE
确保节点存在,不存在则创建Person
是节点标签Name
是主属性,用于唯一标识人物ON CREATE SET
只在创建时设置cate
(类别)和image_url
属性ON MATCH SET
在节点已存在时更新image_url
属性# 创建关系 graph.run( """ MATCH (a:Person {Name: $name1}), (b:Person {Name: $name2}) MERGE (a)-[r:RELATION {relation: $relation}]->(b) """, name1=rela_array[0], name2=rela_array[1], relation=rela_array[2] )
MATCH:查找两个已存在的人物节点
MERGE:确保两者之间存在
RELATION
类型的关系关系带有
relation
属性,存储具体关系描述(如"父亲"、"妻子"等)这段代码的主要功能是:
从文本文件读取《红楼梦》人物关系数据
在Neo4j中创建或更新人物节点(包含名称、类别和头像URL)
最终构建出一个包含人物信息、所属家族和相互关系的知识图谱,可用于人物关系查询、可视化展示等应用场景。
在相关人物之间建立关系(带有关系类型属性)
B直接构建文字节点不使用图片,可节省大量脑力,代码段也比较简单:
from py2neo import Graph, Node, Relationship, NodeMatcher from Xconfig import graph with open("../raw_data/Hrelation.txt", encoding='utf-8') as f: for line in f.readlines(): relation_array = line.strip("\n").split(",") print(relation_array) graph.run("MERGE(p: Person{cate:'%s',Name: '%s'})" % (relation_array[3],relation_array[0])) graph.run("MERGE(p: Person{cate:'%s',Name: '%s'})" % (relation_array[4], relation_array[1])) graph.run( "MATCH(e: Person), (cc: Person) \ WHERE e.Name='%s' AND cc.Name='%s'\ CREATE(e)-[r:%s{relation: '%s'}]->(cc)\ RETURN r" % (relation_array[0], relation_array[1], relation_array[2],relation_array[2]) )
这段代码是用于将关系数据从文本文件导入Neo4j图数据库的Python脚本,主要功能是创建人物节点和建立他们之间的关系。下面我会详细分解每个部分的功能:
from py2neo import Graph, Node, Relationship, NodeMatcher from Xconfig import graph
导入的库:
Graph
: Neo4j数据库连接接口Node
: 表示图数据库中的节点Relationship
: 表示节点之间的关系NodeMatcher
: 用于查询节点的工具
from Xconfig import graph
: 从自定义配置文件导入已配置好的数据库连接对象
with open("../raw_data/Xrelation.txt", encoding='utf-8') as f:
for line in f.readlines():
relation_array = line.strip("\n").split(",")
print(relation_array)
打开
../raw_data/Hrelation.txt
文件(UTF-8编码)逐行读取文件内容
每行处理流程:
去除行尾换行符(
strip("\n")
)按逗号分割成数组(
split(",")
)打印当前行内容(用于调试)
graph.run("MERGE(p: Person{cate:'%s',Name: '%s'})" % (relation_array[3],relation_array[0])) graph.run("MERGE(p: Person{cate:'%s',Name: '%s'})" % (relation_array[4], relation_array[1]))
graph.run("MERGE(p: Person{cate:'%s',Name: '%s'})" % (relation_array[4], relation_array[1]))
MERGE操作:创建或匹配已有节点
节点结构:
标签:
Person
属性:
cate
: 人物类别(来自relation_array[3]和[4])Name
: 人物名称(来自relation_array[0]和[1])
分别为关系中的两个人物创建节点
graph.run( "MATCH(e: Person), (cc: Person) \ WHERE e.Name='%s' AND cc.Name='%s'\ CREATE(e)-[r:%s{relation: '%s'}]->(cc)\ RETURN r" % (relation_array[0], relation_array[1], relation_array[2],relation_array[2]) )
MATCH:查找两个已存在的人物节点
CREATE:创建从第一个节点到第二个节点的关系
关系结构:
类型:动态使用relation_array[2]的值
属性:
relation
,值同样来自relation_array[2]
RETURN r:返回创建的关系对象(主要用于确认操作成功)
这段代码的主要功能是:
从文本文件读取关系数据
在Neo4j中创建或匹配人物节点(带类别属性)
最终构建出一个包含人物节点和他们之间关系的知识图谱,适用于社交网络分析、关系可视化等场景
在指定人物间创建带有类型的关系
在连接到数据库的情况下运行A代码或者B代码,将会弹出以下效果:
我们这是打开数据库可以看到节点已经构建成功: