链路预测相似性指标计算示例(matlab+python)

        小白笔者最近一段时间在学习链路预测(Link Prediction),在查阅资料的时候,偶然间看到了吕琳媛和周涛合著的《链路预测》这本书,这是一本非常好的书,对经典的链路预测算法讲述的比较清楚,其中为了让读者理解链路预测的含义和计算方法,作者举了一个例子,如下图所示:

图1 示例网络

        在书中,作者用CN指标、RA指标以及Jaccard指标计算节点的相似性。

        三种指标的计算公式如下:

        其中S表示相似性矩阵,A表示网络的邻接矩阵,\Gamma (x)表示节点x的邻居节点的集合,\Gamma (y)表示节点y的邻居节点的集合。

(1)CN指标:

       CN指标是基于局部信息的结构相似性指标,其本质是两个节点的共同邻居越多,两个节点越相似,产生连边的可能性越大,上市实际上计算的是节点之间路径长度为2的数目,这一点比较容易理解,节点v_x与节点v_y他们的公共邻居为v_z,则v_x-v_y-v_z的路径长度为2,节点v_x与节点v_y之间有几条这样的路径,节点v_xv_y的CN值就是多少。

(2)RA指标:

        RA指标计算的是节点v_y接收到的资源数,该值即为节点v_xv_y之间的相似度,此指标计算是,首先要假设每个节点接收到的资源平均分配给它的邻居节点。    

(3)Jaccard指标

将上述三种指标应用于图1所示的网络当中,编程实现,代码如下:

matlab的下标是由1开始计数,python的下标由0开始计数,因此两者读入的网络的邻接表的起始下标不同。

一、matlab代码

(1)主函数

clear all
clc
linklist = load( 'ex_linklist.txt');
%------------------------------根据网络的邻接表构造网络的邻接矩阵
linklist( :, 3 ) = 1;          %对无向图,将邻接表将第三列元素置为1
Net = spconvert( linklist );
nodenum = length( Net );
Net( nodenum, nodenum ) = 0;   %此处删除自环,对角元为0以保证为方阵
Net = Net-diag( diag ( Net ));
Net = spones( Net + Net' );    %确保邻接矩阵为对称矩阵
%------------------------------节点相似性
SimCN = CN( Net );
SimJac = Jaccard( Net );
SimRA = RA( Net );
%----------------------------- 采用全矩阵形式表示
Net1 = full( Net );
SimCN1 = full( SimCN );
SimJac1 = full( SimJac );
SimRA1 = full( SimRA );

(2)Common_Neighbors指标

function [ sim ] = CN( matrix )
%计算CN指标
%matrix-网络的邻接矩阵,sim-相似性矩阵
    sim = matrix * matrix;        
end

(3)RA指标

function [ sim ] = RA( matrix )   
%计算RA指标
%net-网络的邻接矩阵,sim-相似性矩阵
    sim1 = matrix ./ repmat( sum ( matrix, 2 ), [1, size( matrix, 1 ) ] ); 
    sim1(isnan(sim1)) = 0; 
    sim1(isinf(sim1)) = 0;
    sim = matrix * sim1;
end

(4)Jaccard指标

function[ sim ] = Jaccard( matrix )
%计算Jaccard指标
%net-网络的邻接矩阵,sim-相似性矩阵
    sim = matrix * matrix;                              %分子,CN             
    deg_row = repmat( sum( matrix, 1 ), [size( matrix, 1 ),1 ] );%节点的度
    deg_row = deg_row .* spones(sim);             %只需保留分子不为0对应的元素
    deg_row = triu( deg_row ) + triu( deg_row' );     %节点对(x,y)的两节点的度之和
    sim = sim ./ ( deg_row .* spones( sim ) - sim );         
    % 计算相似度矩阵 节点x与y并集的元素数目 = x与y的度之和 - 交集的元素数目
end

二、python代码:

import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
#--------------------------------------------
def Common_Neighbors( matrix ):
    #计算CN指标
    #matrix-网络的邻接矩阵,sim-相似性矩阵
    sim = np.dot( matrix, matrix )
    return sim
#--------------------------------------------
def RA( matrix ):
    #计算RA指标
    #matrix-网络的邻接矩阵,sim-相似性矩阵
    add_row = matrix.sum( axis = 1 )           #行求和
    add_row_matrix = np.tile( add_row, (( matrix.shape )[0]) )
    sim = adjacent_matrix / add_row_matrix     #节点权重
    sim = matrix * sim
    return sim 
#-------------------------------------------   
def Jaccard( matrix ):
    #计算Jaccard指标
    #matrix-网络的邻接矩阵,sim-相似性矩阵
    sim = matrix * matrix
    sim1 = sim.copy()                          #深复制,sim1与sim指向不同内存
    sim1[ np.nonzero( sim1 ) ] = 1             #分子
    deg_row = matrix.sum( axis = 0 )           #行求和得节点度
    deg_row_matrix = np.tile( deg_row, ( (matrix.shape)[0], 1) )
    deg_row_matrix = np.multiply( deg_row_matrix, sim1 )
    deg_row_matrix = np.triu( deg_row_matrix ) + np.triu( (deg_row_matrix.T) )
    sim = sim / ( np.multiply( deg_row_matrix, sim1 ) - sim )
    return sim
#-------------------------------------------
G = nx.read_adjlist( 'linklist.txt' )        #无向图 
adjacent_matrix = nx.to_numpy_matrix( G )    #邻接矩阵
#--------------------------------------------绘图
nx.draw_networkx(G, pos=nx.circular_layout(G), with_labels = True )
plt.show()
#--------------------------------------------节点相似性
CN_sim = Common_Neighbors( adjacent_matrix )
RA_sim = RA( adjacent_matrix )
Jac_sim = Jaccard( adjacent_matrix )

使用Networkx创建的网络如图所示:

图2 networkx创建的网络

由于本人初步涉及Networkx库对于该库的绘制网络的函数不甚了解,因此节点的标签默认为由0开始。

参考资料:

[1]吕琳媛,周涛.链路预测[M].高等教育出版社:北京,2013:57-74,289-307.

[2]Link Prediction Group

-------------------------------------------------------------------------------------------

2020年12月27日晚更新

数据集以及代码已经上传到gitlee,有需要的朋友们可以点击链接自行下载,原以为没有太多人需要,但是有很多人评论或私信要数据集,所以链接附在博客下面,谢谢各位朋友的鼓励,我会继续努力的。欢迎批评指正我们共同努力。

  • 20
    点赞
  • 119
    收藏
    觉得还不错? 一键收藏
  • 120
    评论
评论 120
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值