Leiden算法简介:Python实现网络分区
Leiden算法详解:Python实现网络分区
大家好!今天我们来深入了解Leiden算法,这是一个用于网络分区的强大工具。我们将使用Python来实现这个算法,并通过一个实际的例子来展示它的工作原理。
1. Leiden算法简介
Leiden算法是一种用于社区检测的算法,它可以帮助我们在复杂的网络中找到紧密相连的群体。想象你要给一个大班级的学生分组,希望每个小组内的同学关系都很好,Leiden算法就是来解决这类问题的。
2. Python代码实战
让我们用Python来实际操作一下!我们将创建一个同学关系网络,然后使用Leiden算法来进行分组。
import networkx as nx
from graspologic.partition import hierarchical_leiden
# 创建同学关系图
G = nx.Graph()
students = [
"张三", "李四", "王五", "赵六", "孙七", "周八", "吴九", "郑十",
"钱十一", "朱十二", "陈十三", "林十四", "黄十五", "杨十六", "刘十七",
"何十八", "高十九", "马二十", "范二一", "程二二"
]
G.add_nodes_from(students)
# 添加同学关系
relationships = [
("张三", "李四"), ("张三", "王五"), ("李四", "赵六"), ("王五", "孙七"),
("赵六", "周八"), ("孙七", "吴九"), ("周八", "郑十"), ("吴九", "钱十一"),
("郑十", "朱十二"), ("钱十一", "张三"), ("朱十二", "李四"), ("陈十三", "林十四"),
("黄十五", "杨十六"), ("刘十七", "何十八"), ("高十九", "马二十"), ("范二一", "程二二"),
("张三", "陈十三"), ("李四", "黄十五"), ("王五", "刘十七"), ("赵六", "高十九"),
("孙七", "范二一"), ("周八", "林十四"), ("吴九", "杨十六"), ("郑十", "何十八"),
("钱十一", "马二十"), ("朱十二", "程二二")
]
G.add_edges_from(relationships)
# 使用Leiden算法进行分组
result = hierarchical_leiden(
graph=G,
max_cluster_size=5, # 每组最多5人
extra_forced_iterations=3 # 多尝试三次,看看有没有更好的分法
)
# 打印完整的分组结果
print("完整的分组结果:")
for cluster in result:
print(cluster)
# 整理并打印最终分组
final_groups = {}
for cluster in result:
if cluster.is_final_cluster:
if cluster.cluster not in final_groups:
final_groups[cluster.cluster] = []
final_groups[cluster.cluster].append(cluster.node)
print("\n最终分组结果:")
for group_num, members in final_groups.items():
print(f"第{group_num + 1}组:{', '.join(members)}")
3. 分组结果解读
运行上面的代码,我们得到了以下结果:
完整的分组结果:
HierarchicalCluster(node='李四', cluster=0, parent_cluster=None, level=0, is_final_cluster=True)
HierarchicalCluster(node='黄十五', cluster=0, parent_cluster=None, level=0, is_final_cluster=True)
HierarchicalCluster(node='吴九', cluster=0, parent_cluster=None, level=0, is_final_cluster=True)
HierarchicalCluster(node='杨十六', cluster=0, parent_cluster=None, level=0, is_final_cluster=True)
HierarchicalCluster(node='王五', cluster=1, parent_cluster=None, level=0, is_final_cluster=False)
HierarchicalCluster(node='朱十二', cluster=1, parent_cluster=None, level=0, is_final_cluster=False)
HierarchicalCluster(node='孙七', cluster=1, parent_cluster=None, level=0, is_final_cluster=False)
HierarchicalCluster(node='刘十七', cluster=1, parent_cluster=None, level=0, is_final_cluster=False)
HierarchicalCluster(node='范二一', cluster=1, parent_cluster=None, level=0, is_final_cluster=False)
HierarchicalCluster(node='郑十', cluster=1, parent_cluster=None, level=0, is_final_cluster=False)
HierarchicalCluster(node='何十八', cluster=1, parent_cluster=None, level=0, is_final_cluster=False)
HierarchicalCluster(node='程二二', cluster=1, parent_cluster=None, level=0, is_final_cluster=False)
HierarchicalCluster(node='张三', cluster=2, parent_cluster=None, level=0, is_final_cluster=True)
HierarchicalCluster(node='陈十三', cluster=2, parent_cluster=None, level=0, is_final_cluster=True)
HierarchicalCluster(node='周八', cluster=2, parent_cluster=None, level=0, is_final_cluster=True)
HierarchicalCluster(node='林十四', cluster=2, parent_cluster=None, level=0, is_final_cluster=True)
HierarchicalCluster(node='钱十一', cluster=3, parent_cluster=None, level=0, is_final_cluster=True)
HierarchicalCluster(node='赵六', cluster=3, parent_cluster=None, level=0, is_final_cluster=True)
HierarchicalCluster(node='高十九', cluster=3, parent_cluster=None, level=0, is_final_cluster=True)
HierarchicalCluster(node='马二十', cluster=3, parent_cluster=None, level=0, is_final_cluster=True)
HierarchicalCluster(node='王五', cluster=4, parent_cluster=1, level=1, is_final_cluster=True)
HierarchicalCluster(node='刘十七', cluster=4, parent_cluster=1, level=1, is_final_cluster=True)
HierarchicalCluster(node='孙七', cluster=5, parent_cluster=1, level=1, is_final_cluster=True)
HierarchicalCluster(node='范二一', cluster=5, parent_cluster=1, level=1, is_final_cluster=True)
HierarchicalCluster(node='朱十二', cluster=6, parent_cluster=1, level=1, is_final_cluster=True)
HierarchicalCluster(node='程二二', cluster=6, parent_cluster=1, level=1, is_final_cluster=True)
HierarchicalCluster(node='郑十', cluster=7, parent_cluster=1, level=1, is_final_cluster=True)
HierarchicalCluster(node='何十八', cluster=7, parent_cluster=1, level=1, is_final_cluster=True)
最终分组结果:
第1组:李四, 黄十五, 吴九, 杨十六
第3组:张三, 陈十三, 周八, 林十四
第4组:钱十一, 赵六, 高十九, 马二十
第5组:王五, 刘十七
第6组:孙七, 范二一
第7组:朱十二, 程二二
第8组:郑十, 何十八
让我们来解读这个结果:
level=0:初步分组
在 level=0
中,算法将所有学生分成了四个大组:
- 第一个组(cluster=0):包含李四、黄十五、吴九、杨十六
- 第二个组(cluster=1):包含王五、朱十二、孙七、刘十七、范二一、郑十、何十八、程二二
- 第三个组(cluster=2):包含张三、陈十三、周八、林十四
- 第四个组(cluster=3):包含钱十一、赵六、高十九、马二十
注意,第一、三、四组在这个级别就已经是最终结果了(is_final_cluster=True
)。
level=1:细分小组
在 level=1
中,算法进一步将第二个大组(cluster=1)细分成了四个小组:
- 王五、刘十七(cluster=4)
- 孙七、范二一(cluster=5)
- 朱十二、程二二(cluster=6)
- 郑十、何十八(cluster=7)
这些小组都是最终的分组结果(is_final_cluster=True
)。
4. 为什么会这样分组?
Leiden算法在分组时考虑了整个网络的结构,而不仅仅是直接的关系。例如:
- 李四、黄十五、吴九、杨十六被分在一组,可能是因为他们之间有较多的直接或间接联系。
- 虽然有些同学之间有直接联系(如张三和李四),但他们没有被分在一组,这可能是因为整体来看,将他们分开可以使得每个小组内部的关系更加紧密。
- 一些组只有两个人(如王五和刘十七),这可能是因为算法认为他们之间的关系特别紧密,或者他们与其他同学的关系相对较弱。
5. Leiden算法的工作原理
- 初步分组:算法首先根据网络结构将节点分成几个大的社区(在我们的例子中是4个)。
- 优化:然后,算法会尝试移动节点到不同的社区,以提高整体的模块度(衡量网络划分质量的指标)。
- 细化:最后,算法会在需要的情况下对大社区进行进一步的划分,形成更小的子社区(如我们例子中的第二个大组)。
整个过程会重复多次(在我们的例子中是3次,由 extra_forced_iterations=3
决定),以找到最优的分组方案。
6. 实际应用
Leiden算法不仅可以用于学生分组,还有很多其他应用:
- 社交网络分析:发现社交网络中的兴趣小组或社区。
- 生物信息学:分析蛋白质相互作用网络,发现功能相关的蛋白质群。
- 交通网络优化:识别城市中的社区结构,优化公共交通路线。
- 推荐系统:通过对用户进行分组,提供更精准的推荐。
7. 给初学者的建议
- 实验不同的参数:尝试改变
max_cluster_size
和extra_forced_iterations
,看看结果会有什么变化。 - 可视化网络:使用 NetworkX 库的绘图功能,将关系网络可视化,这样可以更直观地理解算法的工作原理。
- 尝试不同的数据集:你可以创建不同的关系网络,看看算法在不同情况下的表现。
- 理解随机性:注意,Leiden算法可能会因为随机性而在不同运行中产生略有不同的结果。这是正常的,也反映了实际网络中社区结构的复杂性。
8. 总结
通过这个详细的例子,我们看到了Leiden算法如何在复杂的网络中找到紧密相连的群体。虽然算法的内部工作原理可能很复杂,但使用Python实现起来并不困难。
这个算法的结果可能会让我们感到惊讶:有些看似应该在一起的同学被分开了,而一些看似关系不那么密切的同学却被分到了一起。这正体现了网络结构的复杂性,以及Leiden算法考虑整体网络结构的特点。
记住,编程和算法学习最重要的是实践。尝试修改代码,创建你自己的网络,看看会得到什么有趣的结果。祝你学习愉快,编程之路越走越远!
原文地址:https://blog.csdn.net/engchina/article/details/142425223
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!