Kernel PCA 原理和演示
来源:互联网 发布:ubuntu cuda9.0 caffe 编辑:程序博客网 时间:2024/04/30 09:02
主成份(Principal Component Analysis)分析是降维(Dimension Reduction)的重要手段。每一个主成分都是数据在某一个方向上的投影,在不同的方向上这些数据方差Variance的大小由其特征值(eigenvalue)决定。一般我们会选取最大的几个特征值所在的特征向量(eigenvector),这些方向上的信息丰富,一般认为包含了更多我们所感兴趣的信息。当然,这里面有较强的假设:(1)特征根的大小决定了我们感兴趣信息的多少。即小特征根往往代表了噪声,但实际上,向小一点的特征根方向投影也有可能包括我们感兴趣的数据; (2)特征向量的方向是互相正交(orthogonal)的,这种正交性使得PCA容易受到Outlier的影响,例如在【1】中提到的例子(3)难于解释结果。例如在建立线性回归模型(Linear Regression Model)分析因变量(response)和第一个主成份的关系时,我们得到的回归系数(Coefficiency)不是某一个自变量(covariate)的贡献,而是对所有自变量的某个线性组合(Linear Combination)的贡献。
在Kernel PCA分析之中,我们同样需要这些假设,但不同的地方是我们认为原有数据有更高的维数,我们可以在更高维的空间(Hilbert Space)中做PCA分析(即在更高维空间里,把原始数据向不同的方向投影)。这样做的优点有:对于在通常线性空间难于线性分类的数据点,我们有可能再更高维度上找到合适的高维线性分类平面。我们第二部分的例子就说明了这一点。
本文写作的动机是因为作者没有找到一篇好的文章(看了wikipedia和若干google结果后)深层次介绍PCA和Kernel PCA之间的联系,以及如何以公式形式来解释如何利用Kernel PCA来做投影,特别有些图片的例子只是展示了结果和一些公式,这里面具体的过程并没有涉及。希望这篇文章能做出较好的解答。
1. Kernel Principal Component Analysis 的矩阵基础
我们从解决这几个问题入手:传统的PCA如何做?在高维空间里的PCA应该如何做?如何用Kernel Trick在高维空间做PCA?如何在主成分方向上投影?如何Centering 高维空间的数据?
1.1 传统的PCA如何做?
让我先定义如下变量:
当我们使用centered的数据(即
做特征值分解,我们可以得到:
注意这里的
当我们做降维时,可以利用前
1.2 在高维空间里的PCA应该如何做?
高维空间中,我们定义一个映射
现在我们的输入数据是
在这个新的空间中,假设协方差矩阵同样是centered,我们的协方差矩阵为:
这里有一个陷阱,我跳进去过:
在对Kernel trick一知半解的时候,我们常常从形式上认为
因此对
但这个错误的方法有两个问题:一是我们不知道矩阵
如果应用这种错误的方法,我们有可能得到看起来差不多正确的结果,但本质上这是错误的。
正确的方法是通过Kernel trick将PCA投影的过程通过内积的形式表达出来,详细见1.3
1.3 如何用Kernel Trick在高维空间做PCA?
在1.1节中,通过PCA,我们得到了
首先我们证明
这里定义
因为
进而我们显示PCA投影可以用内积运算表示,例如我们把
当我们定义
(这里
进一步,我们得到解为:
注意特征值分解时Eigendecomposition,
这里计算出
因为
在上面的分析过程中,我们只使用了内积。因此当我们把
1.4 如何在主成分方向上投影?
投影时,只需要使用
对于高维空间的数据
1.5 如何Centering 高维空间的数据?
在我们的分析中,协方差矩阵的定义需要centered data。在高维空间中,显式的将
因为我们并不知道
令
不难看出,
其中
对于新的数据,我们同样可以
2. 演示 (R code)
首先我们应该注意输入数据的格式,一般在统计中,我们要求
这与统计上的概念并不矛盾:在前面的定义下协方差矩阵为
另外,在下面的结果中,Gaussian 核函数(kernel function)的标准差(sd)为2。在其他取值条件下,所得到的图像是不同的。
KPCA图片:
源地址:http://zhanxw.com/blog/2011/02/kernel-pca-原理和演示/
R 源代码(Source Code):
# 3 groups of sample, each size is 20N_in_group = 40N_group = 3N_total = N_in_group * N_groupx=matrix(0, ncol = 2, nrow = N_total)label = rep(c(1,2,3), rep(N_in_group,N_group))# 4 graphslayout(matrix(seq(4), 2,2))# use polar coordinate to generate sample# theta ~ UNIF(0, 2pi)r = rep(c(1, 3, 6), rep(N_in_group,N_group))theta = runif(N_total)*2*pix[,1] = (r ) * cos(theta) + rnorm(N_total, sd = .2)x[,2] = (r ) * sin(theta) + rnorm(N_total, sd = .2)plot(x[,1], x[,2], col = rainbow(3)[label], main = "Origin", xlab="First dimension", ylab="Second dimension")X = xXtX = t(X) %*% Xres = eigen(XtX)V = res$vectorsD = diag(res$values)# verify eigen decop# sum(abs(XtX %*% V - V %*% (D)))Y = X%*% Vplot(Y[,1], Y[,2], col = rainbow(3)[label], main = "Traditional PCA" , xlab="First component", ylab="Second component")# Kernel PCA# Polynomial Kernel# k(x,y) = t(x) %*% y + 1k1 = function (x,y) { (x[1] * y[1] + x[2] * y[2] + 1)^2 }K = matrix(0, ncol = N_total, nrow = N_total)for (i in 1:N_total) { for (j in 1:N_total) { K[i,j] = k1(X[i,], X[j,])}}ones = 1/N_total* matrix(1, N_total, N_total)K_norm = K - ones %*% K - K %*% ones + ones %*% K %*% onesres = eigen(K_norm)V = res$vectorsD = diag(res$values)Y = K %*% Vplot(Y[,1], Y[,2], col = rainbow(3)[label], main = "Kernel PCA (Poly)", xlab="First component", ylab="Second component")# Gaussian Kernel# k(x,y) = exp(-sum((x-y)^2)))k2 = function (x,y) { dnorm(norm(matrix(x-y), type="F"))}K = matrix(0, ncol = N_total, nrow = N_total)for (i in 1:N_total) { for (j in 1:N_total) { K[i,j] = k2(X[i,], X[j,])}}ones = 1/N_total* matrix(1, N_total, N_total)K_norm = K - ones %*% K - K %*% ones + ones %*% K %*% onesres = eigen(K_norm)V = res$vectorsD = diag(res$values)Y = K %*% Vplot(Y[,1], Y[,2], col = rainbow(3)[label], main = "Kernel PCA (Gaussian)", xlab="First component", ylab="Second component")
- Kernel PCA 原理和演示
- Kernel PCA 原理和演示
- Kernel PCA 原理和演示
- Kernel PCA 原理和演示
- Kernel PCA 原理和演示
- Kernel PCA 原理和演示
- PCA的数学原理Matlab演示
- kernel PCA
- Kernel PCA
- Kernel PCA
- kernel PCA
- Kernel PCA
- PCA and Kernel PCA
- PCA and kernel PCA
- Kernel Methods (5) Kernel PCA
- PCA原理
- PCA原理
- PCA原理
- dev GridControl笔记
- 13.如何做到要求或禁止在堆中产生你自定义的对象
- 【示例代码】超萌的休闲HTML5小游戏——打地鼠
- 详解jar命令打包生成双击即可运行的Java程序
- 跑通第一个ruby on rails 出现问题及解决方案 参照cloudfoundry docs
- Kernel PCA 原理和演示
- freemarker helloworld
- delphi完美经典--第一、二章
- CEdit 文本垂直居中(单行解决方案)
- android 切割画布(clipRect)详解
- CreateDIBSection创建位图
- libxl创建串口流程分析
- win8离线安装.net 3.5【总结-非原创】
- ChartDirector散点图