图嵌入(拉普拉斯特征映射Laplacian Eigenmaps)

图嵌入(Graph embedding)的意义

Graph广泛存在于真实世界的多种场景中,即节点和边的集合。比如社交网络中人与人之间的联系,生物中蛋白质相互作用以及通信网络中的IP地址之间的通信等等。除此之外,我们最常见的一张图片、一个句子也可以抽象地看做是一个图模型的结构,图结构可以说是无处不在。通过对它们的分析,我们可以深入了解社会结构、语言和不同的交流模式,因此图一直是学界研究的热点。
图分析任务可以大致抽象为以下四类:
( a )节点分类:节点分类旨在基于其他标记的节点和网络拓扑来确定节点的标签(也称为顶点)
( b )链接预测:预测缺失链路或未来可能出现的链路的任务
( c )聚类:用于发现相似节点的子集,并将它们分组在一起
( d )可视化:有助于深入了解网络结构

为什么要使用图形嵌入

需要使用图形嵌入有以下几个原因:

1.机器学习图形是有限的。图由边和节点组成。这些网络关系只能使用数学、统计和机器学习的特定子集,而向量空间有更丰富的方法工具集。

2.嵌入是压缩的表示
邻接矩阵描述图中节点之间的连接。它是一个 ∣ V ∣ × ∣ V ∣ |V| \times|V| V×V矩阵 ( ∣ V ∣ |V| V是图中节点的个数)。矩阵中的每一列和每一行表示一个节点。矩阵中的非零值表示两个节点相连。但是使用邻接矩阵作为大型图的特征空间几乎是不可能的。

3.假设一个图有 M M M个节点和一个 M × M M \times M M×M的邻接矩阵。嵌入比邻接矩阵更实用,因为它们将节点属性打包到一个维度更小的向量中。向量运算比图形上的可比运算更简单、更快。

4.真实的图(网络)往往是高维、难以处理的。

20世纪初,研究人员发明了图形嵌入算法,作为降维技术的一部分

他们首先根据实际问题构造一个 D D D维空间中的图。然后将图的节点嵌入到 d ( d < < D ) d(d<<D) dd<<D维向量空间中。嵌入的思想是在向量空间中保持连接的节点彼此靠近。拉普拉斯特征映射(Laplacian Eigenmaps)和局部线性嵌入(Locally Linear Embedding ,LLE)是基于这一原理的算法的例子。然而,可伸缩性是这种方法的一个主要问题,它的时间复杂度是 O ( ∣ V ∣ 2 ) O (| V| ^2) O(V2)

自2010年以来,关于图嵌入的研究已经转移到解决网络稀疏性的可伸缩图嵌入技术上
例如,图分解(Graph Factorization)使用邻接矩阵的近似分解作为嵌入。LINE扩展了这种方法,并试图保持一阶和二阶近似。HOPE通过使用广义奇异值分解( SVD )分解相似性矩阵而不是邻接矩阵来扩展LINE以试图保持高阶邻近性。SDNE 使用自动编码器嵌入图形节点并捕捉高度非线性的依赖关系。这些新的可扩展方法的时间复杂度为 O ( ∣ E ∣ ) O( | E | ) O(E)

什么是图嵌入

通俗点讲:图嵌入(Graph Embedding,也叫Network Embedding)是一种将图数据(通常为高维稠密的矩阵)映射为低微稠密向量的过程,能够很好地解决图数据难以高效输入机器学习算法的问题。

  • 节点的分布式表示
  • 节点之间的相似性表示链接强度
  • 编码网络信息并生成节点表示

图嵌入是将属性图转换为向量或向量集。嵌入应该捕获图的拓扑结构顶点到顶点的关系以及关于图、子图和顶点的其他相关信息。更多的属性嵌入编码可以在以后的任务中获得更好的结果。我们可以将嵌入式大致分为两类:

  • 顶点嵌入: 每个顶点(节点)用其自身的向量表示进行编码。这种嵌入一般用于在顶点层次上执行可视化或预测。比如,在2D平面上显示顶点,或者基于顶点相似性预测新的连接。

  • 图嵌入: 用单个向量表示整个图。这种嵌入用于在图的层次上做出预测,或者想要比较或可视化整个图。例如,比较化学结构。

嵌入的挑战

如前所述,图嵌入的目标是发现高维图的低维向量表示,而获取图中每个节点的向量表示是十分困难的,并且具有几个挑战,这些挑战一直在推动本领域的研究:

  • 属性选择节点的“良好”向量表示应保留图的结构和单个节点之间的连接。第一个挑战是选择嵌入应该保留的图形属性。考虑到图中所定义的距离度量和属性过多,这种选择可能很困难,性能可能取决于实际的应用场景。它们需要表示图拓扑、节点连接和节点邻居。预测或可视化的性能取决于嵌入的质量。

  • 可扩展性:大多数真实网络都很大,包含大量节点和边。嵌入方法应具有可扩展性,能够处理大型图。定义一个可扩展的模型具有挑战性,尤其是当该模型旨在保持网络的全局属性时。好的嵌入方法需要在大型图上高效

  • 嵌入的维数实际嵌入时很难找到表示的最佳维数
    较高的维数可能会提高重建精度,但具有较高的时间和空间复杂性
    较低的维度虽然时间、空间复杂度低,但无疑会损失很多图中原有的信息。用户需要根据需求做出权衡。在一些文章中,他们通常报告说嵌入大小在128到256之间对于大多数任务来说已经足够了。在Word2vec方法中,他们选择了嵌入长度300。

图嵌入的方法

在过去的十年里,在图形嵌入领域已经有了大量的研究,重点是设计新的嵌入算法。发展到现在,大体上可以将这些嵌入方法分为三大类
( 1 )基于因子分解的方法
( 2 )基于随机游走的方法
( 3 )基于深度学习的方法。
在这里插入图片描述
这里主要介绍基于因子分解的方法的Laplacian Eigenmaps (拉普拉斯的特征映射)
在介绍之前先说明一下背景知识

谱聚类

谱聚类(spectral clustering)是广泛使用的聚类算法,比起传统的K-Means算法,谱聚类对数据分布的适应性更强,聚类效果也很优秀,同时聚类的计算量也小很多,更加难能可贵的是实现起来也不复杂。在处理实际的聚类问题时,个人认为谱聚类是应该首先考虑的几种算法之一。下面我们就对谱聚类的算法原理做一个总结。

1. 谱聚类概述

谱聚类是从图论中演化出来的算法,后来在聚类中得到了广泛的应用。它的主要思想是把所有的数据看做空间中的点,这些点之间可以用边连接起来。距离较远的两个点之间的边权重值较低,而距离较近的两个点之间的边权重值较高,通过对所有数据点组成的图进行切图,让切图后不同的子图间边权重和尽可能的低,而子图内的边权重和尽可能的高,从而达到聚类的目的。

乍一看,这个算法原理的确简单,但是要完全理解这个算法的话,需要对图论中的无向图,线性代数和矩阵分析都有一定的了解。下面我们就从这些需要的基础知识开始,一步步学习谱聚类。

2. 谱聚类基础之一:无向权重图

由于谱聚类是基于图论的,因此我们首先温习下图的概念。对于一个图 G G G,我们一般用点的集合 V V V和边的集合 E E E来描述。即为 G ( V , E ) G(V,E) G(V,E)
其中 V V V即为我们数据集里面所有的点 ( v 1 , v 2 , . . . , v n ) (v_1,v_2,...,v_n) (v1,v2,...,vn)。对于 V V V中的任意两个点,可以有边连接,也可以没有边连接。定义权重 w i j w_{ij} wij为点 v i v_i vi和点 v j v_j vj之间的权重。由于是无向图,所以 w i j = w j i w_{ij}=w_{ji} wij=wji

对于有边连接的两个点 v i v_i vi v j v_j vj w i j > 0 w_{ij}>0 wij>0,对于没有边连接的两个点 v i v_i vi v j v_j vj w i j > 0 w_{ij}>0 wij>0。对于图中的任意一个点 v i v_i vi,它的度 d i d_i di定义为和它相连的所有边的权重之和,即

d i = ∑ j = 1 n w i j d_i = \sum_{j=1}^n w_{ij} di=j=1nwij

利用每个点度的定义,我们可以得到一个 n × n n\times n n×n的度矩阵 D D D,它是一个对角矩阵,只有主对角线有值,对应第i行的第 i i i个点的度数,定义如下:
D = [ d i ⋯ ⋯ ⋯ d 2 ⋯ ⋮ ⋮ ⋱ ⋯ ⋯ d n ] D= \begin{bmatrix} d_i & \cdots & \cdots \\ \cdots & d_2 & \cdots \\ \vdots & \vdots & \ddots \\ \cdots & \cdots & d_n \end{bmatrix} D=did2dn
利用所有点之间的权重值,我们可以得到图的邻接矩阵 W W W,它也是一个 n × n n \times n n×n的矩阵。
i i i行的第 j j j个值对应我们的权重 w i j w_{ij} wij

除此之外,对于点集 V V V的的一个子集 A ⊂ V A⊂V AV,我们定义:
∣ A ∣ : = 子 集 A 中 点 的 个 数 |A|:=子集A中点的个数 A:=A
v o l ( A ) : = ∑ i ∈ A d i vol(A):= \sum_{i \in A} d_i vol(A):=iAdi

3. 谱聚类基础之二:相似矩阵

在上一节我们讲到了邻接矩阵 W W W,它是由任意两点之间的权重值 w i j w_{ij} wij组成的矩阵。通常我们可以自己输入权重,但是在谱聚类中,我们只有数据点的定义,并没有直接给出这个邻接矩阵,那么怎么得到这个邻接矩阵呢?

基本思想是,距离较远的两个点之间的边权重值较低,而距离较近的两个点之间的边权重值较高,不过这仅仅是定性,我们需要定量的权重值。一般来说,我们可以通过样本点距离度量的相似矩阵 S S S来获得邻接矩阵 W W W

构建邻接矩阵W的方法有三类。ϵ-邻近法,K邻近法和全连接法。

对于ϵ-邻近法,它设置了一个距离阈值ϵ,然后用欧式距离sij度量任意两点xi和xj的距离。即相似矩阵的 s i j = ∣ ∣ x i − x j ∣ ∣ 2 2 s_ij=||x_i−x_j||_{2}^2 sij=xixj22, 然后根据 s i j s_{ij} sij和ϵ的大小关系,来定义邻接矩阵 W W W如下:

w i j = { 0 s i j > ϵ ϵ s i j ≤ ϵ w_{ij} = \begin{cases} 0 & s_{ij} \gt ϵ \\ ϵ & s_{ij} \leq ϵ \end{cases} wij={0ϵsij>ϵsijϵ
从上式可见,两点间的权重要不就是ϵ,要不就是0,没有其他的信息了。距离远近度量很不精确,因此在实际应用中,我们很少使用ϵ-邻近法。

第二种定义邻接矩阵 W W W的方法是 K K K邻近法,利用 K N N KNN KNN算法遍历所有的样本点,取每个样本最近的k个点作为近邻,只有和样本距离最近的k个点之间的 w i j > 0 w_{ij} \gt 0 wij>0。但是这种方法会造成重构之后的邻接矩阵 W W W非对称,我们后面的算法需要对称邻接矩阵。为了解决这种问题,一般采取下面两种方法之一:
第一种K邻近法是只要一个点在另一个点的K近邻中,则保留 s i j s_{ij} sij

w i j = w j i = { 0 x i ∉ K N N ( x j ) a n d x j ∉ K N N ( x i ) e x p ( − ∣ ∣ x i − x j ∣ ∣ 2 2 2 σ 2 x i ∈ K N N ( x j ) o r x j ∈ K N N ( x i ) w_{ij}= w_{ji} = \begin{cases} 0 & x_i \not\in KNN(x_j) & and & x_j \not\in KNN(x_i) \\ exp(-\frac{||x_i - x_ j ||_{2}^2} {2 \sigma^2} & x_i \in KNN(x_j) & or & x_j \in KNN(x_i) \end{cases} wij=wji={0exp(2σ2xixj22xiKNN(xj)xiKNN(xj)andorxjKNN(xi)xjKNN(xi)
第二种K邻近法是必须两个点互为K近邻中,才能保留 s i j s_{ij} sij
w i j = w j i = { 0 x i ∉ K N N ( x j ) o r x j ∉ K N N ( x i ) e x p ( − ∣ ∣ x i − x j ∣ ∣ 2 2 2 σ 2 ) x i ∈ K N N ( x j ) a n d x j ∈ K N N ( x i ) w_{ij}= w_{ji} = \begin{cases} 0 & x_i \not\in KNN(x_j) & or & x_j \not\in KNN(x_i) \\ exp(-\frac{||x_i - x_ j ||_{2}^2} {2 \sigma^2}) & x_i \in KNN(x_j) & and & x_j \in KNN(x_i) \end{cases} wij=wji={0exp(2σ2xixj22)xiKNN(xj)xiKNN(xj)orandxjKNN(xi)xjKNN(xi)
第三种定义邻接矩阵 W W W的方法是全连接法,相比前两种方法,第三种方法所有的点之间的权重值都大于0,因此称之为全连接法。可以选择不同的核函数来定义边权重,常用的有多项式核函数,高斯核函数和Sigmoid核函数。最常用的是高斯核函数RBF,此时相似矩阵和邻接矩阵相同:
w i j = s i j = e x p ( − ∣ ∣ x i − x j ∣ ∣ 2 2 2 σ 2 ) w_{ij}=s_{ij}= exp(-\frac{||x_i - x_ j ||_{2}^2} {2 \sigma^2}) wij=sij=exp(2σ2xixj22)
在实际的应用中,使用第三种全连接法来建立邻接矩阵是最普遍的,而在全连接法中使用高斯径向核RBF是最普遍的。

4. 谱聚类基础之三:拉普拉斯矩阵

单独把拉普拉斯矩阵(Graph Laplacians)拿出来介绍是因为后面的算法和这个矩阵的性质息息相关。它的定义很简单,拉普拉斯矩阵 L = D − W L=D−W L=DW D D D即为我们第二节讲的度矩阵,它是一个对角矩阵。而 W W W即为我们第二节讲的邻接矩阵,它可以由我们第三节的方法构建出。

拉普拉斯矩阵有一些很好的性质如下:

1)拉普拉斯矩阵是对称矩阵,这可以由 D D D W W W都是对称矩阵而得。

2)由于拉普拉斯矩阵是对称矩阵,则它的所有的特征值都是实数。

3)对于任意的向量 f f f,我们有
f T L f = 1 2 ∑ i , j = 1 n w i j ( f i − f j ) 2 f^{T} L f = \frac{1}{2} \sum_{i,j=1}^{n} w_{ij}(f_i - f_j)^2 fTLf=21i,j=1nwij(fifj)2
这个利用拉普拉斯矩阵的定义很容易得到如下:

f T L f = f T D f − f T W f = ∑ i = 1 n d i f i 2 − ∑ i , j = 1 n w i j f i f j = 1 2 ( ∑ i = 1 n d i f i 2 − 2 ∑ i , j = 1 n w i j f i f j + ∑ j = 1 n d j f j 2 ) 由 于 : d i = ∑ j = 1 n w i j = 1 2 ( ∑ i , j = 1 n w i j f i 2 − 2 ∑ i , j = 1 n w i j f i f j + ∑ j , i = 1 n w i j f j 2 ) = 1 2 ∑ i , j = 1 n w i j ( f i − f j ) 2 \begin{aligned} f^{T}Lf & = f^{T}Df − f^{T}Wf \\ &= \sum_{i=1}^n d_if_{i}^2 - \sum_{i,j=1}^n w_{ij}f_if_j \\ &= \frac{1}{2} ( \sum_{i=1}^n d_if_{i}^2 - 2\sum_{i,j=1}^n w_{ij}f_if_j + \sum_{j=1}^n d_jf_{j}^2) \\ 由于:d_i = \sum_{j = 1}^{n} w_{ij} \\ &= \frac{1}{2} ( \sum_{i,j=1}^n w_{ij}f_{i}^2 - 2\sum_{i,j=1}^n w_{ij}f_if_j + \sum_{j,i=1}^n w_{ij}f_{j}^2) \\ &=\frac{1}{2} \sum_{i,j=1}^{n} w_{ij}(f_i - f_j)^2 \end{aligned} fTLfdi=j=1nwij=fTDffTWf=i=1ndifi2i,j=1nwijfifj=21(i=1ndifi22i,j=1nwijfifj+j=1ndjfj2)=21(i,j=1nwijfi22i,j=1nwijfifj+j,i=1nwijfj2)=21i,j=1nwij(fifj)2
4) 拉普拉斯矩阵是半正定的,且对应的n个实数特征值都大于等于0,即 0 = λ 1 ≤ λ 2 ≤ . . . ≤ λ n 0=λ_1≤λ_2≤...≤λ_n 0=λ1λ2...λn, 且最小的特征值为0,这个由性质3很容易得出。

5. 谱聚类基础之四:无向图切图

对于无向图G的切图,我们的目标是将图 G ( V , E ) G(V,E) G(V,E)切成相互没有连接的k个子图,每个子图点的集合为: A 1 , A 2 , . . , A k A_1,A_2,..,A_k A1,A2,..,Ak,它们满足 A i ∩ A j = ∅ A_i∩A_j=∅ AiAj=,且 A 1 ∪ A 2 ∪ . . . ∪ A k = V A_1∪A_2∪...∪A_k=V A1A2...Ak=V.

对于任意两个子图点的集合 A , B ⊂ V A,B⊂V A,BV A ∩ B = ∅ A∩B=∅ AB= ,

我 们 定 义 A 和 B 之 间 的 切 图 权 重 为 : W ( A , B ) = ∑ i ∈ A , j ∈ B w i j 我们定义A和B之间的切图权重为:W(A,B)=\sum_{i \in A, j \in B} w_{ij} ABW(A,B)=iA,jBwij
那么对于我们 k k k个子图点的集合: A 1 , A 2 , . ⋯   , A k A_1,A_2,. \cdots,A_k A1,A2,.,Ak,我们定义切图cut为:

c u t ( A 1 , A 2 , . ⋯   , A k ) = 1 2 ∑ i = 1 k W ( A i , A i ‾ ) cut(A_1,A_2,. \cdots,A_k)=\frac{1}{2} \sum_{i=1}^k W(A_i, \overline{A_i}) cut(A1,A2,.,Ak)=21i=1kW(Ai,Ai)
其中 A i ‾ \overline{A_i} Ai A i A_i Ai的补集,意为除 A i A_i Ai子集外其他 V V V的子集的并集。

那么切图可以让子图内的点权重高,子图间的点权重低呢?一个自然的想法就是最小化 c u t ( A 1 , A 2 , . ⋯   , A k ) cut(A_1,A_2,. \cdots,A_k) cut(A1,A2,.,Ak),但是最小化这个只是达到了子图间的点权重低的效果

如图:
在这里插入图片描述
我们选择一个权重最小的边缘的点,比如 C C C H H H之间进行 c u t cut cut,这样可以最小化 c u t ( A 1 , A 2 , . ⋯   , A k ) cut(A_1,A_2,. \cdots,A_k) cut(A1,A2,.,Ak), 但是却不是最优的切图(明显在单独的左下角子图中,只有一个点,必然子图内的点权重就小),如何避免这种切图,并且找到类似图中"Best Cut"这样的最优切图呢?我们下一节就来看看谱聚类使用的切图方法。

6. 谱聚类之切图聚类

为了避免最小切图导致的切图效果不佳,我们需要对每个子图的规模做出限定,一般来说,有两种切图方式,第一种是RatioCut,第二种是Ncut。下面我们分别加以介绍。

6.1 RatioCut切图
在数学模型中能表示:两个之间相反变化(一个变大一个变小)同时还能达到同样的效果的,其中一个就是分数表示形式
a b \frac{a}{b} ba
当a变小,b变大的时候,整个数学形式是在变小

RatioCut切图为了避免第五节的最小切图,对每个切图,不光考虑最小化 c u t ( A 1 , A 2 , . ⋯   , A k ) cut(A_1,A_2,. \cdots,A_k) cut(A1,A2,.,Ak),它还同时考虑最大化每个子图点的个数。 即:
R a t i o C u t ( A 1 , A 2 , . ⋯   , A k ) = 1 2 ∑ i = 1 k W ( A i , A i ‾ ) ∣ A i ∣ RatioCut(A_1,A_2,. \cdots,A_k) = \frac{1}{2} \sum_{i=1}^k \frac{W(A_i, \overline{A_i})}{|A_i|} RatioCut(A1,A2,.,Ak)=21i=1kAiW(Ai,Ai)
那么怎么最小化这个RatioCut函数呢?牛人们发现,RatioCut函数可以通过如下方式表示。

我们引入指示向量 h j ∈ { h 1 , h 2 , . . h k } , j = 1 , 2 , . . . k , h_j \in \{h_1,h_2,..h_k\}, j=1,2,...k, hj{h1,h2,..hk},j=1,2,...k,对于任意一个向量 h j h_j hj, 它是一个n维向量(n为样本数),我们定义 h i j h_{ij} hij为:
h i j = { 0 x i ∉ A j 1 ∣ A j ∣ x i ∈ A j h_{ij}= \begin{cases} 0 & x_i \not\in A_j \\ \frac{1} {\sqrt{|A_j|}} & x_i \in A_j \end{cases} hij={0Aj 1xiAjxiAj

那么对于 h i T L h i h_{i}^{T} Lh_i hiTLhi就有:
h i T L h i = 1 2 ∑ m = 1 ∑ n = 1 w m n ( f i m − f j n ) 2 = 1 2 ∑ m ∈ A i , n ∉ A i w m n ( 1 ∣ A i ∣ − 0 ) 2 + ∑ m ∉ A i , n ∈ A i w m n ( 0 − 1 ∣ A i ∣ ) 2 = 1 2 ∑ m ∈ A i , n ∉ A i w m n 1 ∣ A i ∣ + ∑ m ∉ A i , n ∈ A i w m n 1 ∣ A i ∣ = 1 2 ( c u t ( A i , A i ‾ ) 1 ∣ A i ∣ + c u t ( A i ‾ , A i ) 1 ∣ A i ∣ ) = c u t ( A i , A i ‾ ) ∣ A i ∣ \begin{aligned} h_{i}^{T} Lh_i & = \frac{1}{2} \sum_{m=1}\sum_{n=1} w_{mn}(f_{im}- f_{jn})^2 \\ &= \frac{1}{2} \sum_{m\in A_i,n \not\in A_i} w_{mn}(\frac{1} {\sqrt{|A_i|}} - 0)^2 + \sum_{m \not\in A_i,n \in A_i} w_{mn}( 0 - \frac{1} {\sqrt{|A_i|}} )^2\\ & = \frac{1}{2} \sum_{m\in A_i,n \not\in A_i} w_{mn}\frac{1} {|A_i|} + \sum_{m \not\in A_i,n \in A_i} w_{mn}\frac{1} {\sqrt{|A_i|}}\\ & = \frac{1}{2} (cut(A_i, \overline{A_i})\frac{1} {|A_i|} +cut(\overline{A_i},A_i)\frac{1} {|A_i|}) \\ & = \frac{cut(A_i, \overline{A_i})}{|A_i|} \end{aligned} hiTLhi=21m=1n=1wmn(fimfjn)2=21mAi,nAiwmn(Ai 10)2+mAi,nAiwmn(0Ai 1)2=21mAi,nAiwmnAi1+mAi,nAiwmnAi 1=21(cut(Ai,Ai)Ai1+cut(Ai,Ai)Ai1)=Aicut(Ai,Ai)
上述第(1)式用了上面第四节的拉普拉斯矩阵的性质3. 第二式用到了指示向量的定义。可以看出,对于某一个子图i,它的 R a t i o C u t RatioCut RatioCut对应于 h i T L h i h_{i}^{T}Lh_i hiTLhi,那么我们的k个子图呢?对应的 R a t i o C u t RatioCut RatioCut函数表达式为:
R a t i o C u t ( A 1 , A 2 , ⋯   , A K ) = ∑ i = 1 k W ( A i , A i ‾ ) ∣ A i ∣ = ∑ i = 1 k h i T L h i = ∑ i = 1 k ( H T L H ) i i = t r ( H T L H ) RatioCut(A_1,A_2, \cdots, A_K) = \sum_{i=1}^k \frac{W(A_i, \overline{A_i})}{|A_i|} \\ = \sum_{i=1}^{k}h_{i}^{T} Lh_i = \sum_{i=1}^{k}(H^{T}LH)_{ii} = tr(H^{T}LH) RatioCut(A1,A2,,AK)=i=1kAiW(Ai,Ai)=i=1khiTLhi=i=1k(HTLH)ii=tr(HTLH)
其中 t r ( H T L H ) tr(H^{T}LH) tr(HTLH)为矩阵的迹。也就是说,我们的 R a t i o C u t RatioCut RatioCut切图,实际上就是最小化我们的 t r ( H T L H ) tr(H^{T}LH) tr(HTLH)。注意到 H T H = I H^TH=I HTH=I,则我们的切图优化目标为:
a r g m i n t r ( H T L H ) s . t . H T H = I ⏟ H \underbrace{arg \quad min \quad tr(H^{T}LH) \quad \quad s.t.H^TH = I }\\ H argmintr(HTLH)s.t.HTH=IH
注意到我们H矩阵里面的每一个指示向量都是n维的,向量中每个变量的取值为0或者 1 ∣ A j ∣ \frac{1} {\sqrt{|A_j|}} Aj 1,就有 2 n 2^n 2n种取值,有k个子图的话就有k个指示向量,共有 k 2 n k2^n k2n H H H,因此找到满足上面优化目标的H是一个NP难的问题。那么是不是就没有办法了呢?

注意观察 t r ( H T L H ) tr(H^TLH) tr(HTLH)中每一个优化子目标 h i T L h i h^T_iLh_i hiTLhi,其中 h h h是单位正交基, L L L为对称矩阵,此时 h i T L h i h^T_iLh_i hiTLhi的最大值为L的最大特征值,最小值是 L L L的最小特征值。如果你对主成分分析PCA很熟悉的话,这里很好理解。在 P C A PCA PCA中,我们的目标是找到协方差矩阵(对应此处的拉普拉斯矩阵L)的最大的特征值,而在我们的谱聚类中,我们的目标是找到目标的最小的特征值,得到对应的特征向量,此时对应二分切图效果最佳。也就是说,我们这里要用到维度规约的思想来近似去解决这个NP难的问题。

对于 h i T L h i h^T_iLh_i hiTLhi,我们的目标是找到最小的L的特征值,而对于 t r ( H T L H ) = ∑ i = 1 k h i T L h i tr(H^TLH)=\sum_{i=1}^k h^T_iLh_i tr(HTLH)=i=1khiTLhi,则我们的目标就是找到k个最小的特征值,一般来说,k远远小于n,也就是说,此时我们进行了维度规约,将维度从n降到了k,从而近似可以解决这个NP难的问题。

通过找到L的最小的k个特征值,可以得到对应的k个特征向量,这k个特征向量组成一个 n × k n \times k n×k维度的矩阵,即为我们的 H H H。一般需要对 H H H矩阵按行做标准化,即:
             H i j ∗ = h i j ( ∑ t = 1 k h i t 2 ) 1 2             H_{ij}^{*} = \frac{h_{ij}}{ (\sum_{t=1}^ {k} h_{it} ^2)^{ \frac{1}{2}} }          Hij=(t=1khit2)21hij    
    
由于我们在使用维度规约的时候损失了少量信息,导致得到的优化后的指示向量h对应的H现在不能完全指示各样本的归属,因此一般在得到 n × k n \times k n×k维度的矩阵 H H H后还需要对每一行进行一次传统的聚类,比如使用 K − M e a n s K-Means KMeans聚类.

6.2 PCA(主成分析)以及KPCA(核主成分分析)数学原理
PCA(Principal Component Analysis)是一种常用的数据分析方法。PCA通过线性变换将原始数据变换为一组各维度线性无关的表示,可用于提取数据的主要特征分量,常用于高维数据的降维。网上关于PCA的文章有很多,但是大多数只描述了PCA的分析过程,而没有讲述其中的原理。这篇文章的目的是介绍PCA的基本数学原理,帮助读者了解PCA的工作机制是什么。

当然我并不打算把文章写成纯数学文章,而是希望用直观和易懂的方式叙述PCA的数学原理,所以整个文章不会引入严格的数学推导。希望读者在看完这篇文章后能更好的明白PCA的工作原理。

数据的向量表示及降维问题
一般情况下,在数据挖掘和机器学习中,数据被表示为向量。例如某个淘宝店2012年全年的流量及交易情况可以看成一组记录的集合,其中每一天的数据是一条记录,格式如下:

(日期, 浏览量, 访客数, 下单数, 成交数, 成交金额)

其中“日期”是一个记录标志而非度量值,而数据挖掘关心的大多是度量值,因此如果我们忽略日期这个字段后,我们得到一组记录,每条记录可以被表示为一个五维向量,其中一条看起来大约是这个样子:
( 500 , 240 , 25 , 13 , 2312.15 ) T (500,240,25,13,2312.15)^T (500,240,25,13,2312.15)T
注意这里我用了转置,因为习惯上使用列向量表示一条记录(后面会看到原因),本文后面也会遵循这个准则。不过为了方便有时我会省略转置符号,但我们说到向量默认都是指列向量。

我们当然可以对这一组五维向量进行分析和挖掘,不过我们知道,很多机器学习算法的复杂度和数据的维数有着密切关系,甚至与维数呈指数级关联。当然,这里区区五维的数据,也许还无所谓,但是实际机器学习中处理成千上万甚至几十万维的情况也并不罕见,在这种情况下,机器学习的资源消耗是不可接受的,因此我们必须对数据进行降维。

降维当然意味着信息的丢失,不过鉴于实际数据本身常常存在的相关性,我们可以想办法在降维的同时将信息的损失尽量降低。

举个例子,假如某学籍数据有两列M和F,其中M列的取值是如何此学生为男性取值1,为女性取值0;而F列是学生为女性取值1,男性取值0。此时如果我们统计全部学籍数据,会发现对于任何一条记录来说,当M为1时F必定为0,反之当M为0时F必定为1。在这种情况下,我们将M或F去掉实际上没有任何信息的损失,因为只要保留一列就可以完全还原另一列。

当然上面是一个极端的情况,在现实中也许不会出现,不过类似的情况还是很常见的。例如上面淘宝店铺的数据,从经验我们可以知道,“浏览量”和“访客数”往往具有较强的相关关系,而“下单数”和“成交数”也具有较强的相关关系。这里我们非正式的使用“相关关系”这个词,可以直观理解为“当某一天这个店铺的浏览量较高(或较低)时,我们应该很大程度上认为这天的访客数也较高(或较低)”。后面的章节中我们会给出相关性的严格数学定义。

这种情况表明,如果我们删除浏览量或访客数其中一个指标,我们应该期待并不会丢失太多信息。因此我们可以删除一个,以降低机器学习算法的复杂度。

上面给出的是降维的朴素思想描述,可以有助于直观理解降维的动机和可行性,但并不具有操作指导意义。例如,我们到底删除哪一列损失的信息才最小?亦或根本不是单纯删除几列,而是通过某些变换将原始数据变为更少的列但又使得丢失的信息最小?到底如何度量丢失信息的多少?如何根据原始数据决定具体的降维操作步骤?

要回答上面的问题,就要对降维问题进行数学化和形式化的讨论。而PCA是一种具有严格数学基础并且已被广泛采用的降维方法。下面我不会直接描述PCA,而是通过逐步分析问题,让我们一起重新“发明”一遍PCA。

向量的表示及基变换

既然我们面对的数据被抽象为一组向量,那么下面有必要研究一些向量的数学性质。而这些数学性质将成为后续导出PCA的理论基础。

内积与投影
下面先来看一个高中就学过的向量运算:内积。两个维数相同的向量的内积被定义为:
( a 1 , a 2 , ⋯ , a n ) T ⋅ ( b 1 , b 2 , ⋯ , b n ) T = a 1 b 1 + a 2 b 2 + ⋯ + a n b n (a1,a2,⋯,an)^T⋅(b1,b2,⋯,bn)^T=a_1b_1+a_2b_2+⋯+a_nb_n (a1,a2,,an)T(b1,b2,,bn)T=a1b1+a2b2++anbn
内积运算将两个向量映射为一个实数。其计算方式非常容易理解,但是其意义并不明显。下面我们分析内积的几何意义。假设A和B是两个n维向量,我们知道n维向量可以等价表示为n维空间中的一条从原点发射的有向线段,为了简单起见我们假设A和B均为二维向量,则 A = ( x 1 , y 1 ) A=(x_1,y_1) A=(x1,y1) B = ( x 2 , y 2 ) B=(x_2,y_2) B=(x2,y2)。则在二维平面上A和B可以用两条发自原点的有向线段表示,见下图:

在这里插入图片描述
好,现在我们从A点向B所在直线引一条垂线。我们知道垂线与B的交点叫做A在B上的投影,再设A与B的夹角是a,则投影的矢量长度为 ∣ A ∣ c o s ( a ) |A|cos(a) Acos(a),其中 ∣ A ∣ = x 1 2 + y 1 2 |A|= \sqrt{x^{2}_{1}+y^2_1} A=x12+y12 是向量A的模,也就是A线段的标量长度。

注意这里我们专门区分了矢量长度和标量长度,标量长度总是大于等于0,值就是线段的长度;而矢量长度可能为负,其绝对值是线段长度,而符号取决于其方向与标准方向相同或相反。

到这里还是看不出内积和这东西有什么关系,不过如果我们将内积表示为另一种我们熟悉的形式:
A ⋅ B = ∣ A ∣ ∣ B ∣ c o s ( a ) A \cdot B = |A||B|cos(a) AB=ABcos(a)

现在事情似乎是有点眉目了:A与B的内积等于A到B的投影长度乘以B的模。再进一步,如果我们假设B的模为1,即让 ∣ B ∣ = 1 |B|=1 B=1,那么就变成了:
A ⋅ B = ∣ A ∣ c o s ( a ) A \cdot B = |A|cos(a) AB=Acos(a)


下面我们继续在二维空间内讨论向量。上文说过,一个二维向量可以对应二维笛卡尔直角坐标系中从原点出发的一个有向线段。例如下面这个向量:

在这里插入图片描述
在代数表示方面,我们经常用线段终点的点坐标表示向量,例如上面的向量可以表示为(3,2),这是我们再熟悉不过的向量表示。

不过我们常常忽略,只有一个(3,2)本身是不能够精确表示一个向量的。我们仔细看一下,这里的3实际表示的是向量在x轴上的投影值是3,在y轴上的投影值是2。也就是说我们其实隐式引入了一个定义:以x轴和y轴上正方向长度为1的向量为标准。那么一个向量(3,2)实际是说在x轴投影为3而y轴的投影为2。注意投影是一个矢量,所以可以为负。

更正式的说,向量(x,y)实际上表示线性组合:
x ( 1 , 0 ) T + y ( 0 , 1 ) T x(1,0)^T+y(0,1)^T x(1,0)T+y(0,1)T

不难证明所有二维向量都可以表示为这样的线性组合。此处 ( 1 , 0 ) (1,0) (1,0)和$(0,1)4叫做二维空间中的一组基。

在这里插入图片描述
所以,要准确描述向量,首先要确定一组基,然后给出在基所在的各个直线上的投影值,就可以了。只不过我们经常省略第一步,而默认以 ( 1 , 0 ) (1,0) (1,0) ( 0 , 1 ) (0,1) (0,1)为基。

我们之所以默认选择 ( 1 , 0 ) (1,0) (1,0) ( 0 , 1 ) (0,1) (0,1)为基,当然是比较方便,因为它们分别是x和y轴正方向上的单位向量,因此就使得二维平面上点坐标和向量一一对应,非常方便。但实际上任何两个线性无关的二维向量都可以成为一组基,所谓线性无关在二维平面内可以直观认为是两个不在一条直线上的向量。

例如, ( 1 , 1 ) (1,1) (1,1) ( − 1 , 1 ) (-1,1) (1,1)也可以成为一组基。一般来说,我们希望基的模是1,因为从内积的意义可以看到,如果基的模是1,那么就可以方便的用向量点乘基而直接获得其在新基上的坐标了!实际上,对应任何一个向量我们总可以找到其同方向上模为1的向量,只要让两个分量分别除以模就好了。例如,上面的基可以变为 ( 1 2 , − 1 2 ) 和 ( − 1 2 , 1 2 ) (\frac{1}{ \sqrt{2}},-\frac{1}{ \sqrt{2}}) 和(-\frac{1}{ \sqrt{2}},\frac{1}{ \sqrt{2}}) (2 1,2 1)(2 1,2 1)

现在,我们想获得 ( 3 , 2 ) (3,2) (3,2)在新基上的坐标,即在两个方向上的投影矢量值,那么根据内积的几何意义,我们只要分别计算 ( 3 , 2 ) (3,2) (3,2)和两个基的内积,不难得到新的坐标为 ( 5 2 , − 1 2 ) (\frac{5}{ \sqrt{2}},-\frac{1}{ \sqrt{2}}) (2 5,2 1)。下图给出了新的基以及 ( 3 , 2 ) (3,2) (3,2)在新基上坐标值的示意图:

在这里插入图片描述

另外这里要注意的是,我们列举的例子中基是正交的(即内积为0,或直观说相互垂直),但可以成为一组基的唯一要求就是线性无关,非正交的基也是可以的。不过因为正交基有较好的性质,所以一般使用的基都是正交的。

基变换的矩阵表示

下面我们找一种简便的方式来表示基变换。还是拿上面的例子,想一下,将 ( 3 , 2 ) (3,2) (3,2)变换为新基上的坐标,就是用 ( 3 , 2 ) (3,2) (3,2)与第一个基做内积运算,作为第一个新的坐标分量,然后用 ( 3 , 2 ) (3,2) (3,2)与第二个基做内积运算,作为第二个新坐标的分量。实际上,我们可以用矩阵相乘的形式简洁的表示这个变换:
( 1 2 1 2 − 1 2 1 2 ) ( 3 2 ) = ( 5 2 − 1 2 ) \begin{pmatrix} \frac{1}{ \sqrt{2}} & \frac{1}{ \sqrt{2}} \\ -\frac{1}{ \sqrt{2}} & \frac{1}{ \sqrt{2}} \end{pmatrix} \begin{pmatrix} 3\\ 2 \end{pmatrix} = \begin{pmatrix} \frac{5}{ \sqrt{2}} \\ -\frac{1}{ \sqrt{2}} \end{pmatrix} (2 12 12 12 1)(32)=(2 52 1)

太漂亮了!其中矩阵的两行分别为两个基,乘以原向量,其结果刚好为新基的坐标。可以稍微推广一下,如果我们有m个二维向量,只要将二维向量按列排成一个两行m列矩阵,然后用“基矩阵”乘以这个矩阵,就得到了所有这些向量在新基下的值。例如 ( 1 , 1 ) (1,1) (1,1) ( 2 , 2 ) (2,2) (2,2) ( 3 , 3 ) (3,3) (3,3),想变换到刚才那组基上,则可以这样表示:
( 1 2 1 2 − 1 2 1 2 ) ( 1 2 3 1 2 3 ) = ( 2 2 4 2 6 2 0 0 0 ) \begin{pmatrix} \frac{1}{ \sqrt{2}} & \frac{1}{ \sqrt{2}} \\ -\frac{1}{ \sqrt{2}} & \frac{1}{ \sqrt{2}} \end{pmatrix} \begin{pmatrix} 1 & 2 & 3\\ 1 & 2 & 3 \end{pmatrix} = \begin{pmatrix} \frac{2}{ \sqrt{2}} & \frac{4}{ \sqrt{2}} & \frac{6}{ \sqrt{2}}\\ 0 & 0 & 0 \end{pmatrix} (2 12 12 12 1)(112233)=(2 202 402 60)

于是一组向量的基变换被干净的表示为矩阵的相乘。

一般的,如果我们有M个N维向量,想将其变换为由R个N维向量表示的新空间中,那么首先将R个基按行组成矩阵A,然后将向量按列组成矩阵B,那么两矩阵的乘积AB就是变换结果,其中AB的第m列为A中第m列变换后的结果

数学表示为:

( p 1 p 2 ⋮ p R ) ( a 1 a 2 ⋯ a M ) = ( p 1 a 1 ⋯ p 1 a M ⋮ ⋱ ⋮ p R a 1 ⋯ p R a M ) \begin{pmatrix} p_1 \\ p_2\\ \vdots \\ p_R \end{pmatrix} \begin{pmatrix} a_1 & a_2 & \cdots &a_M\\ \end{pmatrix} = \begin{pmatrix} p_1a_1 & \cdots & p_1a_M\\ \vdots & \ddots & \vdots \\ p_Ra_1 & \cdots & p_Ra_M \end{pmatrix} p1p2pR(a1a2aM)=p1a1pRa1p1aMpRaM
其中 p i p_i pi是一个行向量,表示第 i i i个基, a j a_j aj是一个列向量,表示第 j j j个原始数据记录。

特别要注意的是,这里R可以小于N,而R决定了变换后数据的维数。也就是说,我们可以将一N维数据变换到更低维度的空间中去,变换后的维度取决于基的数量。因此这种矩阵相乘的表示也可以表示降维变换。

最后,上述分析同时给矩阵相乘找到了一种物理解释:两个矩阵相乘的意义是将右边矩阵中的每一列列向量变换到左边矩阵中每一行行向量为基所表示的空间中去。更抽象的说,一个矩阵可以表示一种线性变换。很多同学在学线性代数时对矩阵相乘的方法感到奇怪,但是如果明白了矩阵相乘的物理意义,其合理性就一目了然了。

协方差矩阵及优化目标

上面我们讨论了选择不同的基可以对同样一组数据给出不同的表示,而且如果基的数量少于向量本身的维数,则可以达到降维的效果。但是我们还没有回答一个最最关键的问题:如何选择基才是最优的。或者说,如果我们有一组N维向量,现在要将其降到K维(K小于N),那么我们应该如何选择K个基才能最大程度保留原有的信息?

要完全数学化这个问题非常繁杂,这里我们用一种非形式化的直观方法来看这个问题。

为了避免过于抽象的讨论,我们仍以一个具体的例子展开。假设我们的数据由五条记录组成,将它们表示成矩阵形式:
( 1 1 2 4 2 1 3 3 4 4 ) \begin{pmatrix} 1 & 1 & 2 & 4 & 2 \\ 1 & 3 & 3 & 4 & 4 \end{pmatrix} (1113234424)
其中每一列为一条数据记录,而一行为一个字段。为了后续处理方便,我们首先将每个字段内所有值都减去字段均值,其结果是将每个字段都变为均值为0(这样做的道理和好处后面会看到)。

我们看上面的数据,第一个字段均值为2,第二个字段均值为3,所以变换后:

( − 1 − 1 0 2 0 − 2 0 0 1 1 ) \begin{pmatrix} -1 & -1 & 0 & 2 & 0 \\ -2 & 0 & 0 & 1 & 1 \end{pmatrix} (1210002101)

我们可以看下五条数据在平面直角坐标系内的样子:

在这里插入图片描述

现在问题来了:如果我们必须使用一维来表示这些数据,又希望尽量保留原始的信息,你要如何选择?

通过上一节对基变换的讨论我们知道,这个问题实际上是要在二维平面中选择一个方向,将所有数据都投影到这个方向所在直线上,用投影值表示原始记录。这是一个实际的二维降到一维的问题。

那么如何选择这个方向(或者说基)才能尽量保留最多的原始信息呢?一种直观的看法是:希望投影后的投影值尽可能分散。

以上图为例,可以看出如果向x轴投影,那么最左边的两个点会重叠在一起,中间的两个点也会重叠在一起,于是本身四个各不相同的二维点投影后只剩下两个不同的值了,这是一种严重的信息丢失,同理,如果向y轴投影最上面的两个点和分布在x轴上的两个点也会重叠。所以看来x和y轴都不是最好的投影选择。我们直观目测,如果向通过第一象限和第三象限的斜线投影,则五个点在投影后还是可以区分的。

下面,我们用数学方法表述这个问题。

方差
上文说到,我们希望投影后投影值尽可能分散,而这种分散程度,可以用数学上的方差来表述。此处,一个字段的方差可以看做是每个元素与字段均值的差的平方和的均值,即:
V a r ( a ) = 1 m ∑ i = 1 m ( a i − μ ) 2 Var(a) = \frac{1}{m} \sum_{i=1}^{m} (a_i - \mu)^2 Var(a)=m1i=1m(aiμ)2

由于上面我们已经将每个字段的均值都化为0了,因此方差可以直接用每个元素的平方和除以元素个数表示:

V a r ( a ) = 1 m ∑ i = 1 m a i 2 Var(a) = \frac{1}{m} \sum_{i=1}^{m} a_i ^2 Var(a)=m1i=1mai2

于是上面的问题被形式化表述为:寻找一个一维基,使得所有数据变换为这个基上的坐标表示后,方差值最大。

协方差

对于上面二维降成一维的问题来说,找到那个使得方差最大的方向就可以了。不过对于更高维,还有一个问题需要解决。考虑三维降到二维问题。与之前相同,首先我们希望找到一个方向使得投影后方差最大,这样就完成了第一个方向的选择,继而我们选择第二个投影方向。

如果我们还是单纯只选择方差最大的方向,很明显,这个方向与第一个方向应该是“几乎重合在一起”,显然这样的维度是没有用的,因此,应该有其他约束条件。从直观上说,让两个字段尽可能表示更多的原始信息,我们是不希望它们之间存在(线性)相关性的,因为相关性意味着两个字段不是完全独立,必然存在重复表示的信息。

数学上可以用两个字段的协方差表示其相关性,由于已经让每个字段均值为0,则:
C o v ( a , b ) = 1 m ∑ i = 1 m a i b i Cov(a,b)= \frac{1}{m} \sum_{i=1}^{m} a_i b_i Cov(a,b)=m1i=1maibi

可以看到,在字段均值为0的情况下,两个字段的协方差简洁的表示为其内积除以元素数m。

当协方差为0时,表示两个字段完全独立。为了让协方差为0,我们选择第二个基时只能在与第一个基正交的方向上选择。因此最终选择的两个方向一定是正交的。

至此,我们得到了降维问题的优化目标:将一组N维向量降为K维(K大于0,小于N),其目标是选择K个单位(模为1)正交基,使得原始数据变换到这组基上后,各字段两两间协方差为0,而字段的方差则尽可能大(在正交的约束下,取最大的K个方差)。

协方差矩阵

上面我们导出了优化目标,但是这个目标似乎不能直接作为操作指南(或者说算法),因为它只说要什么,但根本没有说怎么做。所以我们要继续在数学上研究计算方案。

我们看到,最终要达到的目的与字段内方差及字段间协方差有密切关系。因此我们希望能将两者统一表示,仔细观察发现,两者均可以表示为内积的形式,而内积又与矩阵相乘密切相关。于是我们来了灵感:

假设我们只有a和b两个字段,那么我们将它们按行组成矩阵X:
X = ( a 1 a 2 ⋯ a m b 1 b 2 ⋯ b m ) X= \begin{pmatrix} a_1 & a_2 & \cdots & a_m \\ b_1 & b_2 & \cdots & b_m \end{pmatrix} X=(a1b1a2b2ambm)

然后我们用X乘以X的转置,并乘上系数1/m:

1 m X X T = ( 1 m ∑ i = 1 m a i 2 1 m ∑ i = 1 m a i b i 1 m ∑ i = 1 m a i b i 1 m ∑ i = 1 m b i 2 ) \frac{1}{m}XX^T= \begin{pmatrix} \frac{1}{m} \sum_{i=1}^m a_i^2 & \frac{1}{m} \sum_{i=1}^m a_ib_i\\ \frac{1}{m} \sum_{i=1}^m a_ib_i & \frac{1}{m} \sum_{i=1}^m b_i^2 \end{pmatrix} m1XXT=(m1i=1mai2m1i=1maibim1i=1maibim1i=1mbi2)

奇迹出现了!这个矩阵对角线上的两个元素分别是两个字段的方差,而其它元素是a和b的协方差。两者被统一到了一个矩阵的。

根据矩阵相乘的运算法则,这个结论很容易被推广到一般情况:
设我们有 m m m n n n维数据记录,将其按列排成n乘m的矩阵X,设 C = 1 m X X T C=\frac{1}{m}XX^T C=m1XXT,则C是一个对称矩阵,其对角线分别个各个字段的方差,而第 i i i j j j列和 j j j行i列元素相同,表示 i i i j j j两个字段的协方差。

方法一
设原始数据矩阵 X X X对应的协方差矩阵为 C C C,而 P P P是一组基按行组成的矩阵,设 Y = P X Y=PX Y=PX,则 Y Y Y X X X P P P做基变换后的数据。设 Y Y Y的协方差矩阵为 D D D,我们推导一下 D D D C C C的关系:

D = 1 m Y Y T = 1 m ( P X ) ( P X ) T = 1 m P X X T P T = P ( 1 m X X T ) P T = P C P T \begin{aligned} D &= \frac{1}{m} YY^T \\ &= \frac{1}{m}(PX)(PX)^T \\ &= \frac{1}{m}PXX^TP^T \\ &= P( \frac{1}{m} XX^T)P^T \\ &= PCP^T \end{aligned} D=m1YYT=m1(PX)(PX)T=m1PXXTPT=P(m1XXT)PT=PCPT

现在事情很明白了!我们要找的 P P P不是别的,而是能让原始协方差矩阵对角化的 P P P。换句话说,优化目标变成了寻找一个矩阵 P P P,满足 P C P T PCP^T PCPT是一个对角矩阵,并且对角元素按从大到小依次排列,那么 P P P的前 K K K行就是要寻找的基,用 P P P的前 K K K行组成的矩阵乘以 X X X就使得 X X X N N N维降到了 K K K维并满足上述优化条件。

至此,我们离“发明”PCA还有仅一步之遥!

现在所有焦点都聚焦在了协方差矩阵对角化问题上,有时,我们真应该感谢数学家的先行,因为矩阵对角化在线性代数领域已经属于被玩烂了的东西,所以这在数学上根本不是问题。

由上文知道,协方差矩阵C是一个是对称矩阵,在线性代数上,实对称矩阵有一系列非常好的性质:

1)实对称矩阵不同特征值对应的特征向量必然正交。

2)设特征向量λ重数为r,则必然存在r个线性无关的特征向量对应于λ,因此可以将这r个特征向量单位正交化。

由上面两条可知,一个 n n n n n n列的实对称矩阵一定可以找到n个单位正交特征向量,设这 n n n个特征向量为 e 1 , e 2 , ⋯ , e n e_1,e_2,⋯,e_n e1,e2,,en,我们将其按列组成矩阵:
E = ( e 1 , e 2 , ⋯ , e n ) E=(e_1,e_2,⋯,e_n) E=(e1,e2,,en)
则对协方差矩阵C有如下结论:
E T C E = Λ = ( λ 1 λ 2 ⋱ λ n ) E^TCE= \Lambda = \begin{pmatrix} \lambda_1& & &\\ & \lambda_2 & &\\ & &\ddots &\\ & & & \lambda_n \end{pmatrix} ETCE=Λ=λ1λ2λn
其中 Λ Λ Λ为对角矩阵,其对角元素为各特征向量对应的特征值(可能有重复)。

以上结论不再给出严格的数学证明,对证明感兴趣的朋友可以参考线性代数书籍关于“实对称矩阵对角化”的内容。

到这里,我们发现我们已经找到了需要的矩阵 P P P
P = E T P=E^T P=ET

P P P是协方差矩阵的特征向量单位化后按行排列出的矩阵,其中每一行都是 C C C的一个特征向量。如果设 P P P按照 Λ Λ Λ中特征值的从大到小,将特征向量从上到下排列,则用P的前K行组成的矩阵乘以原始数据矩阵 X X X,就得到了我们需要的降维后的数据矩阵 Y Y Y

除了矩阵推导之外还有利用拉格朗日乘数法——方法二

至此我们完成了整个 P C A PCA PCA的数学原理讨论。在下面的一节,我们将给出 P C A PCA PCA的一个实例。

想法分析: 一个数学模型,求取带有限条件函数(矩阵)的极值。自然想到是拉格朗日乘数法。故我们把它转换成为最优化问题利用拉格朗日乘数法来推导:

样本点 x i x_i xi在基 W W W下的坐标为: ( x i , w ) = x i T w (x_i, w) = x_i^T w (xi,w)=xiTw, 于是我们有方差:
D ( x ) = 1 m ∑ i = 1 m ( x i T w ) 2 = 1 m ∑ i = 1 m ( x i T w ) T ( x i T w ) = 1 m ∑ i = 1 m w x i x i T w = w T ( 1 m ∑ i = 1 m x i x i T ) w \begin{aligned} D(x) &= \frac{1}{m} \sum_{i=1}^{m}(x_i^Tw)^2 \\ &=\frac{1}{m} \sum_{i=1}^{m}(x_i^Tw)^T(x_iTw) \\ &=\frac{1}{m} \sum_{i=1}^{m} wx_ix_i^Tw \\ &=w^T(\frac{1}{m}\sum_{i=1}^{m} x_ix_i^T)w \end{aligned} D(x)=m1i=1m(xiTw)2=m1i=1m(xiTw)T(xiTw)=m1i=1mwxixiTw=wT(m1i=1mxixiT)w

看到 1 m ∑ i = 1 m x i x i T \frac{1}{m}\sum_{i=1}^{m} x_ix_i^T m1i=1mxixiT 就是原样本的协方差,我们另一个矩阵为 Λ \Lambda Λ, 于是我们就有了:
{ m a x w T Λ w s . t . w T w = 1 \begin{cases} max{w^T \Lambda w} \\ s.t.w^Tw = 1 \end{cases} {maxwTΛws.t.wTw=1
此时就可以用拉格朗日乘数法——构造拉格朗日函数:
L ( w ) = w T Λ w = λ ( 1 − w T w ) L(w) = w^T \Lambda w= \lambda(1-w^Tw) L(w)=wTΛw=λ(1wTw)

w w w求导得:
2 Λ w − λ w = 0 Λ w = λ w 2 \Lambda w - \lambda w=0 \\ \Lambda w= \lambda w 2Λwλw=0Λw=λw
此时方差为:
D ( x ) = w T Λ w = λ w T w = λ D(x)= w^T \Lambda w = \lambda w^Tw =\lambda D(x)=wTΛw=λwTw=λ
于是我们发现, x x x 投影后的方差就是协方差矩阵的特征值。我们要找到最大方差也就是协方差矩阵最大的特征值,最佳投影方向就是最大特征值所对应的特征向量,次佳就是第二大特征值对应的特征向量,以此类推。

至此我们完成了基于最大可分性的 P C A PCA PCA 数学证明。

PCA算法
总结一下PCA的算法步骤:

设有 m m m n n n维数据。

1)将原始数据按列组成 n n n m m m列矩阵 X X X

2)将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值

3)求出协方差矩阵 C = 1 m X X T C=\frac{1}{m} XX^T C=m1XXT
4)求出协方差矩阵的特征值及对应的特征向量

5)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P

6) Y = P X Y=PX Y=PX即为降维到 k k k维后的数据

KPCA(核主成分分析)

KPCA,中文名称”核主成分分析“,是对PCA算法的非线性扩展,言外之意,PCA是线性的,其对于非线性数据往往显得无能为力,例如,不同人之间的人脸图像,肯定存在非线性关系,自己做的基于ORL数据集的实验,PCA能够达到的识别率只有88%,而同样是无监督学习的KPCA算法,能够轻松的达到93%左右的识别率(虽然这二者的主要目的是降维,而不是分类,但也可以用于分类),这其中很大一部分原因是,KPCA能够挖掘到数据集中蕴含的非线性信息

PCA使用的方式:线性可分得数据可以直接使用PCA,通过降维来进行数学向量表示。
KPCA使用的方式: 线性不可分的数据再使用PCA就得不到很好的效果,甚至会产生负面效果。故把此类数据先放到高维度下,使其变得线性可分,再使用PCA

例如:
在这里插入图片描述
如左图,红色部分的点为一类数据,黑色部分的点为另一类,在一维空间中,你不可能通过一刀切将两类数据分开,至少需要两刀。OK,这就说明数据分布是非线性的,我们采用高维映射,当然了,例子中只是映射到了二维空间,但已经足够说明问题了,在右图中,完全可以通过沿着X轴方向的一刀切将两类数据分开,说明在二维空间中,数据已经变成线性可分的了。

例如:

在这里插入图片描述
在原始数据中,明显没法使用线性的切割方式来把2类点分开,强行使用PCA会适得其反,而采用KPCA会起到非常好的效果。

代码如下:

from sklearn.datasets import make_moons
from sklearn.decomposition import PCA
from sklearn.decomposition import KernelPCA
import matplotlib.pyplot as plt
import numpy as np

x2, y2 = make_moons(n_samples=100, random_state=123)

if __name__ == "__main__":
    pca = PCA(n_components=2)
    x_spca = pca.fit_transform(x2)
    fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(14, 6))
    ax[0].scatter(x_spca[y2 == 0, 0], x_spca[y2 == 0, 1], color='red', marker='^', alpha=0.5)
    ax[0].scatter(x_spca[y2 == 1, 0], x_spca[y2 == 1, 1], color='blue', marker='o', alpha=0.5)
    ax[1].scatter(x_spca[y2 == 0, 0], np.zeros((50, 1)) + 0.02, color='red', marker='^', alpha=0.5)
    ax[1].scatter(x_spca[y2 == 1, 0], np.zeros((50, 1)) + 0.02, color='blue', marker='o', alpha=0.5)
    ax[0].set_xlabel('PC1')
    ax[0].set_ylabel('PC2')
    ax[1].set_ylim([-1, 1])
    ax[1].set_yticks([])
    ax[1].set_xlabel('PCA')

    kpca = KernelPCA(n_components=2, kernel='rbf', gamma=15)
    x_kpca = kpca.fit_transform(x2)

    ax[2].scatter(x_kpca[y2 == 0, 0], x_kpca[y2 == 0, 1], color='red', marker='^', alpha=0.5)
    ax[2].scatter(x_kpca[y2 == 1, 0], x_kpca[y2 == 1, 1], color='blue', marker='o', alpha=0.5)
    ax[2].set_xlabel('kPCA')
    plt.show()

由以上例子看出KPCA的优势。接下来正式介绍KPCA。

理论

KPCA的公式推导和PCA十分相似,只是存在两点创新:

  1. 为了更好地处理非线性数据,引入非线性映射函数 Φ \Phi Φ ,将原空间中的数据映射到高维空间,注意,这个 Φ \Phi Φ是隐性的,我们不知道,也不需要知道它的具体形式是啥。

  2. 引入了一个定理:空间中的任一向量(哪怕是基向量),都可以由该空间中的所有样本线性表示,这点对KPCA很重要,我想大概当时那个大牛想出KPCA的时候,这点就是它最大的灵感吧。话说这和”稀疏“的思想比较像。

假设中心化后的样本集合 X X X d × N d \times N d×N,N个样本,维数d维,样本”按列排列“),现将 X X X映射到高维空间,得到,假设在这个高维空间中,本来在原空间中线性不可分的样本现在线性可分了,然后呢?想啥呢!果断上PCA啊!

于是乎!假设 D ( D > > d ) D(D >> d) DD>>d维向量 w i ( i = 1 , ⋯   , d ) w_i(i=1, \cdots, d) wi(i=1,,d)为高维空间中的特征向量, λ i ( i = 1 , ⋯   , d ) \lambda _{i}(i=1, \cdots, d) λi(i=1,,d)为对应的特征值,根据PCA的数学模型 X X T w i = λ i w i XX^Tw_i = \lambda _i w_i XXTwi=λiwi, 高维空间中的PCA如下:

Φ ( X ) Φ ( X ) T w i = λ i w i \Phi (X) \Phi (X)^T w_i = \lambda_iw_i Φ(X)Φ(X)Twi=λiwi
我们根据基的概念得到:一个空间中的基向量完全可以用所有的训练样本线性表示出来,即:
w i Φ = ∑ k = 1 N α k ϕ ( x k ) = Φ ( X ) α i w_i^{\Phi} = \sum_{k=1}^{N} \alpha_k \phi(x_k)=\Phi(X) \alpha_i wiΦ=k=1Nαkϕ(xk)=Φ(X)αi

带入到高维PCA的表示式中得:
Φ ( X ) Φ ( X ) T Φ ( X ) α i = λ i Φ ( X ) α i \Phi (X) \Phi (X)^T \Phi(X) \alpha_i = \lambda_i\Phi(X) \alpha_i \\ Φ(X)Φ(X)TΦ(X)αi=λiΦ(X)αi
变换,等号两侧同时左乘一个东西
Φ ( X ) T Φ ( X ) Φ ( X ) T Φ ( X ) α i = λ i Φ ( X ) T Φ ( X ) α i \Phi(X)^T\Phi (X) \Phi (X)^T \Phi(X) \alpha_i = \lambda_i\Phi(X)^T\Phi(X) \alpha_i Φ(X)TΦ(X)Φ(X)TΦ(X)αi=λiΦ(X)TΦ(X)αi

此时定义核函数使得下式成立;
k ( x i , x j ) = Φ ( x i ) Φ ( x j ) k(x_i,x_j)= \Phi(x_i) \Phi(x_j) k(xixj)=Φ(xi)Φ(xj)

请注意,这个公式表达的意思只是高维空间中向量的内积等于原空间中向量之间的核函数值,根核函数的具体形式没有一毛钱的关系。我们继续,一个样本是这样的,那么矩阵化的形式如下:
K = Φ ( X ) T Φ ( X ) K = \Phi(X)^T\Phi(X) K=Φ(X)TΦ(X)

那么高维PCA就变成了:
K 2 α i = λ i K α i K α i = λ i α i K^2 \alpha_i = \lambda_i K \alpha_i \\ K \alpha_i = \lambda_i \alpha_i K2αi=λiKαiKαi=λiαi

求解公式的含义就是求K最大的几个特征值所对应的特征向量,由于K为对称矩阵,所得的解向量彼此之间肯定是正交的。

但是,请注意,这里的 α \alpha α只是 K K K的特征向量,但是其不是高维空间中的特征向量,高维空间中的特征向量 w w w应该是由 α \alpha α进一步求出。

其中它借用核函数的性质,将高维映射 w w w成功的抹掉了。所以我们根本就不需要关心高维映射的基向量。

解决另一个问题又带来另一个问题,那么什么样的函数可以被称作和函数呢?这里大牛们给出了一个著名的定理,称作mercer定理。

Mercer 定理:任何半正定的函数都可以作为核函数。所谓半正定的函数 f ( x i , x j ) f(x_i,x_j) f(xi,xj),是指拥有训练数据集合 ( x 1 , x 2 , . . . x n ) (x_1,x_2,...x_n) x1,x2,...xn),我们定义一个矩阵的元素 a i j = f ( x i , x j ) a_{ij} = f(x_i,x_j) aij=f(xi,xj),这个矩阵式 n × n n\times n n×n的,如果这个矩阵是半正定的,那么 f ( x i , x j ) f(x_i,x_j) f(xi,xj)就称为半正定的函数。

请注意,这个mercer定理不是核函数必要条件,只是一个充分条件,即还有不满足mercer定理的函数也可以是核函数。所谓半正定指的就是核矩阵K的特征值均为非负。

证明过程:https://www.cnblogs.com/jerrylead/archive/2011/03/18/1988406.html

其中一些常见的核函数在:https://blog.csdn.net/wsj998689aa/article/details/47027365

至此PCA以及KPCA介绍完成。

6.3 Ncut切图

N c u t Ncut Ncut切图和 R a t i o C u t RatioCut RatioCut切图很类似,但是把 R a t i o c u Ratiocu Ratiocut的分母 ∣ A i ∣ |A_i| Ai换成 v o l ( A i ) vol(A_i) vol(Ai). 由于子图样本的个数多并不一定权重就大,我们切图时基于权重也更合我们的目标,因此一般来说 N c u t Ncut Ncut切图优于 R a t i o C u t RatioCut RatioCut切图。
N C u t ( A 1 , A 2 , ⋯   , A k ) = 1 2 ∑ i = 1 k W ( A i , A i ‾ ) v o l ( A i ) NCut(A_1, A_2, \cdots, A_k) = \frac{1}{2} \sum_{i=1}^{k} \frac{W(A_i, \overline{A_i})}{vol(A_i)} NCut(A1,A2,,Ak)=21i=1kvol(Ai)W(Ai,Ai)

对应的, N c u t Ncut Ncut切图对指示向量h做了改进。注意到 R a t i o C u t RatioCut RatioCut切图的指示向量使用的是 1 v o l ( A i ) \frac{1}{\sqrt{vol(A_i)}} vol(Ai) 1标示样本归属,而Ncut切图使用了子图权重 1 v o l ( A i ) \frac{1}{\sqrt{vol(A_i)}} vol(Ai) 1来标示指示向量 h h h,定义如下:
h i j = { 0 v i ∉ A i 1 v o l ( A i ) v i ∈ A i h_{ij} = \begin{cases} 0 & v_i \not\in A_i \\ \frac{1}{\sqrt{vol(A_i)}} & v_i \in A_i \end{cases} hij={0vol(Ai) 1viAiviAi
那么我们对于 h i T L h i h_i^T L h_i hiTLhi就有 (根据前面的推导):
h i T L h i = c u t ( A i , A i ‾ ) v o l ( A i ) h_i^T L h_i = \frac{cut(A_i, \overline{A_i})}{vol(A_i)} hiTLhi=vol(Ai)cut(Ai,Ai)

同样的我们的优化目标推到方式和 R a t i o C u t RatioCut RatioCut切图一样:
N C u t ( A 1 , A 2 , ⋯   , A k ) = ∑ i = 1 k c u t ( A i , A i ‾ ) v o l ( A i ) = t r ( H T L H ) NCut(A_1, A_2, \cdots, A_k) = \sum_{i=1}^{k} \frac{cut(A_i, \overline{A_i})}{vol(A_i)} = tr(H^TLH) NCut(A1,A2,,Ak)=i=1kvol(Ai)cut(Ai,Ai)=tr(HTLH)

有一点不同的是此时, H T H ≠ I H^TH \ne I HTH=I 而是 H T D H = I H^TDH = I HTDH=I.,推导如下:
h i T D h i = ∑ j = 1 k h i j 2 d j = 1 v o l ( A i ) ∑ j = 1 k d j h_i^T D h_i = \sum_{j=1}^{k} h_{ij}^2 d_j = \frac{1}{vol(A_i)} \sum_{j=1}^{k} d_j hiTDhi=j=1khij2dj=vol(Ai)1j=1kdj

根据 v o l ( A i ) = ∑ j = 1 k d j vol(A_i) = \sum_{j=1}^k d_j vol(Ai)=j=1kdj:

则:
= 1 v o l ( A i ) v o l ( A i ) = 1 = \frac{1}{vol(A_i)} vol(A_i)=1 =vol(Ai)1vol(Ai)=1

也就是说,此时我们的优化目标最终为:

a r g m i n t r ( H T L H ) s . t . H T D H = I ⏟ H \underbrace{arg \quad min \quad tr(H^{T}LH) \quad \quad s.t.H^TDH = I }\\ H argmintr(HTLH)s.t.HTDH=IH

此时我们的 H H H中的指示向量 h h h并不是标准正交基,所以在 R a t i o C u t RatioCut RatioCut里面的降维思想不能直接用。怎么办呢?其实只需要将指示向量矩阵 H H H做一个小小的转化即可。

H = D − 1 2 F H= D^{-\frac{1}{2}} F H=D21F, 则: H T L H = F T D − 1 2 L D − 1 2 F , H T D H = F T F = I H^TLH = F^TD^{- \frac{1}{2}} L D^{-\frac{1}{2}}F, H^TDH = F^TF=I HTLH=FTD21LD21F,HTDH=FTF=I 也就是说我们的优化目标:
a r g m i n t r ( H T L H ) s . t F T F = I ⏟ H \underbrace{arg \quad min \quad tr(H^{T}LH) \quad \quad s.t F^TF = I }\\ H argmintr(HTLH)s.tFTF=IH
可以发现这个式子和 R a t i o C u t RatioCut RatioCut基本一致,只是中间的L变成了 D − 1 2 L D − 1 2 D^{- \frac{1}{2}} L D^{-\frac{1}{2}} D21LD21。这样我们就可以继续按照 R a t i o C u t RatioCut RatioCut的思想,求出 D − 1 2 L D − 1 2 D^{- \frac{1}{2}} L D^{-\frac{1}{2}} D21LD21的最小的前k个特征值,然后求出对应的特征向量,并标准化,得到最后的特征矩阵 F F F,最后对F进行一次传统的聚类(比如K-Means)即可。

一般来说, D − 1 2 L D − 1 2 D^{- \frac{1}{2}} L D^{-\frac{1}{2}} D21LD21相当于对拉普拉斯矩阵L做了一次标准化即: L i j d i ∗ d j \frac{L_{ij}}{\sqrt{d_i * d_j}} didj Lij

7. 谱聚类算法流程

铺垫了这么久,终于可以总结下谱聚类的基本流程了。一般来说,谱聚类主要的注意点为相似矩阵的生成方式(参见第二节),切图的方式(参见第六节)以及最后的聚类方法(参见第六节)。

最常用的相似矩阵的生成方式是基于高斯核距离的全连接方式,最常用的切图方式是Ncut。而到最后常用的聚类方法为K-Means。下面以Ncut总结谱聚类算法流程。

输入:样本集 D = ( x 1 , x 2 , . . . , x n ) D=(x_1,x_2,...,x_n) D=(x1,x2,...,xn),相似矩阵的生成方式, 降维后的维度 k 1 k_1 k1, 聚类方法,聚类后的维度 k 2 k_2 k2
输出: 簇划分 C ( c 1 , c 2 , . . . c k 2 ) C(c_1,c_2,...c_{k_2}) C(c1,c2,...ck2).

1)根据输入的相似矩阵的生成方式构建样本的相似矩阵 S S S

2)根据相似矩阵 S S S构建邻接矩阵 W W W,构建度矩阵 D D D

3)计算出拉普拉斯矩阵 L L L

4)构建标准化后的拉普拉斯矩阵 D − 1 2 L D − 1 2 D^{- \frac{1}{2}} L D^{-\frac{1}{2}} D21LD21

5)计算 D − 1 2 L D − 1 2 D^{- \frac{1}{2}} L D^{-\frac{1}{2}} D21LD21最小的 k 1 k_1 k1个特征值所各自对应的特征向量 f f f

6)将各自对应的特征向量f组成的矩阵按行标准化,最终组成 n × k 1 n\times k_1 n×k1维的特征矩阵 F F F

7)对 F F F中的每一行作为一个 k 1 k_1 k1维的样本,共 n n n个样本,用输入的聚类方法进行聚类,聚类维数为 k 2 k_2 k2

8)得到簇划分 C ( c 1 , c 2 , . . . c k 2 ) C(c_1,c_2,...c_{k_2}) C(c1,c2,...ck2).

8. 谱聚类算法总结
    谱聚类算法是一个使用起来简单,但是讲清楚却不是那么容易的算法,它需要你有一定的数学基础。如果你掌握了谱聚类,相信你会对矩阵分析,图论有更深入的理解。同时对降维里的主成分分析也会加深理解。

下面总结下谱聚类算法的优缺点。

谱聚类算法的主要优点有:

1)谱聚类只需要数据之间的相似度矩阵,因此对于处理稀疏数据的聚类很有效。这点传统聚类算法比如K-Means很难做到

2)由于使用了降维,因此在处理高维数据聚类时的复杂度比传统聚类算法好。

谱聚类算法的主要缺点有:

1)如果最终聚类的维度非常高,则由于降维的幅度不够,谱聚类的运行速度和最后的聚类效果均不好。

2) 聚类效果依赖于相似矩阵,不同的相似矩阵得到的最终聚类效果可能很不同。

参考:

https://www.cnblogs.com/pinard/p/6221564.html
https://blog.csdn.net/wsj998689aa/article/details/40398777
http://blog.codinglabs.org/articles/pca-tutorial.html
https://zhuanlan.zhihu.com/p/85977023
https://zhuanlan.zhihu.com/p/100586855

  • 4
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Laplacian Eigenmaps是一种经典的降维算法,它通过构建数据之间的相似关系来重构数据流形的局部结构特征。该算法的主要思想是,如果两个数据实例i和j很相似,那么在降维后的目标子空间中,它们应该尽量接近。该算法通过优化一个目标函数来实现降维操作。目标函数的定义如下: \[J(Y) = \sum_{ij} w_{ij} ||y_i-y_j||^2\] 其中,Y表示降维后的数据矩阵,w_{ij}表示数据实例i和j之间的相似度。通过优化这个目标函数,可以得到降维后的数据矩阵Y,从而实现对数据的降维操作。 Laplacian Eigenmaps与其他降维算法(如PCA、LDA和LLE)相比,在处理非线性流形数据时具有更好的性能。它能够保留数据的局部结构特征,并且对噪声和异常值具有较好的鲁棒性。因此,在数据分析和可视化领域,Laplacian Eigenmaps被广泛应用于降维和数据流形学习任务中。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [机器学习降维算法四:Laplacian Eigenmaps 拉普拉斯特征映射](https://blog.csdn.net/weixin_43499818/article/details/108653762)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值