Python求解拉普拉斯矩阵及其特征值

简介: 一、背景介绍1.1 图论基础定义一(图的邻接矩阵):

一、背景介绍

1.1 图论基础

定义一(图的邻接矩阵)

给定一个图G = { V , E } \mathcal{G}=\{\mathcal{V}, \mathcal{E}\}G={V,E},其对应的邻接矩阵被记为image.png表示存在从结点v i v_iv

i

到v j v_jv

j

的边,反之表示不存在从结点v i v_iv

i

到v j v_jv

j

的边。

在无向图中,从结点v i v_iv

i

到v j v_jv

j

的边存在,意味着从结点v j v_jv

j

到v i v_iv

i

的边也存在。因而无向图的邻接矩阵是对称的。

在无权图中,各条边的权重被认为是等价的,即认为各条边的权重为1 11。

对于有权图,其对应的邻接矩阵通常被记为W ∈ { 0 , 1 } N × N \mathbf{W} \in\{0,1\}^{N \times N}W∈{0,1}

N×N

,其中W i , j = w i j \mathbf{W}_{i, j}=w_{ij}W

i,j

=w

ij

表示从结点v i v_iv

i

到v j v_jv

j

的边的权重。若边不存在时,边的权重为0 00。

一个无向无权图的例子:


image.png

image.png

其邻接矩阵为:

image.png

定义二(拉普拉斯矩阵,Laplacian Matrix):

给定一个图G = { V , E } \mathcal{G}=\{\mathcal{V}, \mathcal{E}\}G={V,E},其邻接矩阵为A AA,其拉普拉斯矩阵定义为L = D − A \mathbf{L=D-A}L=D−A,其中度矩阵 D = d i a g ( d ( v 1 ) , ⋯   , d ( v N ) ) \mathbf{D=diag(d(v_1), \cdots, d(v_N))}D=diag(d(v

1

),⋯,d(v

N

))。

定义三(对称归一化的拉普拉斯矩阵,Symmetric normalized Laplacian):

给定一个图G = { V , E } \mathcal{G}=\{\mathcal{V}, \mathcal{E}\}G={V,E},其邻接矩阵为A AA,其规范化的拉普拉斯矩阵定义为


image.png

image.png

1.2 拉普拉斯矩阵的变体

节点数为n nn的简单图G GG,A AA是G GG的邻接矩阵,则如上面介绍的那样,G GG的拉普拉斯矩阵即L = D − A L=D-AL=D−A。

(1)对称归一化后的拉普拉斯矩阵:

image.png

(2)随机游走归一化的拉普拉斯矩阵:

image.png

1.3 拉普拉斯矩阵的优良性质:

拉普拉斯矩阵是半正定对称矩阵

对称矩阵有n个线性无关的特征向量,n是Graph中节点的个数 ⇒ \Rightarrow⇒ 拉普拉斯矩阵可以特征分解

半正定矩阵的特征值非负

对称矩阵的特征向量构成的矩阵为正交阵 ⇒ U T U = E \Rightarrow U^{T} U=E⇒U

T

U=E

1.4 GCN为啥要用拉普拉斯矩阵

拉普拉斯矩阵可以谱分解(特征分解)GCN是从谱域的角度提取拓扑图的空间特征的。

拉普拉斯矩阵只在中心元素和一阶相邻元素处有非零元素,其他位置皆为0.

传统傅里叶变换公式中的基函数是拉普拉斯算子,借助拉普拉斯矩阵,通过类比可以推导出Graph上的傅里叶变换公式。

二、Python代码实现

这是networkX库对稀疏矩阵A的处理方式,有少量改进(将所有内容保持稀疏):

n,m = A.shape
diags = A.sum(axis=1)
D = sps.spdiags(diags.flatten(), [0], m, n, format='csr')
D - A

numpyscipy两个库中模块中都提供了线性代数的库linalg,但scipylinalg的更全面一些。

# laplacian矩阵
import numpy as np
def unnormalized_laplacian(adj_matrix):
    # 先求度矩阵
    R = np.sum(adj_matrix, axis=1)
    degreeMatrix = np.diag(R)
    return degreeMatrix - adj_matrix
# 对称归一化的laplacian矩阵
def normalized_laplacian(adj_matrix):
    R = np.sum(adj_matrix, axis=1)
    R_sqrt = 1/np.sqrt(R)
    D_sqrt = np.diag(R_sqrt)
    I = np.eye(adj_matrix.shape[0])
    return I - np.matmul(np.matmul(D_sqrt, adj_matrix), D_sqrt)

matlab的代码实现为:

L = diag(sum(A,2)) - A   % or L=diag(sum(A))-A because A is symmetric

那么如何求矩阵的特征值呢——利用numpy的linalg.eig

# !/usr/bin/python
## -*-coding:utf-8 -*-
import numpy as np
A = np.array([[3,-1],[-1,3]])
print('打印A:\n{}'.format(A))
a, b = np.linalg.eig(A)
print('打印特征值a:\n{}'.format(a))
print('打印特征向量b:\n{}'.format(b))

得到特征值和特征向量

打印A:  
[[ 3 -1] 
 [-1  3]]
打印特征值a:
[4. 2.]
打印特征向量b:
[[ 0.70710678  0.70710678] 
 [-0.70710678  0.70710678]]

三阶矩阵试试,回归考研线代的题目:

image.png

import numpy as np
A = np.array([[2,-3,1],[1,-2,1],[1,-3,2]])
print('打印A:\n{}'.format(A))
a, b = np.linalg.eig(A)
print('打印特征值a:\n{}'.format(a))
print('打印特征向量b:\n{}'.format(b))

结果如下,看结果的特征向量矩阵,每一列代表一个一个特征向量,都是

打印A:
[[ 2 -3  1]
 [ 1 -2  1]
 [ 1 -3  2]]
打印特征值a:
[2.09037533e-15+0.00000000e+00j 1.00000000e+00+5.87474805e-16j
 1.00000000e+00-5.87474805e-16j]
打印特征向量b:
[[0.57735027+0.j         0.84946664+0.j         0.84946664-0.j        ]
 [0.57735027+0.j         0.34188085-0.11423045j 0.34188085+0.11423045j]
 [0.57735027+0.j         0.17617591-0.34269135j 0.17617591+0.34269135j]]

三、关于图Fourier变换

根据卷积原理,卷积公式可以写成

image.png

正、逆Fourier变换

image.png

一阶导数定义

image.png

拉普拉斯相当于二阶导数

image.png
在graph上,定义一阶导数为

image.png

对应的拉普拉斯算子定义为

image.png

假设D DD为N × N N\times{N}N×N的度矩阵(degree matrix)


image.png

image.png

A为N × N N\times{N}N×N的邻接矩阵(adjacency matrix)


image.png

image.png

那么图上的Laplacian算子可以写成

image.png

标准化后得到

image.png

定义Laplacian算子的目的是为了找到Fourier变换的基

传统Fourier变换的基就是Laplacian算子的一组特征向量

image.png

类似的,在graph上,有

image.png

图拉普拉斯算子作用在由图节点信息构成的向量f ff上得到的结果等于图拉普拉斯矩阵和向量f ff的点积。

那么graph上的Fourier基就是L LL矩阵的n nn个特征向量U = [ u 1 … u n ] U=\left[u_{1} \dots u_{n}\right]U=[u

1

…u

n

],L LL可以分解成L = U Λ U T L=U \Lambda U^{T}L=UΛU

T

,其中,Λ \LambdaΛ是特征值组成的对角矩阵。

传统的Fourier变换与graph的Fourier变换区别


image.png

image.png

将f ( i ) f(i)f(i)看成是第i ii个点上的signal,用向量x = ( f ( 1 ) … f ( n ) ) ∈ R n x=(f(1) \ldots f(n)) \in \mathbb{R}^{n}x=(f(1)…f(n))∈R

n

来表示。矩阵形式的graph的Fourier变换为


image.png

image.png

类似的graph上的Fourier逆变换为

image.png

相关文章
|
4月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
PYTHON TENSORFLOW 2二维卷积神经网络CNN对图像物体识别混淆矩阵评估|数据分享
PYTHON TENSORFLOW 2二维卷积神经网络CNN对图像物体识别混淆矩阵评估|数据分享
|
1月前
|
Python
Python计算误码率,输入是0-1比特流矩阵和小数矩阵
本文提供了一个Python函数calculate_ber,用于计算两个NumPy矩阵表示的二进制信号和接收信号之间的误码率(BER),其中包括信号与接收信号的比较、误差计数以及BER的计算过程,并给出了具体的使用示例。
39 2
|
9天前
|
Python
Python 练习实例44 - Python 两个矩阵相加
Python 练习实例44 - Python 两个矩阵相加
|
1月前
|
算法 JavaScript Python
【Leetcode刷题Python】79. 单词搜索和剑指 Offer 12. 矩阵中的路径
Leetcode第79题"单词搜索"的Python解决方案,使用回溯算法在给定的二维字符网格中搜索单词,判断单词是否存在于网格中。
21 4
|
1月前
|
算法 Python
【Leetcode刷题Python】73. 矩阵置零
本文介绍了LeetCode第73题的解法,题目要求在给定矩阵中将所有值为0的元素所在的行和列全部置为0,并提供了一种原地算法的Python实现。
17 0
【Leetcode刷题Python】73. 矩阵置零
|
3月前
|
机器学习/深度学习 数据处理 索引
Python遍历矩阵的技巧与实践
Python遍历矩阵的技巧与实践
46 2
|
3月前
|
计算机视觉 Python
Python矩阵转灰度图技术解析
Python矩阵转灰度图技术解析
42 1
|
2月前
|
Python
打印9*9乘法表(递归或压缩矩阵)python
打印9*9乘法表(递归或压缩矩阵)python
|
4月前
|
机器学习/深度学习 数据采集 自然语言处理
图像分类模型评估之用python绘制混淆矩阵confusion_matrix_python confusion_matrix
图像分类模型评估之用python绘制混淆矩阵confusion_matrix_python confusion_matrix
|
4月前
|
机器学习/深度学习
python-随机森林后筛选最重要变量,模型准确率、随机森林混淆矩阵结果、基尼系数排序图
python-随机森林后筛选最重要变量,模型准确率、随机森林混淆矩阵结果、基尼系数排序图