文章目录
解读math_graph.py_图处理工具
import numpy as np
import pandas as pd
from scipy.sparse.linalg import eigs
scaled_laplacian()函数
def scaled_laplacian(W):
'''
Normalized graph Laplacian function.
:param W: np.ndarray, [n_route, n_route], weighted adjacency matrix of G.
:return: np.matrix, [n_route, n_route].
'''
# d -> diagonal degree matrix
n, d = np.shape(W)[0], np.sum(W, axis=1)
# L -> graph Laplacian
L = -W
L[np.diag_indices_from(L)] = d
for i in range(n):
for j in range(n):
if (d[i] > 0) and (d[j] > 0):
L[i, j] = L[i, j] / np.sqrt(d[i] * d[j])
# lambda_max \approx 2.0, the largest eigenvalues of L.
lambda_max = eigs(L, k=1, which='LR')[0][0].real
return np.mat(2 * L / lambda_max - np.identity(n))
这段Python代码定义了一个函数scaled_laplacian
,用于计算一个图的归一化拉普拉斯矩阵(Normalized Laplacian Matrix)。
参数:
W
: 这是一个NumPy数组,具有维度[n_route, n_route]
,表示图G的加权邻接矩阵。
返回值:
- 函数返回一个NumPy矩阵,其维度是
[n_route, n_route]
,代表归一化拉普拉斯矩阵。
功能和逻辑:
-
计算度数矩阵(Degree Matrix):
d
是一个一维数组,其中第i
个元素是节点i
的度(degree),即与节点i
相连接的所有边的权重之和。
-
计算原始拉普拉斯矩阵(Unnormalized Laplacian Matrix)
L
:- 初始化
L
为-W
(邻接矩阵的负数)。 - 将
L
的对角线元素设置为相应节点的度。
- 初始化
-
归一化:
- 对于非零度的节点
i
和j
,将L[i, j]
更新为L[i, j] / sqrt(d[i] * d[j])
。
- 对于非零度的节点
-
计算最大特征值
lambda_max
:- 使用
eigs
函数计算L
的最大特征值(即最大的实部)。
- 使用
-
进一步归一化:
- 返回
2 * L / lambda_max - np.identity(n)
,其中np.identity(n)
是单位矩阵。
- 返回
该函数通常用于图信号处理和图卷积网络(Graph Convolutional Networks, GCNs)中,特别是在需要对图结构进行编码或嵌入的情况下。归一化拉普拉斯矩阵在这些应用中有助于提高算法的性能和稳定性。
cheb_poly_approx()函数
def cheb_poly_approx(L, Ks, n):
'''
Chebyshev polynomials approximation function.
:param L: np.matrix, [n_route, n_route], graph Laplacian.
:param Ks: int, kernel size of spatial convolution.
:param n: int, number of routes / size of graph.
:return: np.ndarray, [n_route, Ks*n_route].
'''
L0, L1 = np.mat(np.identity(n)), np.mat(np.copy(L))
if Ks > 1:
L_list = [np.copy(L0), np.copy(L1)]
for i in range(Ks - 2):
Ln = np.mat(2 * L * L1 - L0)
L_list.append(np.copy(Ln))
L0, L1 = np.matrix(np.copy(L1)), np.matrix(np.copy(Ln))
# L_lsit [Ks, n*n], Lk [n, Ks*n]
return np.concatenate(L_list, axis=-1)
elif Ks == 1:
return np.asarray(L0)
else:
raise ValueError(f'ERROR: the size of spatial kernel must be greater than 1, but received "{Ks}".')
这段Python代码定义了一个函数cheb_poly_approx
,该函数用于计算Chebyshev多项式近似,这在图卷积网络(Graph Convolutional Networks,简称GCNs)中是一种常见的操作。
参数:
L
: 这是一个NumPy矩阵,表示图的拉普拉斯矩阵(Laplacian)。其维度是[n_route, n_route]
。Ks
: 这是一个整数,表示空间卷积的核(kernel)大小。n
: 这是一个整数,表示图中的路由或节点数。
返回值:
- 函数返回一个NumPy数组,其形状是
[n_route, Ks * n_route]
。
功能和逻辑:
-
初始化:
L0
是一个单位矩阵,L1
是拉普拉斯矩阵L的副本。 -
计算Chebyshev多项式:
- 如果
Ks > 1
,那么它会使用递归关系Ln = 2 * L * L1 - L0
计算出Ks阶的Chebyshev多项式,并将它们存储在一个列表L_list
中。 - 每次迭代,
L0
和L1
都会更新,以用于计算下一个Chebyshev多项式。
- 如果
-
连接(Concatenation):最后,这些Chebyshev多项式被连接成一个大的矩阵,其形状是
[n_route, Ks * n_route]
。 -
特殊情况:
- 如果
Ks == 1
,则函数只返回单位矩阵。 - 如果
Ks
小于或等于 1,函数将抛出一个错误。
- 如果
这个函数的主要作用是准备空间卷积的多项式系数,这些系数随后可以用于GCNs中的卷积操作。它实际上计算了一组局部(spatial)的基函数(在这里是Chebyshev多项式),这些基函数用于在节点与其邻居之间共享信息。
first_approx()函数
def first_approx(W, n):
'''
1st-order approximation function.
:param W: np.ndarray, [n_route, n_route], weighted adjacency matrix of G.
:param n: int, number of routes / size of graph.
:return: np.ndarray, [n_route, n_route].
'''
A = W + np.identity(n)
d = np.sum(A, axis=1)
sinvD = np.sqrt(np.mat(np.diag(d)).I)
# refer to Eq.5
return np.mat(np.identity(n) + sinvD * A * sinvD)
这段Python代码定义了一个函数first_approx
,用于计算图的一阶近似拉普拉斯矩阵。
参数:
W
: 这是一个NumPy数组,其维度为[n_route, n_route]
,表示图G的加权邻接矩阵。n
: 这是一个整数,表示图中的路由或节点数。
返回值:
- 函数返回一个NumPy数组,其维度为
[n_route, n_route]
。
功能和逻辑:
-
创建增广邻接矩阵(Augmented Adjacency Matrix):
A = W + np.identity(n)
:将单位矩阵加到邻接矩阵W
上,以包含自环(self-loops)。
-
计算度数矩阵的平方根的逆(Inverse Square Root of Degree Matrix):
- 首先计算
d
,一个一维数组,其中第i
个元素是节点i
的度,即与节点i
相连接的所有边的权重之和。 - 然后计算度数矩阵
D
的平方根的逆,表示为sinvD
。
- 首先计算
-
计算一阶近似:
- 返回的矩阵是
np.mat(np.identity(n) + sinvD * A * sinvD)
,这是对图的一阶近似拉普拉斯矩阵。
- 返回的矩阵是
这种一阶近似通常用于图卷积网络(Graph Convolutional Networks, GCNs)等图分析任务中,特别是在需要将图结构编码为低维表示或嵌入的情况下。这种近似方法允许网络捕捉到图中节点之间的局部结构信息。
weight_matrix()函数
def weight_matrix(file_path, sigma2=0.1, epsilon=0.5, scaling=True):
'''
Load weight matrix function.
:param file_path: str, the path of saved weight matrix file.
:param sigma2: float, scalar of matrix W.
:param epsilon: float, thresholds to control the sparsity of matrix W.
:param scaling: bool, whether applies numerical scaling on W.
:return: np.ndarray, [n_route, n_route].
'''
try:
W = pd.read_csv(file_path, header=None).values
except FileNotFoundError:
print(f'ERROR: input file was not found in {file_path}.')
# check whether W is a 0/1 matrix.
if set(np.unique(W)) == {0, 1}:
print('The input graph is a 0/1 matrix; set "scaling" to False.')
scaling = False
if scaling:
n = W.shape[0]
W = W / 10000.
W2, W_mask = W * W, np.ones([n, n]) - np.identity(n)
# refer to Eq.10
return np.exp(-W2 / sigma2) * (np.exp(-W2 / sigma2) >= epsilon) * W_mask
else:
return W
这段Python代码定义了一个函数weight_matrix
,用于加载一个权重矩阵,并根据给定的参数进行一些额外的处理和缩放。
参数:
file_path
: 字符串,指定保存权重矩阵文件的路径。sigma2
: 浮点数,用于权重矩阵W
的缩放。epsilon
: 浮点数,用于控制权重矩阵W
的稀疏性。scaling
: 布尔值,表示是否对W
进行数值缩放。
返回值:
- 返回一个NumPy数组
W
,其形状为[n_route, n_route]
。
功能和逻辑:
-
加载权重矩阵:
- 尝试从
file_path
读取CSV文件,并将其存储在W
中。
- 尝试从
-
检查矩阵类型:
- 如果
W
是一个0/1矩阵,即其所有元素都是0或1,那么将scaling
设置为False
。
- 如果
-
缩放与稀疏化:
- 如果
scaling
为True
,则进行以下操作:- 缩小
W
的值(除以10000)。 - 计算
W
的平方(W2
)以及一个掩码矩阵(W_mask
),该掩码矩阵与W
有相同的形状,但对角线上的元素是0。 - 使用公式
exp(-W2 / sigma2) * (exp(-W2 / sigma2) >= epsilon) * W_mask
进行进一步的缩放和稀疏化。
- 缩小
- 如果
-
返回处理后的权重矩阵:
- 如果
scaling
为True
,返回处理后的W
。 - 否则,返回原始的
W
。
- 如果
这个函数主要用于图卷积网络(Graph Convolutional Networks, GCNs)或其他图分析任务,特别是在需要从文件中加载并预处理图结构信息的情况下。通过调整sigma2
和epsilon
参数,你可以控制图的稀疏性和权重分布,这可能有助于改善模型性能。