PCA不进行分类的动作,而只做做数据预处理,将样本变换到一个容易分类(向最大化方差的方向,principal component axes,投影)的更低维的新的特征空间中。Kernel PCA比PCA多了一步,也即先升维(RBF包括多项式核均是升高到无穷维)再进行投影的动作,因为有些非线性可分的数据集只有在升维的视角下才线性可分。

PCA

  • 均值化的数据:

    ∑ixi=0

    \sum_i\mathrm{x}_i=0

# python
>>> X-np.mean(X, 0)# 一个二维矩阵减去一维向量?对,# 这里用到的技术是numpy中broadcasting(广播机制)
  • 样本协方差矩阵(sample-covariance matrix CC)

    C=1N∑ixixTi=1NXXT

    C=\frac1N\sum_i\mathrm{x}_i\mathrm{x}_i^T=\frac1NXX^T
    其中,XX 的每一列表示一个样本(特征向量)

  • 特征分解

    C=UΛUT=∑αλαuαuTα

    C=U\Lambda U^T=\sum_\alpha \lambda_\alpha\mathbf{u}_\alpha\mathbf{u}_\alpha^T

  • projection or transform

yi=UTkxi

\mathrm{y}_i=U_k^T\mathrm{x}_i

1N∑iyiyTi=1N∑iUTkxixTiUk=UTk(1N∑ixixTi)Uk=UTkCUk=UTkUΛUUTk=Λk

\frac1N\sum_i\mathrm{y}_i\mathrm{y}_i^T=\frac1N\sum_iU_k^T\mathrm{x}_i\mathrm{x}_i^TU_k=U_k^T(\frac1N\sum_i\mathrm{x}_i\mathrm{x}_i^T)U_k=U_k^TCU_k=U_k^TU\Lambda UU_k^T=\Lambda_k

the projected data are de-correlated in this new axis.

  • 重构

    yi=UTkxi⇓Ukyi=UkUTkxi=xi

    \mathrm{y}_i=U_k^T\mathrm{x}_i\\\Downarrow\\ U_k\mathrm{y}_i=U_kU_k^T\mathrm{x}_i=\mathrm{x}_i


import pandas as pd
import numpy as npdf = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data', header=None)
X, y = df.values[:, 1:], df.values[:, 0]# step 1
X -= X.mean(0)## step 2
N = X.shape[0]
C = X.T.dot(X)/N## step 3
Lambda, Q = np.linalg.eig(C)## step 4
k = 3
eigen_pairs = [(Lambda[i], Q[:, i]) for i in range(len(Lambda))]
eigen_pairs = sorted(eigen_pairs, reverse=True, key=lambda k: k[0])
W = np.column_stack((eigen_pairs[i][1] for i in range(k=3)))## step 5
X_pca = X.dot(W)

Kernel PCA

以 Radial Basis Function(RBF) kernel PCA(不同的核,体现在代码上仅仅是一处细微的差别)为例进行说明:

  • 计算核矩阵(相似度矩阵) KK
Kij=k(x(i),x(j))=exp(−γ∥x(i)−x(j)∥2)

K_{ij}=k(x^{(i)},x^{(j)})=\exp(-\gamma\|x^{(i)}-x^{(j)}\|^2)

这是最为常见的RBF(Rational Basis Function)核函数,也有多项式核

Kij=k(x(i),x(j))=(<x(i),x(j)>+θ)p

K_{ij}=k(x^{(i)},x^{(j)})=(+\theta)^p
sigmoid型(hyperbolic tangent)核

Kij=k(x(i),x(j))=tanh(η<x(i),x(j)>+θ)

K_{ij}=k(x^{(i)},x^{(j)})=\tanh(\eta+\theta)
其矩阵形式也即:

K=⎡⎣⎢⎢⎢⎢⎢⎢k(x(1),x(1)),k(x(2),x(1)),⋯,k(x(n),x(1)),k(x(1),x(2)),k(x(2),x(2)),⋯,k(x(n),x(2)),⋯,⋯,⋱,⋯,k(x(1),x(n))k(x(2),x(n))⋯k(x(n),x(n))⎤⎦⎥⎥⎥⎥⎥⎥n×n

K = \begin{bmatrix} k(x^{(1)},x^{(1)}),&k(x^{(1)},x^{(2)}),&\cdots,&k(x^{(1)},x^{(n)})\\ k(x^{(2)},x^{(1)}),&k(x^{(2)},x^{(2)}),&\cdots,&k(x^{(2)},x^{(n)})\\ \cdots,&\cdots,&\ddots,&\cdots\\ k(x^{(n)},x^{(1)}),&k(x^{(n)},x^{(2)}),&\cdots,&k(x^{(n)},x^{(n)}) \end{bmatrix}_{n\times n}

  • center the KK
K′=K−1nK−K1n+1nK1n

K'=K-\mathbf{1}_nK-K\mathbf{1}_n+\mathbf{1}_nK\mathbf{1}_n

其中 1n\mathbf{1}_n是 n×nn\times n 的元素值全为1n\frac1n矩阵。

  • 对 K′K'进行特征值分解,获得对应于前 kk个特征值的特征向量。与标准PCA算法不同的是,这里获得特征向量不再是 principal component axes,而已经是全部样本在这些轴上的投影了,也即是我们所需的进行降维后的数据了。

这里为了验证核机制的性能,我们在如下的数据集上进行测试:

from sklearn.datasets import make_moonsX, y = make_moons(n_samples=200, random_state=123)
plt.scatter(X[y==0, 0], X[y==0, 1], colors='r', marker='^', alpha=.4)
plt.scatter(X[y==1, 0], X[y==1, 1], colors='b', marker='o', alpha=.4)

from scipy.spatial.distance import pdist, squareformdef rbf_kpca(X, gamma, k):sq_dist = pdist(X, metric='sqeuclidean')# N = X.shape[0]    # sq_dist.shape = N*(N-1)/2mat_sq_dist = squareform(sq_dist)# mat_sq_dist.shape = (N, N)# step 1K = np.exp(-gamma*mat_sq_dist)# step 2N = X.shape[0]one_N = np.ones((N, N))/NK = K - one_N.dot(K) - K.dot(one_N) + one_N.dot(K).dot(one_N)# step 3Lambda, Q = np.linalg.eig(K)eigen_pairs = [(Lambda[i], Q[:, i]) for i in range(len(Lambda))]eigen_pairs = sorted(eigen_pairs, reverse=True, key=lambda k: k[0])return np.column_stack((eigen_pairs[i][1] for i in range(k)))

调用:

X_kpca = rbf_kpca(X, gamma=15, k=2)

一个非线性可分的数据集

from sklearn.datasets import make_circles
X, y = make_circles(n_samples=1000, noise=.1, factor=.2, random_state=123)
plt.scatter(X[y==0, 0], X[y==0, 1], color='r', marker='^', alpha=.4)
plt.scatter(X[y==1, 0], X[y==1, 1], color='b', marker='o', alpha=.4)
plt.show()

在这样的一个非线性可分的数据集,显然如何找到最大方差的方向都不可能使最后的数据集线性可分。接下来,我们探讨KPCA的核机制是如何工作的,使线性不可分的数据集变得线性可分

应用kernel trick:

X_kpca = rbf_kpca(X, gamma=15, k=2)

可视化:

fig, ax = plt.subplots(1, 2, figsize=(8, 4))ax[0].scatter(X_kpca[y==0, 0], X_kpca[y==0, 1], color='r', marker='^', alpha=.4)
ax[0].scatter(X_kpca[y==1, 0], X_kpca[y==1, 1], color='b', marker='o', alpha=.4)label_count = np.bincount(y)# 统计各类别出现的次数# label_count[0] = 500# label_count[1] = 500
ax[1].scatter(X_kpca[y==0, 0], np.zeros(label_count[0]), color='r')
ax[1].scatter(X_kpca[y==1, 0], np.zeros(label_count[1]), color='b')# y轴置零# 投影到x轴
ax[1].set_ylim([-1, 1])
ax[0].set_xlabel('PC1')
ax[0].set_ylabel('PC2')
ax[1].set_xlabel('PC1')plt.show()

PCA 与 KPCA 的另一点重要不同

不同在于对数据、样本(当然还是同一类型数据,比如测试样本之于训练样本)的转换方式不同;

标准PCA算法,转换矩阵(transformation matrix Wd×kW_{d\times k})对应于训练样本的协方差矩阵的特征向量,使用 WW 可继续作用于新的数据集,x′1×d⋅Wd×kx'_{1\times d}\cdot W_{d\times k}。而KPCA,KK 的特征向量(Ka=λα{Ka}=\lambda\alpha 中的 α\alpha)即为变换后的样本。
对于新的样本,我们想要计算:

ϕ(x′)Tv

\phi(x')^Tv

而特征向量 v=∑ia(i)ϕ(x(i))v=\sum\limits_ia^{(i)}\phi(x^{(i)}),则:

ϕ(x′)Tv=∑ia(i)ϕ(x′)Tϕ(x(i))=∑ia(i)k(x′,x(i))

\phi(x')^Tv=\sum_ia^{(i)}\phi(x')^T\phi(x^{(i)})=\sum_ia^{(i)}k(x',x^{(i)})

from scipy.spatial.distance import sqdist, squareformdef rbf_kpca(X, gamma, k):sq_dists = sqdist(X, metric='sqeuclidean')mat_sq_dists = squareform(sq_dists)K = np.exp(-gamma*mat_sq_dists)N = X.shape[0]one_N = np.ones((N, N))/NK = K-one_N.dot(K)-K.dot(one_N)+one_N.dot(K).dot(one_N)Lambda, Q = np.linalg.eigh(K)alphas = np.column_stack((Q[:, -i]for i in range(1, 1+k)))lambdas = [Lambda[-i] for i in range(1, k+1)]return alphas, lambdasdef proj_new(X_new, X, gamma, alphas, lambdas):k = np.exp(-gamma*np.sum((X-X_new)**2, 1))return k.dot(alphas/lambdas)# alphas/lambdas,归一化后的alphasX, y = make_moons(n_samples=100, random_state=123)# 设置random_state,为了可重复性
alphas, lambdas = rbf_kpca(X, gamma=15, k=1)
X_new = X[25]# 以当前样本的某一样本作为新的样本进行测试
X_proj = proj_new(X_new, X, gamma=15, alphas, lambdas)
print(alphas[25])
print(X_proj)# [-0.07877284]# [-0.07877284]

从PCA到Kernel PCA(Python)相关推荐

  1. 核PCA(Kernel PCA)学习笔记

    感谢大佬们的文章 1.(46条消息) Gram矩阵_wangyang20170901的博客-CSDN博客_gram矩阵 2.数据降维: 核主成分分析(Kernel PCA)原理解析 - 知乎 ---- ...

  2. Missing Data in Kernel PCA

    目录 引 主要内容 关于缺失数据的导数 附录 极大似然估计 代码 Sanguinetti G, Lawrence N D. Missing data in kernel PCA[J]. europea ...

  3. 数学建模:评价模型——主成分分析 PCA SPSS实现、python实现

    文章目录 PCA介绍 SPSS实现 python实现 简单的主成分分析 主成分分析用于综合评价 Notice PCA介绍 主成分分析(Principal Component Analysis,PCA) ...

  4. PCA算法原理及python实现

    [原理]PCA算法原理 1.PCA算法 PCA(principal Component Analysis),即主成分分析方法,是一种使用最广泛的数据压缩算法.在PCA中,数据从原来的坐标系转换到新的坐 ...

  5. 主成分分析(PCA)原理及其python实现

    主成分分析 一.概述 1.1 问题提出 1.2 降维的作用 二.主成分分析(PCA)主要思想 三.相关数学知识 四.PCA实现步骤 4.1 特征值分解矩阵 4.2 SVD分解协方差矩阵 五.pytho ...

  6. PCA分析法的python主要代码

    一 PCA分析法介绍 可以理解为是一种降维的思想,将M列数据降维成对应的N列数据,用主要的几个字段解释整体方差变异 也可以理解为一种低维度的映射,举例将三维的数据找到一个二维映射面,同时可以尽力解释出 ...

  7. 【火炉炼AI】机器学习053-数据降维绝招-PCA和核PCA

    [火炉炼AI]机器学习053-数据降维绝招-PCA和核PCA (本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplo ...

  8. PCA主成分分析(PCA降维)

    PCA主成分分析 PCA任务介绍 公式推导 算法实现 降维是对数据高维度特征的一种预处理方法. 降维是将高维度的数据保留下最重要的一些特征,去除噪声和不重要的特征,从而实现提升数据处理速度的目的.在实 ...

  9. PCA 与 Robust PCA区别

    之前的一篇博客对PCA的原理.特点进行了介绍以及用python实现了PCA.本篇博客对PCA和Robust PCA进行简单的区别. 1.PCA 主成分分析(PCA)可以有效的找出数据中最重要的元素和结 ...

最新文章

  1. C语言关键字、标识符和注释
  2. caffe中权值初始化方法
  3. mybatis的bean注入出现警告
  4. python中ioerror怎么解决_Python IOError错误异常原因|python基础教程|python入门|python教程...
  5. Mjpeg‐stream移植
  6. 一步一步写算法(之克鲁斯卡尔算法 中)
  7. 走进rxjs的世界 - 万物皆流 - Everything is a stream
  8. Java 8 Friday Goodies:Lambda和SQL
  9. 【转】EntityFramework使用Code First模式创建数据库控制生成单数形式的表名
  10. (转)一段挺好的领导者应该记得的话
  11. Android 中.aar文件生成方法与用法
  12. 漫画:应用程序被拖慢?罪魁祸首是 Log4j!
  13. 自学python还是c4d_C4D到底需要学多久?要学到什么程度?
  14. Jupyter Notebook的三大短板,都被这个新工具补齐了
  15. CSS —— 多媒体查询
  16. 以下数据库收录外文文献全文的有_除了SCIHUB,这十大外文文献下载数据库也应该一试!...
  17. ESP8266 Arduino 串口监控器有什么用
  18. 《Java从入门到放弃》JavaSE入门篇:变量
  19. html a标签 alt,A标签、IMG标签、ALT属性详解
  20. 虚拟机启动失败-Intel VT-x 处于禁用状态 的解决方案

热门文章

  1. JSP中application的用法
  2. CUDA算法——Stream and Event
  3. android内容提供器读取图片,android实现拍照或从相册选取图片
  4. 马士兵_JAVA自学之路(为那些目标模糊的码农们)
  5. TCP/IP笔记 三.运输层(3)——TCP超时重传算法
  6. C#面向对象方式设置、读取应用配置
  7. 安装阿里Java代码规约插件
  8. jsp___jstl标签
  9. 【转】现代浏览器的工作原理
  10. 【转】基础知识系列2--线性表之链表