声明:版权所有,转载请联系作者并注明出处:
http://blog.csdn.net/u013719780?viewmode=contents

知乎专栏:
https://www.zhihu.com/people/feng-xue-ye-gui-zi

前面两篇文章详细讲解了线性判别分析LDA,说到LDA,就不能不提到主成份分析,简称为PCA,是一种非监督学习算法,经常被用来进行数据降维、有损数据压缩、特征抽取、数据可视化(Jolliffe, 2002)。它也被称为Karhunen-Loève变换。

1. PCA原理

PCA的思想是将n

维特征映射到k维空间上k<n,这k维特征是全新的正交特征,是重新构造出来的k维特征,而不是简单地从n维特征中去除其余n−k

维特征。那么如何衡量投影向量的优劣呢?在数学上有三种方法衡量投影的优劣!PCA可以被定义为数据在低维线性空间上的正交投影,这个线性空间被称为主⼦空间(principal subspace),使得投影数据的⽅差被最⼤化(Hotelling, 1933),即最大方差理论。等价地,它也可以被定义为使得平均投影代价最⼩的线性投影,即最小误差理论。平均投影代价是指数据点和它们的投影之间的平均平⽅距离(Pearson, 1901)。还有另一个理论也可以解释PCA原理,即坐标轴相关度理论。这里简单探讨前两种,最后一种在讨论PCA意义时简单概述。

1.1 最大方差理论

在信号处理中认为信号具有较大的方差,噪声有较小的方差,信噪比就是信号与噪声的方差比,越大越好。因此我们认为,最好的k

维特征是将n维样本点变换为k

维后,每一维上的样本方差都尽可能的大。

首先,考虑在一维空间 (k=1) 上的投影。我们可以使用 n

维向量u定义这个空间的方
向。为了方便(并且不失一般性),我们假定选择一个单位向量,从而 uTu=1 (注意,我们只对u的方向感兴趣,而对 u

本身的大小不感兴趣)。

如上图所示,红色点表示原样本点x(i)

,u是蓝色直线的斜率也是直线的方向向量,而且是单位向量,直线上的蓝色点表示原样本点x(i)在u上的投影。容易知道投影点离原点的距离是x(i)Tu

,由于这些原始样本点的每一维特征均值都为0,因此投影到u上的样本点的均值仍然是0。

假设原始数据集为Xmxn

,我们的目标是找到最佳的投影空间Wnxk=(w1,w2,…,wk),其中wi是单位向量且wi与wj(i≠j)正交, 何为最佳的W?就是原始样本点投影到W

上之后,使得投影后的样本点方差最大。

由于投影后均值为0,因此投影后的总方差为:

1m∑i=1m(x(i)Tw)2=1m∑i=1mwTx(i)x(i)Tw=∑i=1mwT(1mx(i)x(i)T)w1

1mx(i)x(i)T

是不是似曾相识,没错,它就是原始数据集X的协方差矩阵(因为x(i)的均值为0,因为无偏估计的原因,一般协方差矩阵除以m−1

,这里用m)。

记λ=1m∑mi=1(x(i)Tw)2

, ∑=1mx(i)x(i)T

, 则有

λ=wT∑w

.

上式两边同时左乘w

,注意到wwT=1

(单位向量),则有

λw=∑w

.

所以w

是矩阵∑

的特征值所对应的特征向量。

欲使投影后的总方差最大,即λ

最大,因此最佳的投影向量w是特征值λ最大时对应的特征向量,因此,当我们将w设置为与具有最大的特征值λ

的特征向量相等时,方差会达到最大值。这个特征向量被称为第一主成分。

我们可以用一种增量的方式定义额外的主成分,方法为:在所有与那些已经考虑过的方向正交的所有可能的方向中,将新的方向选择为最大化投影方差的方向。如果我们考虑 k

维投影空间的一般情形,那么最大化投影数据方差的最优线性投影由数据协方差矩阵 ∑ 的 k 个特征向量 w1,...,wk 定义,对应于 k 个最大的特征值 λ1,...,λk

。可以通过归纳法很容易地证明出来。

因此,我们只需要对协方差矩阵进行特征值分解,得到的前k

大特征值对应的特征向量就是最佳的k维新特征,而且这k维新特征是正交的。得到前k个u以后,原始数据集X

通过变换可以得到新的样本。

PCA算法流程

算法输入:数据集Xmxn

* 按列计算数据集X的均值Xmean,然后令Xnew=X−Xmean;
* 求解矩阵Xnew的协方差矩阵,并将其记为Cov;
* 计算协方差矩阵COv的特征值和相应的特征向量;
* 将特征值按照从大到小的排序,选择其中最大的k个,然后将其对应的k个特征向量分别作为列向量组成特征向量矩阵Wnxk;
* 计算XnewW,即将数据集Xnew投影到选取的特征向量上,这样就得到了我们需要的已经降维的数据集XnewW

注意,计算一个nxn

矩阵的完整的特征向量分解的时间复杂度为 O(n3) 。如果我们将数据集投影到前 k 个主成分中,那么我们只需寻找前 k 个特征值和特征向量。这可以使用更高效的方法得到,例如幂方法(power method) (Golub and Van Loan, 1996),它的时间复杂度为 O(kn2)

,或者我们也可以使用 EM 算法。

1.2 最小平方误差理论

如上图所示,假设有这样的二维样本点(红色点),按照前文我们讲解的最大方差理论,我们的目标是是求一条直线,使得样本点投影到直线或者平面上的点的方差最大。本质是求直线或者平面,那么度量直线求的好不好,不仅仅只有方差最大化的方法。再回想我们最开始学习的线性回归等,目的也是求一个线性函数使得直线能够最佳拟合样本点,那么我们能不能认为最佳的直线就是回归后的直线呢?回归时我们的最小二乘法度量的是样本点到直线的坐标轴距离。比如这个问题中,特征是x,类标签是y。回归时最小二乘法度量的是距离d。如果使用回归方法来度量最佳直线,那么就是直接在原始样本上做回归了,跟特征选择就没什么关系了。

因此,我们打算选用另外一种评价直线好坏的方法,使用点到直线的距离d′

来度量。

现在有m

个样本点x(1),...,x(m),每个样本点为n维。将样本点x(i)在直线上的投影记为x(1)′

,那么我们就是要最小化

∑i=1m(x(i)′−x(i))2

这个公式称作最小平方误差(Least Squared Error)。

初中我们就已经知道确定一条直线,只需要知道直线经过某一个点和其方向即可。

首先,我们确定直线经过的点,假设要在空间中找一点x0

来代表这m个样本点,“代表”这个词不是量化的,因此要量化的话,我们就是要找一个n维的点x0

,使得

J0(x0)=∑i=1m(x0−x(i))2

最小。其中J0(x0)

是平方错误评价函数(squared-error criterion function),假设x¯为m

个样本点的均值,即

x¯=1m∑i=1mx(i)

J0(x0)=∑i=1m(x0−x(i))2=∑i=1m((x0−x¯)−(x(i)−x¯))2=∑i=1m(x0−x¯)2−2∑i=1m(x0−x¯)T(x(i)−x¯)+∑i=1m(x(i)−x¯)2=∑i=1m(x0−x¯)2−2(x0−x¯)T∑i=1m(x(i)−x¯)+∑i=1m(x(i)−x¯)2=∑i=1m(x0−x¯)2+∑i=1m(x(i)−x¯)2

显然,上式的第二项与x0

无关,因此,J0(x0)在x¯

处有最小值。

接下来,我们确定直线的方向向量。我们已经知道直线经过点x¯

,假设直线的方向是单位向量e⃗ 。那么直线上任意一点x(i)′

有:

x(i)′=x¯+aie⃗

其中,ai

是x(i)′到点x¯

的距离。

我们重新定义最小平方误差:

J1(a1,a2,...,am,e⃗ )=∑i=1m(x(i)′−x(i))2=∑i=1m((x¯+aie⃗ )−x(i))2=∑i=1m(aie⃗ −(x(i)−x¯))2=∑i=1ma2ie⃗ 2−2∑i=1maie⃗ T(x(i)−x¯)+∑i=1m(x(i)−x¯)2

我们首先固定e⃗

,将其看做是常量,然后令J1 关于 ai

的导数等于0,则有:

ai=e⃗ T(x(i)−x¯),

这个结果意思是说,如果知道了e⃗

,那么将(x(i)−x¯)与e⃗ 做内积,就可以知道了x(i)在e⃗ 上的投影离x¯

的长度距离,不过这个结果不用求都知道。

然后是固定ai

,对e⃗ 求偏导数,我们先将 ai代入J1

,得

J1(e⃗ )=∑i=1ma2ie⃗ 2−2∑i=1maie⃗ T(x(i)−x¯)+∑i=1m(x(i)−x¯)2=∑i=1ma2ie⃗ 2−2∑i=1ma2i+∑i=1m(x(i)−x¯)2=−∑i=1m(e⃗ T(x(i)−x¯))2+∑i=1m(x(i)−x¯)2=−∑i=1me⃗ T(x(i)−x¯)(x(i)−x¯)Te⃗ +∑i=1m(x(i)−x¯)2=−e⃗ TSe⃗ +∑i=1m(x(i)−x¯)2

其中S=∑mi=1(x(i)−x¯)(x(i)−x¯)T

,与协方差矩阵类似,只是缺少个分母n−1

,我们称之为散列矩阵(scatter matrix)。

现在我们就可以用拉格朗日乘数法求解方向向量e⃗

了。令

f(e⃗ )=−e⃗ TSe⃗ +∑i=1m(x(i)−x¯)2+λ(e⃗ Te⃗ −1)

令上式关于e⃗

的偏导数等于0,则可得

Se⃗ =λe⃗

两边除以n−1

就变成了对协方差矩阵求特征值向量了。

从不同的思路出发,最后得到同一个结果,对协方差矩阵求特征向量,求得后特征向量上就成为了新的坐标,如下图:

这时候点都聚集在新的坐标轴周围,因为我们使用的最小平方误差的意义就在此。另外,PRML书上从线性子空间的角度进行了详细的阐述,有兴趣的读者可以看看。

2. PCA算法优缺点:

优点:

  • 它是无监督学习,完全无参数限制的。在PCA的计算过程中完全不需要人为的设定参数或是根据任何经验模型对计算进行干预,最后的结果只与数据相关,与用户是独立的。

  • 用PCA技术可以对数据进行降维,同时对新求出的“主元”向量的重要性进行排序,根据需要取前面最重要的部分,将后面的维数省去,可以达到降维从而简化模型或是对数据进行压缩的效果。同时最大程度的保持了原有数据的信息。

  • 各主成分之间正交,可消除原始数据成分间的相互影响。

  • 计算方法简单,易于在计算机上实现。

缺点:

  • 如果用户对观测对象有一定的先验知识,掌握了数据的一些特征,却无法通过参数化等方法对处理过程进行干预,可能会得不到预期的效果,效率也不高。

  • 贡献率小的主成分往往可能含有对样本差异的重要信息。

  • 特征值矩阵的正交向量空间是否唯一有待讨论。

  • 在非高斯分布的情况下,PCA方法得出的主元可能并不是最优的,此时在寻找主元时不能将方差作为衡量重要性的标准。

    3. 代码实现

from __future__ import print_function
from sklearn import datasets
import matplotlib.pyplot as plt
import matplotlib.cm as cmx
import matplotlib.colors as colors
import numpy as np
%matplotlib inlinedef shuffle_data(X, y, seed=None):if seed:np.random.seed(seed)idx = np.arange(X.shape[0])np.random.shuffle(idx)return X[idx], y[idx]# 正规化数据集 X
def normalize(X, axis=-1, p=2):lp_norm = np.atleast_1d(np.linalg.norm(X, p, axis))lp_norm[lp_norm == 0] = 1return X / np.expand_dims(lp_norm, axis)# 标准化数据集 X
def standardize(X):X_std = np.zeros(X.shape)mean = X.mean(axis=0)std = X.std(axis=0)# 做除法运算时请永远记住分母不能等于0的情形# X_std = (X - X.mean(axis=0)) / X.std(axis=0) for col in range(np.shape(X)[1]):if std[col]:X_std[:, col] = (X_std[:, col] - mean[col]) / std[col]return X_std# 划分数据集为训练集和测试集
def train_test_split(X, y, test_size=0.2, shuffle=True, seed=None):if shuffle:X, y = shuffle_data(X, y, seed)n_train_samples = int(X.shape[0] * (1-test_size))x_train, x_test = X[:n_train_samples], X[n_train_samples:]y_train, y_test = y[:n_train_samples], y[n_train_samples:]return x_train, x_test, y_train, y_test# 计算矩阵X的协方差矩阵
def calculate_covariance_matrix(X, Y=np.empty((0,0))):if not Y.any():Y = Xn_samples = np.shape(X)[0]covariance_matrix = (1 / (n_samples-1)) * (X - X.mean(axis=0)).T.dot(Y - Y.mean(axis=0))return np.array(covariance_matrix, dtype=float)# 计算数据集X每列的方差
def calculate_variance(X):n_samples = np.shape(X)[0]variance = (1 / n_samples) * np.diag((X - X.mean(axis=0)).T.dot(X - X.mean(axis=0)))return variance# 计算数据集X每列的标准差
def calculate_std_dev(X):std_dev = np.sqrt(calculate_variance(X))return std_dev# 计算相关系数矩阵
def calculate_correlation_matrix(X, Y=np.empty([0])):# 先计算协方差矩阵covariance_matrix = calculate_covariance_matrix(X, Y)# 计算X, Y的标准差std_dev_X = np.expand_dims(calculate_std_dev(X), 1)std_dev_y = np.expand_dims(calculate_std_dev(Y), 1)correlation_matrix = np.divide(covariance_matrix, std_dev_X.dot(std_dev_y.T))return np.array(correlation_matrix, dtype=float)class PCA():"""主成份分析算法PCA,非监督学习算法."""def __init__(self):self.eigen_values = Noneself.eigen_vectors = Noneself.k = 2def transform(self, X):""" 将原始数据集X通过PCA进行降维"""covariance = calculate_covariance_matrix(X)# 求解特征值和特征向量self.eigen_values, self.eigen_vectors = np.linalg.eig(covariance)# 将特征值从大到小进行排序,注意特征向量是按列排的,即self.eigen_vectors第k列是self.eigen_values中第k个特征值对应的特征向量idx = self.eigen_values.argsort()[::-1]eigenvalues = self.eigen_values[idx][:self.k]eigenvectors = self.eigen_vectors[:, idx][:, :self.k]# 将原始数据集X映射到低维空间X_transformed = X.dot(eigenvectors)return X_transformeddef main():# Load the datasetdata = datasets.load_iris()X = data.datay = data.target# 将数据集X映射到低维空间X_trans = PCA().transform(X)x1 = X_trans[:, 0]x2 = X_trans[:, 1]cmap = plt.get_cmap('viridis')colors = [cmap(i) for i in np.linspace(0, 1, len(np.unique(y)))]class_distr = []# Plot the different class distributionsfor i, l in enumerate(np.unique(y)):_x1 = x1[y == l]_x2 = x2[y == l]_y = y[y == l]class_distr.append(plt.scatter(_x1, _x2, color=colors[i]))# Add a legendplt.legend(class_distr, y, loc=1)# Axis labelsplt.xlabel('Principal Component 1')plt.ylabel('Principal Component 2')plt.show()if __name__ == "__main__":main()

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013719780/article/details/78352262

从零开始实现主成分分析(PCA)算法相关推荐

  1. 主成分分析|PCA算法大全

    主成分分析|PCA算法大全 文章目录 主成分分析|PCA算法大全 1. PCA原理 1.1 最大方差理论 1.2 最小平方误差理论 1.3 高维数据下的特征值分解 2. CCIPCA增量主元分析算法[ ...

  2. 机器学习--主成分分析PCA算法:为什么去均值以后的高维矩阵乘以其协方差矩阵的特征向量矩阵就是“投影”?

    原文链接:主成分分析PCA算法:为什么去均值以后的高维矩阵乘以其协方差矩阵的特征向量矩阵就是"投影"?_天下对手教会少林武僧-CSDN博客_pca投影矩阵 这是从网上看到的PCA算 ...

  3. 机器学习-降维之主成分分析PCA算法原理及实战

    主成分分析 前言 近年来,随着互联网和信息行业的发展,数据已经渗透到各行各业,成为重要的生产因素如数据记录和属性规模的急剧增长.社会已经进入大数据时代,数据越多越好似乎已经成为公理.然而,数据量并不是 ...

  4. 主成分分析PCA算法:为什么去均值以后的高维矩阵乘以其协方差矩阵的特征向量矩阵就是“投影”?

    这是从网上看到的PCA算法的步骤: 第一步,分别求每列的平均值,然后对于所有的样例,都减去对应的均值. 第二步,求特征协方差矩阵. 第三步,求协方差的特征值-显示全部 关注者 1,218 被浏览 78 ...

  5. 用通俗易懂的方式讲解:主成分分析(PCA)算法及案例(Python 代码)

    文章目录 知识汇总 加入方式 一.引入问题 二.数据降维 三.PCA基本数学原理 3.1 内积与投影 3.2 基 3.3 基变换的矩阵表示 3.4 协方差矩阵及优化目标 3.5 方差 3.6 协方差 ...

  6. 图解主成分分析PCA算法(附Python实现)

    0 写在前面 机器学习强基计划聚焦深度和广度,加深对机器学习模型的理解与应用."深"在详细推导算法模型背后的数学原理:"广"在分析多个机器学习模型:决策树.支持 ...

  7. 主成分分析 PCA算法

    夹角余弦是用原始数据定义的. 如果改用与样本平均值的比较值, 就是所谓的相似系数rkl (有的文献中也称为相关系数).     rkl构成的矩阵为相似矩阵,多用于Q型分析.式中求和对特征进行(列标处的 ...

  8. 【人脸识别】基于主成分分析PCA算法人脸识别门禁系统含Matlab源码

    1 简介 人脸是反应人身份的最直接的,最可靠的信息资源.通过人脸我们可以很快辨识一个人,这就是所谓的人脸识别.最初的人脸研究人员是一些从事社会心理学的工作者,从20世纪50年代开始有一些文献资料陆续发 ...

  9. 【视频】主成分分析PCA降维方法和R语言分析葡萄酒可视化实例|数据分享

    最近我们被客户要求撰写关于主成分分析PCA的研究报告,包括一些图形和统计输出.降维技术之一是主成分分析 (PCA) 算法,该算法将可能相关变量的一组观察值转换为一组线性不相关变量.在本文中,我们将讨论 ...

最新文章

  1. Docker学习(六)-----Docker数据卷
  2. 14条建议 使你的IT职业生涯更上一层楼
  3. 用Vue框架和后台请求的时候传递的参数的方式
  4. 云南省2021高考成绩排名查询,2020年云南高考成绩位次排名及一分一段表查询
  5. Hadoop Distributed File System 简介
  6. 银行业AI:炒作背后的现实——“尽管对新技术感到兴奋,但银行业态度非常谨慎”
  7. 卷积神经网络学习指南_卷积神经网络的直观指南
  8. 如何去除chrome最常访问的网页
  9. 阐述SDN的原理、SDN使用场景、SDN技术的优缺点、SDN发展现状及分析SDN对社会和环境的影响
  10. The car's gossip
  11. 分数阶微积分学薛定宇电子版_分数阶微积分学与分数阶控制 pdf epub mobi txt 下载...
  12. FIL会不会涨,至联云教你看这三点就知道
  13. 关于虚拟机非正常关机的解决方案
  14. 魔兽世界6.2.2德拉诺怎么飞行 wow飞行成就获得方法
  15. Supervised pre-trainning有监督预训练
  16. Dism解决win 10访问服务器共享问题,共享需要过时的SMB1协议,安装时错误代码:0x800736B3
  17. setTimeout原理
  18. php加入语音播报功能_PHP实现语音播报功能
  19. 盗墓笔记讲的什么秘密_为什么组织有公开的秘密?
  20. 立志做文艺小清新的技术宅

热门文章

  1. boost::rational模块相关的测试程序
  2. boost::mp11::mp_drop相关用法的测试程序
  3. boost::hana::intersection用法的测试程序
  4. boost::hana模块使用 Hana 实现基本维度分析的示例
  5. boost::hana::make_map用法的测试程序
  6. boost::fusion::joint_view用法的测试程序
  7. Boost:bind绑定和数据成员以及高级用途的测试程序
  8. ITK:在保留边缘的同时使图像平滑
  9. C语言字符串中最后一个单词的长度的算法(附完整源码)
  10. C语言unit test单元测试类的实现(附完整源码)