隣接行列を使用して、視覚的に次のように解釈できる友人のネットワークを表現しています。
Mary 0 1 1 1
Joe 1 0 1 1
Bob 1 1 0 1
Susan 1 1 1 0
Mary Joe Bob Susan
このマトリックスを使用して、ユーザー1がユーザー2と友達であり、ユーザー2がユーザー3と友達であるという条件で、考えられるすべての友情の三角形のリストを作成します。私のリストでは、ユーザー1がと友達である必要はありません。ユーザー3。
(joe, mary, bob)
(joe, mary, susan)
(bob, mary, susan)
(bob, joe, susan)
小さな三角形でうまく機能するコードが少しありますが、非常に大きなスパース行列に合わせてスケーリングする必要があります。
from numpy import *
from scipy import *
def buildTriangles(G):
# G is a sparse adjacency matrix
start = time.time()
ctr = 0
G = G + G.T # I do this to make sure it is symmetric
triples = []
for i in arange(G.shape[0] - 1): # for each row but the last one
J,J = G[i,:].nonzero() # J: primary friends of user i
# I do J,J because I do not care about the row values
J = J[ J < i ] # only computer the lower triangle to avoid repetition
for j in J:
K, buff = G[:,j].nonzero() # K: secondary friends of user i
K = K[ K > i ] # only compute below i to avoid repetition
for k in K:
ctr = ctr + 1
triples.append( (i,j,k) )
print("total number of triples: %d" % ctr)
print("run time is %.2f" % (time.time() - start())
return triples
私は約21分でcsr_matrixでコードを実行することができました。マトリックスは1032570x1032570で、88910個の格納された要素が含まれていました。合計2178893個のトリプレットが生成されました。
9428596の格納された要素を持つ1968654x1968654のスパース行列で同様のことを実行できる必要があります。
私はPythonに非常に慣れておらず(1か月弱の経験)、線形代数が得意ではありません。そのため、私のコードは行列演算を利用していません。誰かが改善のための提案をしたり、私の目的が現実的であるかどうかを教えてもらえますか?