Common neighbors and preferential attachment score matrixes using igraph for python
Is there an efficient way to calculate the matrix score for common neighbors(CC) and preferential attachment(PA) in python? I'm using igraph to calculate score matrixes for other methods such as jaccard's coefficient (Graph.similarity_jaccard()), dice (Graph.similarity_dice) and adamic/adar (Graph.similarity_inverse_log_weighted()), but I haven't found any function to compute score matrixes for CC and PA.
Currently I'm doing:
#Preferential attachment score between nodes i and j in a graph g
len(g.neighbors(i))*len(g.neighbors(j))
#Common neighbors score between nodes i and j in a graph g
len(g.neighbors(i) and g.neighbors(j))
but I have to do this for all edges(i,j) in the network which in my case is really large.
If anyone knows any mathematical matrix operation that generates such score matrixes I'm looking for, I would开发者_运维技巧 appreciate as well.
There is no direct function for this in igraph. However, note that len(g.neighbors(i))
is simply the degree of vertex i, so you can call g.degree()
, treat it as a 1D matrix using NumPy, then multiply it with its own transpose s.t. a column vector is multiplied by a row vector from the right. This gives you the preferential attachment score matrix:
from numpy import matrix
d = matrix(g.degree())
pref_score_matrix = d.T*d
The common neighbors score is trickier using matrix notation, and I wouldn't operate with matrices anyway if your graph is really large (even with only 2000 vertices, you would have a matrix with 4 million elements). I would simply cache set representations of g.neighbors(i)
for all possible values in a list, and then use that to calculate the common neighbor scores as sets can be intersected efficiently:
neisets = [set(g.neighbors(i)) for i in xrange(g.vcount())]
for v1, v2 in g.get_edgelist():
common_neis = neisets[v1].intersection(neisets[v2])
print "%d --> %d: %d" % (v1, v2, len(common_neis))
If you really want to stick to matrices, you can construct an n by n matrix consisting of zeros only using the zeros
function from NumPy and then loop over the vertices once. Get all the neighbors of vertex v and note that any pair of neighbors of v have one neighbor in common: v itself:
from itertools import combinations
from numpy import zeros
n = g.vcount()
common_neis = zeros(n, n)
for v in xrange(g.vcount()):
neis = g.neighbors(v)
for u, w in combinations(neis, 2):
# v is a common neighbor of u and w
common_neis[u, w] += 1
common_neis[w, u] += 1
精彩评论