基于Python实现并测试Modularity算法
实现并测试Modularity算法
一、问题简述
1.1 社区发现问题
社区发现问题(Community Detection)用于解决网络中的聚类问题,从网络中发现社区。网络中的社区是一个内部节点联系紧密,社区之间联系稀疏的子网络结构,即社区满足高内聚、低耦合的特性。社区分为非重叠型社区(Disjoint Community)和重叠型社区(Overlapping Community),分别指各个社区节点集合彼此没有交集和有交集的社区结构模型。通过社区发现,可以发现社交网络、合作网络等中客观存在的社区结构,从而在实现用户 / 商品 / 网页等项(Item)推荐时优先推荐同一社区的用户 / 商品 / 网页。同时,社区网络实际上是按照某种标准对用户 / 商品 / 网页等项进行了一种划分,可以在划分的基础上对每一个社区进行进一步的挖掘,相比于直接挖掘网络中的信息,社区发现相当于分解了任务。
1.2 模块度
模块度(Modularity)用于度量社区内部链接相对于社区之间链接的紧密程度、衡量一个社区划分的质量。对于不同类型的网络(有向/无向图、带权/无权图)和不同的社区模型(重叠性型/非重叠型),不同研究对模块度给出了不同的定义,并衍生出了许多社区发现算法。这些基于模块度的社区发现算法,都已最大化模块度为目标。一般认为模块度大于 0.3(在 0.3 到 0.7 之间)可以说明,算法划分结果较为合适。在论文 Fast unfolding of communities in large networks 中,作者所使用的模块度是一个介于 -1 和 1 之间的标量。从节点的角度,其数学公式如下:
Q=12m∑i,j[Aij−kikj2m]δ(ci,cj)Q = \frac1{2m}\sum_{i,j}[A_{ij}-\frac{k_ik_j}{2m}]\delta(c_i,c_j) Q=2m1i,j∑[Aij−2mkikj]δ(ci,cj)
其中,AijA_{ij}Aij是节点 iii 和 jjj 关联的边 (i,j)(i,j)(i,j) 的权重;ki=∑jAijk_i = \sum_jA_{ij}ki=∑jAij 表示与节点 iii 关联的所有边的权值之和;cic_ici 是节点 iii 所属的社区,δ(u,v)\delta(u,v)δ(u,v) 函数仅当 u=vu = vu=v 时为 111,否则为 000;m=12∑ijAijm = \frac12\sum_{ij}A_{ij}m=21∑ijAij。
若图为无向图,$A_{ij} = 1$;$k_i$ 可以理解为节点 $i$ 的度数,$\frac{k_ik_j}{2m}$ 指 节点 $i$ 和 $j$ 邻接的概率,$m$ 是图的边数。从社区的角度,可以化简为如下公式:
Q=12m∑c(Σin−Σtot22m)Q = \frac1{2m}\sum_c(\Sigma in - \frac{\Sigma tot^2}{2m}) Q=2m1c∑(Σin−2mΣtot2)
其中,Σin\Sigma inΣin 表示社区 ccc 中所有节点之间的边权之和;Σtot\Sigma totΣtot 表示与社区 ccc 内的节点关联的边的权重之和。
引入模块度增益的概念:将节点 $i$ 分配到一个邻居节点所在的社区 $c$,从而给整个网络的模块度带来的变化量。结合上述的模块度定义,有:
ΔQ=12m(Σin+ki,in−Σtot+ki2m)−12m(Σin−Σtot22m−ki22m)=ki,in2m−kiΣtot2m2\Delta Q = \frac1{2m}(\Sigma in + k_{i,in} - \frac{\Sigma tot + k_i}{2m}) - \frac1{2m}(\Sigma in - \frac {\Sigma tot^2}{2m} - \frac{k_i^2}{2m}) \\ = \frac{k_{i, in}}{2m} - \frac{k_i\Sigma tot}{2m^2} ΔQ=2m1(Σin+ki,in−2mΣtot+ki)−2m1(Σin−2mΣtot2−2mki2)=2mki,in−2m2kiΣtot
1.3 GenLouvain算法步骤
GenLouvain算法可以划分为以下两个阶段:
- 阶段一:社区构建阶段
- 将每一个节点视为一个社区。
- 对于每一个节点 iii,考虑将节点 iii 从他所在的社区中移除,并加入到节点 iii 的一个邻接结点 jjj 所在的社区中,计算此过程再来的模块度变化值,最后保存模块度增值最大的邻居节点,如果模块度增值大于零,则将节点 iii 从他原来的社区移动到新的社区中,否则保持不变。
- 循环执行第 2 步,直到所有节点所属的社区不再变化,进入阶段二。
- 阶段二:网络重建阶段
视一个社区为下一阶段的网络中的一个节点,社区内节点之间的边的权重转化为新节点的内部权重,社区之间的边的权重转为为新节点之间的边权。
将新构建的网络输入到阶段 1,如果整个图的模块度发生变化,则返回阶段二进一步重建网络,否则结束该算法。
GenLouvain算法是基于模块度优化的启发式算法,算法无监督、易于理解、计算速度快,算法还可以通过分布式实现来进一步提速。
从算法步骤可以看出,计算耗时比较多的是第一层的社区划分,之后随网络的重建,节点的数目大大减少,计算好时不断缩短。在阶段一遍历节点时,结点的顺序对最终的社区划分有一定的影响,但差距不大,但会影响算法的运行时间。
二、GenLouvain 实现
GenLouvain 实现的基本框架参考了 https://github.com/xmweijh/CommunityDetection ,用一个 Vertex 类来表示、保存节点的节点编号、社区编号和权重等,并用一个 GenLouvain 类负责核心算法的实现。
Vertex 类
class Vertex:def __init__(self, vid, cid, nodes, k_in=0):self._vid = vid # 节点编号self._cid = cid # 社区编号self._nodes = nodes # 保存节点对应的原先网络社区内的节点self._k_in = k_in # 节点内部的边权重
GenLouvain 类包含以下属性:
_graph
:collections.defaultdict(dict)
以邻接表的形式保存网络_m
:网络的边数_vertices
:字典,键值是节点的编号vid
,值是节点对应的 Vertex 对象_community
:字典,键值是社区的编号cid
,值是社区节点编号vid
组成的集合
GenLouvain 类包含以下方法:
phase_1
执行算法的第一阶段,返回此轮社区划分有没有变化phase_2
执行算法的第二阶段,重建网络,将本轮划分得到的社区作为下一轮的节点get_communities
返回算法最终的社区划分结果excute
执行算法def execute(self):while self.phase_1():self.phase_2()return self.get_communities()
三、实验结果分析
为了增强实验的可比性,使用 Python 的 python-louvain 库而不是在 Matlab 上进行比较。由于难以找到规模合适并且包含真是标签的网络数据集,我们选择了 4 个含真是标签的数据集和 1 个不含标签的数据集,数据集信息如下表所示:
Dataset | Graph Type | Nodes | Edges | Communities | Link |
---|---|---|---|---|---|
polbooks | 无向无权 | 105 | 441 | 3 | http://www-personal.umich.edu/~mejn/netdata/polblogs.zip |
football | 无向无权 | 115 | 613 | 12 | http://www-personal.umich.edu/~mejn/netdata/football.zip |
email-Eu-core | 有向无权 | 1005 | 25571 | 42 | https://snap.stanford.edu/data/email-Eu-core.html |
lastfm_asia | 无向无权 | 7624 | 27806 | 18 | https://snap.stanford.edu/data/feather-lastfm-social.html |
无向无权 | 4039 | 88234 | unknown | https://snap.stanford.edu/data/ego-Facebook.html |
我们将 python-louvain 的结果视为标准,测试结果如下所示:
Dataset | My Communities | My NMI | My Modularity | My Cost Time |
---|---|---|---|---|
polbooks | 3 | 0.505 | 0.499 | 0.015 s |
football | 8 | 0.813 | 0.602 | 0.010 s |
email-Eu-core | 34 | 0.627 | 0.402 | 3.379 s |
lastfm_asia | 13 | 0.650 | 0.810 | 18.993 s |
13 | - | 0.828 | 18.227 s | |
Dataset | Standard Communities | Standard NMI | Standard Modularity | Standard Time Cost |
polbooks | 5 | 0.537 | 0.526 | 0.009 s |
football | 9 | 0.856 | 0.604 | 0.010 s |
email-Eu-core | 27 | 0.576 | 0.418 | 0.372 s |
lastfm_asia | 31 | 0.012 | 0.814 | 1.489 s |
16 | - | 0.834 | 2.197 s |
通过比较上述表格,我们发现在 polbook、football、email-Eu-core、facebook 四个数据集上,我们的实现python-louvain 的社区发现结果差别不大,在网络比较大时,我们的实现耗时明显增加。lastfm_asia 数据集比较特殊,我们的实现能得到 NMI 为 0.65 较好,但 Python-louvain 的划分结果 NMI 只有 0.01,我们猜测是由于python-louvain 划分社区过多的原因,但是我们和 python-louvain 的实现都能得到较高的模块度。通过五个数据集的测试,我们的实现应用在每一个数据集上都能得到高于 0.5 的 NMI,其中 football 数据集得到了 0.81 的 NMI,同时在每个数据集上都得到了较理想的模块度,在 0.48 到 0.83 之间。最后,我们将两个比较小的数据集 polbook 和 football 进行可视化,得到以下结果:
基于Python实现并测试Modularity算法相关推荐
- 基于Python+Open CV的手势识别算法设计
素材资料下载: 基于Python+OpenCV的手势识别算法设计源代码材料-机器学习文档类资源-CSDN下载采用Python的集成开发环境Pycharm进行本次课程设计,在Pycharm中进行需要库( ...
- python服务器稳定性,一种基于Python服务器稳定性测试的方法技术
[技术实现步骤摘要] 本专利技术涉及一种服务器稳定性测试的方法,具体地说是. 技术介绍 随着服务器行业的快速发展,越来越多的客户开始偏向于购买大批量的服务器作为自己的核心应用.所以对服务器的稳定性也提 ...
- python多叉树遍历_基于Python的多叉树遍历算法
[ 综直厘翹 S 赛理 ) 信息记录材料 2019 年 5 月第 20 卷第 5 期 基于 Python 的多叉树遍历算法 钱雨波 , 王金祥 ( 指导老师 ) ( 延边大学 吉林 延边 1 3300 ...
- 基于Python贝叶斯优化XGBoost算法调参报错“TypeError: ‘float‘ object is not subscriptable”
基于Python贝叶斯优化XGBoost算法调参运行情况如下: iter target colsam- gamma max_depth min_ch- subsample 1 0.9398 0.804 ...
- python算法的三种描述是什么_基于Python的产品经理必备算法描述
原标题:基于Python的产品经理必备算法描述 产品经理需要懂点算法,作者用案例描述了几种产品经理的必备算法. 未来的世界,一定是信息科技主导的世界.未来的任何产品,都离不开信息科技的支撑.不论你是哪 ...
- 基于python的回归与集成算法进行房价预测
项目介绍 在房地产大热的时代,很多人倾尽一生的财富来获取一套房子,很多时候客户会根据地理位置去选取某一小区来购置房产,那么在特定的地理位置上,什么样的房型是最热门的,什么样的房子才是具有性价比的,开发 ...
- 基于Python Scrapy爬虫改进KNN算法的网站分类系统
目 录 摘 要 I Abstract II 第 1 章 绪 论 1 1.1课题的研究背景和意义 1 1.1.1目前网站分类的研究情况 1 1.1.2现有解决方案的优点与不足 1 1.1.3基于特征熵值 ...
- 基于Python实现五大常用分类算法(原理+代码)
读: 在机器学习和统计中,分类算法通过对已知类别训练集的计算和分析,从中发现类别规则并预测新数据的类别.分类被认为是监督学习的一个实例,即学习可以获得正确识别的观察的训练集的情况. 实现分类的算法,特 ...
- go python php 压力测试_pyLot 基于python的压力测试工具
因为组内的产品是一个供上海甚至全球所有designer使用的网站,所以并发性很高,于是一直存在访问速度不佳的诟病.为了提高访问速度,就需要对该网站的性能进行测试.于是在网上查了并发性测试和自动化测试的 ...
最新文章
- python如何训练模型生产_手把手教你用Python构建你的第一个多标签图像分类模型(附案例)...
- Pandas对不同类型缺失值的转换规则
- Java秒杀系统优化的工程要点
- Visifire中图表的导出
- jquery ajax error但状态是200,jQuery $ .ajaxError()在200上运行 - 好的
- 序列化加密字段_自动加密可序列化的类
- Java异常处理(1)--异常概述与异常体系结构
- AngularJs通过路由传参解决多个页面资源浪费问题
- c# 配置文件App.config操作类库
- linux解锁文件.user.ini,Linux下解决网页服务器权限和.user.ini无法删除的问题
- Coding and Paper Letter(二)
- linux 7修改主机名重启后不生效_Linux 中改变主机名的 4 种方法 | Linux 中国
- BestCoder Round #81 (div.2) B Matrix
- Blender烘焙光照贴图
- 分布式理论,架构设计
- Linux下Chelsio T5调试方法
- oracle- 审计日志
- 从因果关系来看小样本学习
- influxdb官网文档翻译
- ArcMap 打不开
热门文章
- MacBook通过XGP玩女神异闻录5皇家版不踩坑指南
- 引用防删——JAVA设计模式总结之六大设计原则
- 在c语言中 实参与其对应的形参各占独立的存储单元,以下正确的说法是( )。在C语言中: A.实参和与其对应的形参各占用独立的存储单元...
- Excel图表—超级好用的Bullet图(KPI考核图)
- 电信各种视频免流卡申请地址合集附地址失效解决方法
- SpringBoot Mybatis 读写分离配置(山东数漫江湖)
- 尚硅谷前端框架vue语法(二)
- 选购硬盘HDD、SSD、SSHD、IDE、SATA、SCSI、SAS、PCIe、M.2、USB
- python根据关键字爬取微博_Python 超简单爬取微博热搜榜数据
- 代理记账的基本流程是什么