Python実装で理解するラプラシアン行列(Laplacian matrix)の概要
GNN(Graph Neural Network)関連についていくつか見ていたのですが、ラプラシアン行列はConvolutinal Graph Neural NetworkのSpectral-basedの話に関連して出てくるものの、あまり見たことがなかったのでPython実装を通して簡単にまとめておきます。
[1901.00596] A Comprehensive Survey on Graph Neural Networks
上記のConvolutinal Graph Neural Networkにおいて、正規化ラプラシアン行列(normalized Laplacian matrix)も用いられていますが、概要を掴むのも兼ねてPythonを用いて簡単に実装してみます。
以下目次になります。
1. ラプラシアン行列の概要
2. ラプラシアン行列の実装
3. まとめ
1. ラプラシアン行列の概要
1節ではラプラシアン行列の概要についてまとめます。
ラプラシアン行列 - Wikipedia
上記はWikipediaのラプラシアン行列の冒頭部の記載になります。グラフ理論の数学的分野における考え方で、グラフの行列表現を表すとされています。
ここで、数式な定義としてはラプラシアン行列のは上記のように、グラフの次数行列のから隣接行列のを引いた行列として定義されています。
具体的な値に関しては上記のように、が与えられるとされています。のとき、は頂点の次数に一致、の際は頂点とが隣接していればに一致、でとが隣接していなければに一致するとされています。
同様にConvolutinal Graph Neural NetworkのSpectral-basedに出てくる正規化ラプラシアンについても確認しておきます。
正規化ラプラシアンは上記のように記載されています。ラプラシアン行列がノード(頂点)の次数で正規化されたと考えておけば良さそうです。やは二つのノードが隣接している前提であれば最小値を取り、この時は最小値を取ります。やは頂点とが他のノードと多く連結していればしているほど値が大きくなるので、-1≦<0の値を動くとだけ把握しておくと良さそうです。
正規化ラプラシアンまで把握できたので1節はここまでとします。
2. ラプラシアン行列の実装
2節ではPythonを用いたラプラシアン行列の簡単な実装を行います。
import numpy as np
a = np.array([[0,1,0,0,1,0],[1,0,1,0,1,0],[0,1,0,1,0,0],[0,0,1,0,1,1],[1,1,0,1,0,0],[0,0,0,1,0,0]])
d = np.diag(np.sum(a,axis=0))
l = d-aprint(a)
print("===")
print(d)
print("===")
print(l)
上記はトップ画像にも貼っているWikipedia記載のラプラシアン行列の実装での表記になります。実行結果は下記のようになります。
次に正規化ラプラシアン行列について確認してみます。
import numpy as np
from scipy import linalga = np.array([[0,1,0,0,1,0],[1,0,1,0,1,0],[0,1,0,1,0,0],[0,0,1,0,1,1],[1,1,0,1,0,0],[0,0,0,1,0,0]])
d = np.diag(np.sum(a,axis=0))
l = d-al_norm = np.dot(np.sqrt(linalg.inv(d)),np.dot(l,np.sqrt(linalg.inv(d))))
np.set_printoptions(precision=3)
print(l_norm)
上記の実行結果は下記になります。
ここでは逆行列の計算としてscipy.linalg.inv、-1/2乗の計算としてはnp.sqrtを用いました(対角行列で結果だけざっくり確認できれば良いという前提だったため、最適な実装ではないかもしれません)。
1節で確認した数式通りの結果が得られ、大枠については確認できたので2節はここまでとします。
3. まとめ
当記事ではGNNで出てくる正規化ラプラシアン行列について取り扱いました。
行列の積などが色々と出てきて複雑そうに見えますが、ラプラシアン行列ではが対角行列だったため、計算上は比較的取り扱いやすい内容でした。