一次人物关系分析的数据整理经过

本文介绍了一种使用Python处理大规模节点关系网数据的方法。通过递归算法遍历约11万条关系数据,筛选出与指定节点相关的4万多条独特关系,有效绘制出复杂的关系网图形。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

最近在做一个数据分析的研究过程中,遇到一个大约有3万个节点和11万条变的关系网,而我手中的数据简化一下大概是如下的格式:

节点1节点2
ab
ad
ba
bd
bc
be
cb
cd
da
db
dc
df

关系网对应的图形如下:
这里写图片描述


需求

我所需要做的就是从给定的节点出发,从11万条关系数据中挑出选定节点处于同一关系网的不重复的两两对应关系,这样就可以使用工具画出上面的关系网图形了。
也就是对于上面的表格,得到如下的表格形式:

节点1节点2
ab
ad
bd
bc
be
cd
df

解决

数据的处理我使用Python来完成,通过函数递归调用来完成所有11万条关系的遍历,由于对图论相关算法不了解,所以自己设计算法,最终用一个看上去比较笨的办法成功解决的问题。具体如下:

1、描述

算法的核心是从数据库中查出节点1这一列中所有等于a的行,然后再将每行中节点b中的值逐个作为参数带入函数进行递归查询,直到查询结束。为了因为存在a–>b,b–>a这样的数据会造成递归无限循环,因此,每次查询的时候需要有两个参数,第一个是本次查询的节点1值,另一个则是节点1的值作为上层节点2的值时所对应的节点1的值。同时为了防止跳过好几层后出现之前查询过值再次作为节点1的值进行查询,需要单独创建一个空的列表,将已经查询过的值插入列表,每次查询前检查,已经查询过的就不再进行查询,这里描述的比较绕口,可以直接跳过看代码。

2、代码
global relationship
relationship = [] #设置全局变量relationship用来保存最终导出的关系
global notList
notList = []      #设置全局变量notList用来保存已经作为节点1查询过的节点值,防止出现递归造成的死循环


def getTree(node1,node2):
    returnout = []  #为了防止递归层数太深导致的mysql连接数过大,使用returnout变量先将每次查询的关系存入列表
    db= pymysql.connect(host="localhost",user="root",  password="root",db="ant",port=3306) 
    cur = db.cursor()
    sqlstring = "SELECT * FROM test WHERE node1='"+node1+"' and node2!= '"+node2+"';"
    cur.execute(sqlstring)
    for eachiline in cur:
        returnout.append([eachiline[1],eachiline[2]])
    cur.close()
    db.close()
    for each in  returnout:  #遍历数据库查询结果,并对符合条件的数据进行深层次递归
		relationship.append([each[0],each[1]])  #将查询结果保存在导出列表中
	    print("[*]已统计"+str(len(relationship))+"对关系")
	    notList.append(each[0])  #将已经查询过的节点1值保存进notList列表
        if each[1] not in notList:  #检查节点2的值是否在notList列表中,如果不在就继续进行递归调用
	        getTree(each[1],each[0])  #递归调用时,将节点一和节点二的值对调带入函数进行下一层的查询,同时除去a-->b,b-->a这样的关系对,保证只出现一次。

getTree('a','')

使用测试数据执行成功后,最终从给定节点出发,从11万关系数据中挑选出与其相关的关系共4万多条,画出了一个十分庞大的关系网。


总结

问题是成功解决了,但是感觉有些啰嗦,如果你看到这篇文章且正好了解相关的算法,或者我写的方法就是其中某种算法值是存在更简洁的写法请一定留言告诉我。如果以后学习过程中有了新的认识,我也会及时在这里更大家更新分享的。

<think>嗯,用户想用Gephi来分析和可视化《三国演义》的人物关系数据。首先,我需要回忆一下之前的引用内容,看看有没有相关的信息。引用[4]提到了使用jieba分词和Gephi来处理数据,生成CSV文件。还有引用[3]讨论了人物关系的确定方法,不能只局限于同一句话中的互动,要考虑更广泛的关系。用户可能已经完成了一些数据提取,但需要具体的步骤来构建网络图。 首先,用户需要准备数据。这可能包括人物列表和他们的关系。引用[2]提到处理别名的问题,比如“玄德”和“刘备”是同一个人,所以数据清洗很重要。可能需要手动整理别名表,确保同一个人物的不同名称被正确识别。然后,使用jieba分词来提取文本中出现的人物名字,统计共现次数或者根据章节中的出现情况来建立关系权重。 接下来是数据处理的步骤。生成节点表和边表,节点表包括ID、标签、出现次数等,边表包括源节点、目标节点和权重。引用[4]提到将数据保存为CSV格式,供Gephi使用。用户可能需要检查数据格式是否正确,比如是否有重复的边,或者权重计算是否合理。 然后是Gephi的操作部分。导入数据后,可能需要调整布局,比如使用Force Atlas 2来分布节点,根据度数调整节点大小,颜色区分不同群体。引用[3]提到人物关系的复杂性,可能需要使用模块化算法来检测社区结构,帮助用户更直观地看到不同阵营的人物。 用户可能遇到的问题包括数据清洗不彻底,别名处理不当,导致同一个人物被分成多个节点。这时候需要提醒用户检查并手动修正。另外,Gephi中的布局调整可能需要多次尝试不同的参数,才能达到理想的可视化效果。还有,如何解释权重和度数的意义,帮助用户理解分析结果。 最后,用户可能需要进一步分析,比如结合小说内容解释人物关系的变化,或者比较不同算法得出的社区结构。这时候可以建议参考引用[3]中的方法,从更高视角分析关系,而不仅仅是直接的互动。</think>以下是使用Gephi分析和可视化《三国演义》人物关系数据的步骤指南: ### 一、数据准备阶段 1. **人物名称提取** - 使用`jieba`分词工具标注文本中的人名,需添加自定义词典解决古称问题(如"玄德=刘备")[^2] - 生成人物出现频次统计表(示例代码): ```python import jieba with open("sanguo.txt") as f: words = [word for word in jieba.cut(f.read()) if len(word)>=2] name_counts = Counter(words) ``` 2. **关系矩阵构建** - 采用"共现分析"方法:当两个人物在同一章节出现时建立联系 - 优化方法:根据对话、事件关联性设置权重值[^3] ### 二、数据处理阶段 1. **节点表(nodes.csv)** ```csv Id,Label,Size 0,刘备,358 1,曹操,412 2,诸葛亮,287 ... ``` 2. **边表(edges.csv)** ```csv Source,Target,Weight,Type 0,1,120,undirected 0,2,98,undirected ... ``` ### 三、Gephi可视化步骤 1. **数据导入** - 通过"文件-导入电子表格"分别导入节点表和边表 - 选择编码格式为UTF-8 2. **布局算法设置** - 初始布局选择`Force Atlas 2`(迭代1000次) - 调整参数: ``` 斥力强度=1000.0 吸引强度=10.0 重力=50.0 ``` 3. **视觉呈现优化** - 节点大小:按"Degree"属性缩放(范围10-50) - 节点颜色:使用`模块化算法`划分社区 - 边透明度:设置30%透明度避免视觉混乱 4. **标签渲染** - 开启"显示标签"功能 - 设置标签大小与节点度数关联 - 启用"标签避让"功能 ### 四、结果解读要点 1. **中心性指标** - 度数中心性最高者多为贯穿全书的核心人物(如曹操、刘备)[^2] - 介数中心性高者可能为关键纽带人物(如诸葛亮) 2. **社区划分** - 通过模块化算法可自动识别魏、蜀、吴阵营 - 特殊节点(如吕布)可能单独成簇 3. **动态演化** - 使用时间线功能可观察赤壁之战前后关系网变化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值