G をグラフとします。したがって、G はノードの集合とリンクの集合です。グラフをすばやく分割する方法を見つける必要があります。私が現在取り組んでいるグラフには 120*160 ノードしかありませんが、別のコンテキスト (医学ではなく Web サイト開発) で数百万のノードを持つ同等の問題にすぐに取り組んでいる可能性があります。
だから、私がしたことは、すべてのリンクをグラフマトリックスに格納することでした:
M=numpy.mat(numpy.zeros((len(data.keys()),len(data.keys()))))
ここで、ノード s がノード t に接続されている場合、M は位置 s,t に 1 を保持します。M が対称 M[s,t]=M[t,s] であり、各ノードが M[s,s]=1 にリンクしていることを確認します。
よく覚えているのですが、M に M を掛けると、結果は 2 つのステップで到達した頂点を結ぶグラフを表す行列になります。
したがって、行列内のゼロの数が減少しなくなるまで、M をそれ自体で乗算し続けます。これで、接続されたコンポーネントのリストができました。次に、このマトリックスをクラスター化する必要があります。
今のところ、アルゴリズムにはかなり満足しています。簡単で、エレガントで、かなり速いと思います。この部分で悩んでいます。
基本的に、このグラフを接続されたコンポーネントに分割する必要があります。
すべてのノードを調べて、それらが何に接続されているかを確認できます。
しかし、行を並べ替えて行列をソートするのはどうでしょうか。しかし、それが可能かどうかはわかりません。
以下は、これまでのコードです。
def findzeros(M):
nZeros=0
for t in M.flat:
if not t:
nZeros+=1
return nZeros
M=numpy.mat(numpy.zeros((len(data.keys()),len(data.keys()))))
for s in data.keys():
MatrixCells[s,s]=1
for t in data.keys():
if t<s:
if (scipy.corrcoef(data[t],data[s])[0,1])>threashold:
M[s,t]=1
M[t,s]=1
nZeros=findzeros(M)
M2=M*M
nZeros2=findzeros(M2)
while (nZeros-nZeros2):
nZeros=nZeros2
M=M2
M2=M*M
nZeros2=findzeros(M2)
編集:
SVD 分解を使用することが提案されています。これは、5x5 グラフの問題の簡単な例です。これを使用するのは、19200x19200 の正方行列ではクラスターが見にくいためです。
import numpy
import scipy
M=numpy.mat(numpy.zeros((5,5)))
M[1,3]=1
M[3,1]=1
M[1,1]=1
M[2,2]=1
M[3,3]=1
M[4,4]=1
M[0,0]=1
print M
u,s,vh = numpy.linalg.linalg.svd(M)
print u
print s
print vh
基本的にここには 4 つのクラスターがあります: (0),(1,3),(2),(4) しかし、このコンテキストで svn がどのように役立つかはまだわかりません。