鲭兜的博客


努力に胜る天才无し


Kernel Principal Component Analysis


主成分分析(Principal Component Analysis)是降维(Demension Reduction)的重要手段。但是就像上篇文章所说,使用主成分分析也存在一些限制,它可以很好地解除特征量的线性相关性问题,但是对于高阶相关性就没有办法了(协方差等于0,意味着特征量之间不存在线性相关性,而不是完全独立,可能仍然存在高阶相关性)。这个时候,我们考虑Kernel PCA,通过Kernel函数将非线性相关转为线性相关,从而进行PCA转换。
这篇文章的目的是记录我学习Kernel PCA过程的心得体会,简单介绍一下Kernel PCA的数学原理,文章有错误的地方欢迎指正。

0、几个假设

对于PCA,实际上存在几个假设:
(1)特征值的大小决定了该字段的信息多少,即小特征值往往表示噪声。但实际上,向小特征值方向投影也有可能包括许多信息。
(2)特征向量的方向是互相正交(orthogonal)的,这种正交性使得PCA容易受到离群点(Outlier)的影响。
(3)难于解释结果。例如在建立线性回归模型(Linear Regression Model)分析因变量(responce)和第一个主成分的关系时,我们得到的回归系数(coefficiency)不是某一个自变量(covariate)的贡献,而是所有自变量的某个线性组合(Linear Combination)的贡献。

在Kernel PCA中,我们同样需要这些假设,但不同的地方是我们认为原始数据有更高的维度,我们可以在更高维的空间(Hilbert Space)中做PCA分析(即在更高维空间里,把原始数据向不同的方向投影)。这样做,对于在通常线性空间难以线性分类的数据点,我们有可能在更高维度上找到合适的高维线性分类平面。

1、Kernel Principal Component Analysis

我们对比传统PCA算法,类比出在高维空间的PCA算法。

1-1、传统PCA的做法

我们先定义必要的变量和需要解决的问题:$X=[\begin{matrix} x_1 & x_2 & \dots & x_N]\end{matrix}$是一个$d \times N$的矩阵,代表输入的数据有$N$个,每个样本的维度是$d$。我们做降维,就是想用$k$维的数据来表示原始的$d$维数据($k < d$)。
我们首先将每个字段的均值化为0,即$\displaystyle\sum_i^Nx_i=0$,定义协方差矩阵$C$为:
$$C=\frac{1}{N}XX^T$$
做特征值分解,我们得到:
$$CU=U\Lambda\Rightarrow C=U\Lambda U^T=\displaystyle\sum_a\lambda_au_a{u_a}^T$$
注意这里的$C,U,\Lambda$的维度都是$d\times d$,且$U=[\begin{matrix} u_1 & u_2 & \dots & u_d]\end{matrix}$,$\Lambda=diag(\begin{matrix} \lambda_1 & \lambda_2 & \dots & \lambda_d \end{matrix})$。当我们做降维时,可以利用前$k$个特征向量$U_k=[\begin{matrix} u_1 & u_2 & \dots & u_k \end{matrix}]$,则将一个$d$维的$x_i$向$k$维的主成分方向投影后的数据为$y_i=U_k^Tx_i$。

1-2、高维空间中的PCA

高维空间中,我们定义一个映射$\Phi:X^d\rightarrow\mathcal{F}$,这里$\mathcal{F}$表示Hilbert泛函空间。
现在我们的输入数据是$\Phi(x_i),i=1,2,\dots,n$,他们的维度可以是无穷维的(泛函空间),为了方便讨论,设其空间的维度为$D(D\gg d)$。
在这个新的空间(特征空间)中,将中心化的数据记为$\tilde\Phi(x_i)$,即
$$\tilde\Phi(x_i)=\Phi(x_i)-\bar\Phi$$
其中
$$\bar\Phi=\frac{1}{N}\displaystyle\sum_i^N\Phi(x_i)$$
将中心化的核矩阵记为$\tilde K$(核矩阵是样本之间通过核函数映射之后得到的,每两个样本之间进行一次核函数映射),且定义$\tilde K_{ij}\le \tilde\Phi(x_i)$,$\tilde\Phi(x_j)\ge\tilde\Phi(x_i)^T\tilde\Phi(x_j)$。
$\tilde\Phi(x_i)$中心化的数据($\displaystyle\sum_i^N\tilde\Phi(x_i)=0$)的协方差矩阵为$\bar{C}$:
$$\bar C=\frac{1}{N}\tilde\Phi(X)\tilde\Phi(X)^T$$
这里有一个陷阱:
对Kernel Trick一知半解的时候,我们常常从形式上认为$\bar C$可以用$\tilde K_{ij}=\tilde K(x_i,x_j)$来代替,因此对$\tilde K=(\tilde K_{ij})$做特征值分解,然后得到$\tilde K=U\Lambda U^T$,并且对原始数据降维的时候,定义$Y_i=U_k^TX_i$。
但这个错误的方法有两个问题:一是我们不知道矩阵$\bar C$的维度,即也不知道$\bar C$的具体形式;二是$U_k^TX_i$从形式上看不出是从高维空间的$\Phi(x_i)$的投影,并且当有新的数据$X_{new}$时,我们无法从理论上理解$U_k^TX_{new}$是从高维空间的投影,后面发现,投影方向不是这里的$U$。
如果应用这种错误的方法,我们有可能得到看起来差不多正确的结果,但本质上这是错误的。正确的方法是通过Kernel Trick将PCA投影的过程通过内积的形式表现出来。

1-3、利用Kernel Trick在高维空间做PCA

在1-1节,通过PCA,我们得到了$U$矩阵。这里介绍如何仅利用内积的概念来计算传统的PCA。
首先需要证明一个结论:$U$可以由$x_1,x_2,\dots,x_N$展开。
由于$Cu_a=\lambda_au_a$得
$$
\begin{array} {l l l}
u_a & = & \frac{1}{\lambda_a}Cu_a \\\
& = & \frac{1}{\lambda_aN}(\displaystyle\sum_i^Nx_ix_i^T)u_a \\\
& = & \frac{1}{\lambda_aN}\displaystyle\sum_i^Nx_i(x_i^Tu_a) \\\
& = & \frac{1}{\lambda_aN}\displaystyle\sum_i^N(x_i^Tu_a)x_i \\\
& = & \displaystyle\sum_i^N\frac{x_i^Tu_a}{\lambda_aN}x_i \\\
& = & \displaystyle\sum_i^N\alpha_i^{(a)}x_i
\end{array}
$$
其中定义$\alpha_i^{(a)}=\frac{x_i^Tu_a}{\lambda_aN}$
因为$x_i^Tu_a$是一个标量,所以$\alpha_i^{(a)}$也是一个标量,因此$u_a$是可以由$x_i$组成的。
进而我们介绍PCA投影可以用内积表示,例如我们把$x_i$向任意一个主成分分量$u_a$进行投影,得到的是$u_a^Tx_i$,也就是$x_i^Tu_a$。我猜测写成这种形式是为了能抽出$x_i^Tx_j=< x_i , x_j >$的内积形式。
$$
\begin{array} {l l l}
x_i^TCu_a & = & \lambda_ax_i^Tu_a \\\
x_i^T\frac{1}{N}\left(\displaystyle\sum_j^Nx_jx_j^T\right)\left(\displaystyle\sum_k^N\alpha_k^{(a)}x_k\right) & = & \lambda_ax_i^T\displaystyle\sum_k^N\alpha_k^{(a)}x_k \\\
\displaystyle\sum_k^N\alpha_k^{(a)}\displaystyle\sum_j^N(x_i^Tx_j)(x_j^Tx_k) & = & N\lambda_a\displaystyle\sum_k^N\alpha_k^{(a)}(x_i^Tx_k)
\end{array}
$$
也就是说,对于$i$:
$$
\alpha_1^{(a)}(x_i^Tx_1x_1^Tx_1+x_i^Tx_2x_2^Tx_1+\dots+x_i^Tx_Nx_N^Tx_1)+ \\\
\alpha_2^{(a)}(x_i^Tx_1x_1^Tx_2+x_i^Tx_2x_2^Tx_2+\dots+x_i^Tx_Nx_N^Tx_2)+\dots \\\
\alpha_N^{(a)}(x_i^Tx_1x_1^Tx_N+x_i^Tx_2x_2^Tx_N+\dots+x_i^Tx_Nx_N^Tx_N)+ \\\
= N\lambda_a(\alpha_1^{(a)}x_i^Tx_1+\alpha_2^{(a)}x_i^Tx_2+\dots+\alpha_N^{(a)}x_i^Tx_N)
$$
将其写成矩阵形式为:
$$
\begin{pmatrix}
x_1^Tx_1 & x_1^Tx_2 & \dots & x_1^Tx_N \\\
x_2^Tx_1 & x_2^Tx_2 & \dots & x_2^Tx_N \\\
\vdots & \vdots & \ddots & \vdots \\\
x_N^Tx_1 & x_N^Tx_2 & \dots & x_N^Tx_N
\end{pmatrix}
\begin{pmatrix}
x_1^Tx_1 & x_1^Tx_2 & \dots & x_1^Tx_N \\\
x_2^Tx_1 & x_2^Tx_2 & \dots & x_2^Tx_N \\\
\vdots & \vdots & \ddots & \vdots \\\
x_N^Tx_1 & x_N^Tx_2 & \dots & x_N^Tx_N
\end{pmatrix}
\begin{pmatrix}
\alpha_1^{(a)} \\\
\alpha_2^{(a)} \\\
\vdots \\\
\alpha_N^{(a)}
\end{pmatrix} = N \lambda_a
\begin{pmatrix}
x_1^Tx_1 & x_1^Tx_2 & \dots & x_1^Tx_N \\\
x_2^Tx_1 & x_2^Tx_2 & \dots & x_2^Tx_N \\\
\vdots & \vdots & \ddots & \vdots \\\
x_N^Tx_1 & x_N^Tx_2 & \dots & x_N^Tx_N
\end{pmatrix}
\begin{pmatrix}
\alpha_1^{(a)} \\\
\alpha_2^{(a)} \\\
\vdots \\\
\alpha_N^{(a)}
\end{pmatrix}
$$
当我们定义$K_{ij}=x_i^Tx_j$时,上式可以写成$K^2\alpha^{(a)}=N\lambda_aK\alpha^{(a)}$,这里定义$\alpha^{(a)}=\begin{bmatrix} \alpha_1^{(a)} & \alpha_2^{(a)} & \dots & \alpha_N^{(a)} \end{bmatrix}^T$。
进一步,我们得到:
$K\alpha^{(a)}=\tilde\lambda_a\alpha^{(a)}$,其中$\tilde\lambda_a=N\lambda_a$
$K$矩阵包含特征值$\tilde\lambda_a$和特征向量$\alpha^{(a)}$,我们可以通过$\alpha^{(a)}$计算得到特征向量$u_a$。
注意特征值分解时,$\alpha^{(a)}$只代表一个方向,它的模一般为1,但是在此处不为1。下面计算$\alpha^{(a)}$的长度:
$$
\begin{array} {l l l}
1 & = & u_a^Tu_a \\\
& = & (\displaystyle\sum_i^N\alpha_i^{(a)}x_i)^T(\displaystyle\sum_j^N\alpha_j^{(a)}x_j) \\\
& = & \displaystyle\sum_i^N\displaystyle\sum_j^N\alpha_i^{(a)}\alpha_j^{(a)}x_i^Tx_j \\\
& = & (\alpha^{(a)})^TK\alpha^{(a)} \\\
& = & (\alpha^{(a)})^T\tilde\lambda_a\alpha^{(a)} \\\
& = & \tilde\lambda_a(\alpha^{(a)})^T\alpha^{(a)}
\end{array}
$$
所以
$||\alpha^{(a)}||=\dfrac{1}{\sqrt{\tilde\lambda_a}}$
在上面的分析过程中,我们使用了内积的思想完成了传统PCA的过程,即可以通过核矩阵$K$的特征值$\tilde\lambda_a$和特征向量$\alpha^{(a)}$计算协方差矩阵的特征值$\lambda_a=\frac{\tilde\lambda_a}{N}$和特征向量$u_a=\displaystyle\sum_i^N\frac{\alpha_i^{(a)}}{\sqrt{\tilde\lambda_a}}x_i$。

1-4、KPCA的实现

我们重复1-3过程,看看KPCA中的有关推导。
设$\bar C$的特征值和对应的特征向量分别为$\lambda_k$和$u_k$,即
$$\bar Cu_k=\lambda_k u_k(k=1,2,\dots,D)\dots\dots\dots\dots(*)$$
由1-3知,$u_k\in span\{\tilde\Phi(x_1),\tilde\Phi(x_2),\dots,\tilde\Phi(x_N)\}$,即存在$\alpha_1^{(k)},\alpha_2^{(k)},\dots,\alpha_N^{(k)}$使得
$$u_k=\displaystyle\sum_i^N\alpha_i^{(k)}\tilde\Phi(x_i)$$
用$\tilde\Phi(x_j)^T$同时作用于(*)式子得到:
$$
\begin{array} {l l l}
\lambda_k\tilde\Phi(x_j)^Tu_k & = & \tilde\Phi(x_j)^T\bar Cu_k
\end{array}
$$
左边可以化为:
$$
\begin{array} {l l l}
\lambda_k\tilde\Phi(x_j)^Tu_k & = & \lambda_k\left(\displaystyle\sum_i^N\alpha_i^{(k)}\tilde\Phi(x_j)^T\tilde\Phi(x_i)\right) \\\
& = & \lambda_k\left(\displaystyle\sum_i^N\alpha_i^{(k)}\tilde K_{ij}\right) \\\
& = & \lambda_k\left(\tilde K\alpha^{(k)}\right)_j\text{ 下标j表示矩阵的第j行}
\end{array}
$$
其中
$\tilde K=\left(\tilde K_{ij}\right)_{N\times N}=\left(\tilde\Phi(x_i)^T\tilde\Phi(x_j)\right)_{N\times N}$,$\alpha^{(k)}=(\alpha_1^{(k)},\alpha_2^{(k)},\dots,\alpha_N^{(k)})^T$
右边可以化为:
$$
\begin{array} {l l l}
\tilde\Phi(x_j)^T\bar Cu_k & = & \tilde\Phi(x_j)^T\frac{1}{N}\displaystyle\sum_l^N\tilde\Phi(x_l)\tilde\Phi(x_l)^T\displaystyle\sum_i^N\alpha_i^{(k)}\tilde\Phi(x_i) \\\
& = & \frac{1}{N}\displaystyle\sum_i^N\displaystyle\sum_l^N\alpha_i^{(k)}\left(\tilde\Phi(x_j)^T\tilde\Phi(x_l)\tilde\Phi(x_l)^T\tilde\Phi(x_i)\right) \\\
& = & \frac{1}{N}\displaystyle\sum_i^N\displaystyle\sum_l^N\alpha_i^{(k)}\tilde K_{jl}\tilde K_{li} \\\
& = & \frac{1}{N}\left(\tilde K^2\alpha^{(k)}\right)_j\text{ 下标j表示矩阵的第j行}
\end{array}
$$
让$j$依次取遍$1,2,\dots,N$的所有数,得到上面推导的”左边=右边”的矩阵表示:
$$\lambda_k\tilde K\alpha^{(k)}=\frac{1}{N}\tilde K^2\alpha^{(k)}$$
化简得到
$$\tilde K\alpha^{(k)}=N\lambda_k\alpha^{(k)}=\tilde\lambda_k\alpha^{(k)}$$
即之前假设的$\alpha^{(k)}=(\alpha_1^{(k)},\alpha_2^{(k)},\dots,\alpha_N^{(k)})^T$为中心化的核矩阵$\tilde K$的第$k$个特征向量和对应的特征值$\tilde\lambda_k$。现在我们可以用所求的$\tilde\lambda_k$和$\alpha^{(k)}$去表示协方差矩阵$\bar C$的特征值$\lambda_k$和特征向量$u_k$。
$\lambda_k=\frac{\tilde\lambda_k}{N}$,$u_k=\displaystyle\sum_i^N\alpha_i^{(k)}\tilde\Phi(x_i)=\tilde\Phi\alpha^{(k)}$,其中$\tilde\Phi=\left(\tilde\Phi(x_1),\tilde\Phi(x_2),\dots,\tilde\Phi(x_N)\right)$
现在还有个小问题没有解决,在传统PCA方法中,协方差矩阵得到的特征向量是单位正交的。同样,我们希望$u_k$也是单位向量,即:
$$
\begin{array} {l l l}
1 & = & u_k^Tu_k \\\
& = & \left(\displaystyle\sum_i^N\alpha_i^{(k)}\tilde\Phi(x_i)\right)^T\left(\displaystyle\sum_j^N\alpha_j^{(k)}\tilde\Phi(x_j)\right) \\\
& = & (\alpha^{(k)})^T\tilde\Phi^T\tilde\Phi\alpha^{(k)} \\\
& = & (\alpha^{(k)})^T\tilde K\alpha^{(k)} \\\
& = & (\alpha^{(k)})^T\tilde\lambda_k\alpha^{(k)} \\\
& = & \tilde\lambda_k(\alpha^{(k)})^T\alpha^{(k)} \\\
& = & \tilde\lambda_k||\alpha^{(k)}||^2
\end{array}
$$
因此,将$\tilde K$的特征向量$\alpha^{(k)}$的长度归一化到$||\alpha^{(k)}||=\dfrac{1}{\sqrt{\tilde\lambda_k}}$,便能保证$u_k$的长度为1。
下面证明正交性:
$$
\begin{array} {l l l}
u_i^Tu_j & = & (\alpha^{(i)})^T\tilde\Phi^T\tilde\Phi\alpha^{(j)} \\\
& = & (\alpha^{(i)})^T\tilde K\alpha^{(j)} \\\
& = & (\alpha^{(i)})^T\tilde\lambda_j\alpha^{(j)} \\\
& = & \tilde\lambda_j(\alpha^{(i)})^T\alpha^{(j)} \\\
& = & 0
\end{array}
$$
得证!
最后总结一下之前的结论,特征空间中协方差矩阵$\bar C$的特征值为$\lambda_k=\dfrac{\tilde\lambda_k}{N}$,对应的特征向量为$u_k=\dfrac{1}{\sqrt{\tilde\lambda_k}}\tilde\Phi\alpha^{(k)},(k=1,2,\dots,D)$,其中$\tilde\lambda_k$和$\alpha^{(k)}$为$\tilde K$的特征值和特征向量。
由于映射$\Phi$未知,直接在特征空间内进行数据中心化不可行,直接将输入数据在特征空间中心的过程见1-6。

1-5、在主成分方向上投影

由于高维空间的维度具体是多少是未知的,所以无法实际求出$u_k$的数据,但是我们可以通过核矩阵$\tilde K$来间接计算在主成分方向的投影。
传统PCA投影时,只需要使用$U$矩阵,假设我们得到的新数据为$T=(t_1,t_2,\dots,t_M)$,那么$t_k$在$u_a$方向的投影是:
$$u_a^Tt_k=\displaystyle\sum_i^N\alpha_i^{(a)}x_i^Tt_k=\displaystyle\sum_i^N\alpha_i^{(a)}(x_i^Tt_k)$$
对于高维空间的数据$\tilde\Phi(x_i),\tilde\phi(t_k)$,我们可以用Kernel Trick,用$\tilde\Psi(x_i,t_k)=\tilde\Phi(x_i)^T\tilde\phi(t_k)$来代入上式:
$$
\begin{array} {l l l}
u_a^T\tilde\phi(t_k) & = & \frac{1}{\sqrt{\tilde\lambda_a}}\left(\displaystyle\sum_i^N\alpha_i^{(a)}\tilde\Phi(x_i)\right)^T\tilde\phi(t_k) \\\
& = & \frac{1}{\sqrt{\tilde\lambda_a}}\displaystyle\sum_i^N\alpha_i^{(a)}\left(\tilde\Phi(x_i)^T\tilde\phi(t_k)\right) \\\
& = & \displaystyle\sum_i^N\frac{\alpha_i^{(a)}}{\sqrt{\tilde\lambda_a}}\tilde\Psi(x_i,t_k)
\end{array}
$$
一般$\tilde\phi(t_k)$不能显式得到,从而需要计算输入数据$T$的中心化核矩阵,记为$\tilde\Psi$。

1-6、中心化高维空间的数据

在我们的分析中,协方差矩阵的定义需要中心化数据。在高维空间中,显式地将$\Phi(x_i)$中心化并不简单,因为我们并不知道$\Phi$的显式表达。但从上面两节可以看出,所有的计算只和$K$矩阵有关。具体计算如下:
令$\Phi_i=\Phi(x_i)$,其中:$\tilde\Phi_i=\Phi_i-\frac{1}{N}\displaystyle\sum_k^N\Phi_k$
$$
\begin{array} {l l l}
\tilde K_{ij} & = & <\tilde\Phi_i,\tilde\Phi_j> \\\
& = & (\Phi_i-\frac{1}{N}\displaystyle\sum_k^N\Phi_k)^T(\Phi_j-\frac{1}{N}\displaystyle\sum_l^N\Phi_l) \\\
& = & \Phi_i^T\Phi_j-\frac{1}{N}\displaystyle\sum_k^N\Phi_k^T\Phi_j-\frac{1}{N}\displaystyle\sum_l^N\Phi_i^T\Phi_l+\frac{1}{N^2}\displaystyle\sum_k^N\displaystyle\sum_l^N\Phi_k^T\Phi_l \\\
& = & K_{ij}-\frac{1}{N}\displaystyle\sum_k^NK_{kj}-\frac{1}{N}\displaystyle\sum_l^NK_{il}+\frac{1}{N^2}\displaystyle\sum_k^N\displaystyle\sum_l^NK_{kl}
\end{array}
$$
不难看出
$$\tilde K=K-1_NK-K1_N+1_NK1_N$$
其中$1_N$为$N\times N$的矩阵,矩阵中的每个元素都是$\dfrac{1}{N}$。
对于新的数据,如果数据$t_j\not\in X$:
$$
\begin{array} {l l l}
\tilde\Psi_{i,j} & = & <\tilde\Phi_i,\tilde\phi_j> \\\
& = & \left(\Phi_i-\frac{1}{N}\displaystyle\sum_k^N\Phi_k\right)^T\left(\phi_j-\frac{1}{M}\displaystyle\sum_l^M\phi_l\right) \\\
& = & \Phi_i^T\phi_j-\frac{1}{N}\displaystyle\sum_k^N\Phi_k^T\phi_j-\frac{1}{M}\displaystyle\sum_l^M\Phi_i^T\phi_l+\frac{1}{MN}\displaystyle\sum_k^N\displaystyle\sum_l^M\Phi_k^T\phi_l \\\
& = & \Psi_{i,j}-\frac{1}{N}\displaystyle\sum_k^N\Psi_{k,j}-\frac{1}{M}\displaystyle\sum_l^M\Psi_{i,l}+\frac{1}{MN}\displaystyle\sum_k^N\displaystyle\sum_l^M\Psi_{k,l}
\end{array}
$$
不难看出
$$\tilde\Psi=\Psi-1_NK-K1_M+1_NK1_M$$
如果有数据$t_k\in X$,则上式中有$M=N$,且$\tilde K=\tilde\Psi$。

2、算法实现

2-1、KPCA算法

总结一下KPCA的算法步骤:
设有$m$条$n$维数据
1)将原始数据按行组成$m$行$n$列矩阵$X$
2)每两条数据进行kernel计算,得到核矩阵$K$
3)根据高维空间数据中心化方法$\tilde K=K-1_NK-K1_N+1_NK1_N$,计算中心化核矩阵$\tilde K$
4)求出中心化核矩阵的特征向量和特征值
5)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前$k$列组成矩阵$\alpha$
6)将每一行特征向量单位化,每一行特征向量除去对应特征值的开方值
7)$Y=\alpha X$即为先升维再降维到$k$维后的数据

2-2、关键代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def kernel(x, y, kTup):
if kTup[0] == 'lin':
return x * y.T
elif kTup[0] == 'rbf':
return exp((x - y) * (x - y).T / (-2 * kTup[1] ** 2))
def kpca(dataMat, kTup, topN = 99):
M, N = shape(dataMat)
K = mat(zeros((M, M)))
for i in range(M):
for j in range(M):
K[i, j] = kernel(dataMat[i, :], dataMat[j, :], kTup)
M_M = mat(ones((M, M))) / M
cenK = K - M_M * K - K * M_M + M_M * K * M_M
eigVals, eigVects = linalg.eig(cenK)
eigValInd = argsort(eigVals)
eigValInd = eigValInd[-1: -(topN + 1): -1]
redEigVects = eigVects[:, eigValInd]
for i in range(topN):
redEigVects[:, i] = redEigVects[:, i] / sqrt(eigVals[eigValInd[i]])
needMat = cenK * redEigVects
return needMat

完整代码请点击shengtao96-github-kpca

3、说明

KPCA算法是先将数据升维,然后再降维的技术,目的是发现数据之间的非线性高阶相关性并且去除掉这种相关性。KPCA不是按步骤来的,将数据升维的操作实际是不存在的,这只是概念上的。
将KPCA与PCA相比,发现代码有很多相似的地方,但是进行特征分解的矩阵是完全不一样的。可以说,KPCA算法已经完成与PCA不一样了,至少计算过程是完成不一样的。
PCA是一种无参数技术,但是KPCA显然不是。KPCA的参数实际上就是Kernel的参数,具体要升到什么维度之后再降维,需要进行多次调参。