
我们先从主因素 剖析 PCA最先 看。在诠释 这个要领之前,我们先快速回首一下什么是特征的降维。在机械学习领域中,我们要举行 大量的特征工程,将物品的特征转换成盘算机所能处置赏罚 的种种数据。通常,若是 我们增添 物品的特征,就有可能提升机械学习的效果。可是,随着特征数目 一直 增添 ,特征向量的维数也会一直 升高。这不仅会加大机械学习的难度,还会形成过拟合,影响最终的准确度。针对这种情形,我们需要过滤掉一些不主要 的特征,或者是将某些相关的特征合并起来,最终到达在降低特征维数的同时,只管 保留原始数据所包罗的信息。相识 了这些配景信息,我们再来看PCA要领。本节先从它的运算步骤入手讲清晰 每一步,再诠释 其背后的焦点头脑 。
14.1.1 PCA的主要步骤和协同过滤的案例一样,我们使用一个矩阵来体现数据集。我们假设数据集中有
个样本、
维特征,而这些特征都是数值型的,那么这个荟萃可以凭证 如表14-1所示的方式来展示。
表14-1 数据纪录及其特征
样本ID
特征1
特征2
特征3
...
特征
特征
1
1
3
−7
...
−10.5
−8.2
2
2
5
−14
...
2.7
4
...
...
...
...
...
...
...
−3
−7
2
...
55
13.6
那么这个样本集的矩阵形式就是这样的:
这个矩阵是
维的,其中每一行体现一个样本,每一列体现一维特征。我们将这个矩阵称为样本矩阵,现在我们的问题是能不能通过某种要领找到一种变换,其可以镌汰 这个矩阵的列数,也就是特征的维数,而且尽可能保留原始数据中的有用信息?针对这个问题,PCA要领提出了一种可行的解决方案。它包罗以下4个主要的步骤。
(1)尺度化样本矩阵中的原始数据。
(2)获取尺度化数据的协方差矩阵。
(3)盘算协方差矩阵的特征值和特征向量。
(4)遵照 特征值的巨细挑选主要的特征向量,以转换原始数据并天生 新的特征。
1.尺度化样本矩阵中的原始数据之前我们已经先容 过基于Z分数的特征尺度化,这里我们需要举行 同样的处置赏罚 才气让每维特征的主要 性具有可比性。需要注重 的是,这里尺度化的数据是针对统一 种特征,也是在统一 个特征维度之内。差异维度的特征不能放在一起举行 尺度化。
2.获取尺度化数据的协方差矩阵首先,我们来看一下什么是协方差(covariance),以及协方差矩阵。协方差用于权衡两个变量的总体误差。假设两个变量划分是
和
,而它们的采样数目 都是
,那么协方差的盘算公式就是如下这种形式:
其中,
体现变量
的第
个采样数据,
体现这
个采样的均值。当两个变量是统一 个变量时,协方差就酿成了方差。
那么,协方差矩阵又是什么呢?我们刚刚提到了样本矩阵,假设
体现样本矩阵
的第1列,
体现样本矩阵
的第2列,依次类推。
体现第1列向量和自身的协方差,
体现第1列向量和第2列向量之间的协方差。团结 之前协方差的界说,我们可以得知:
其中,
体现矩阵中第
行、第
列的元素。
体现第
列的均值。有了这些符号体现,我们就可以天生 下面这种协方差矩阵:
从协方差的界说可以看出,
,以是
是个对称矩阵。另外,我们刚刚提到,对
而言,若是
,那么
也就是
这组数的方差。以是 这个对称矩阵的主对角线上的值就是各维特征的方差。
3.盘算协方差矩阵的特征值和特征向量这里所说的矩阵的特征向量(eigenvector)和机械学习中的特征向量(feature vector)完全是两回事。矩阵的特征值和特征向量是线性代数中两个很是主要 的看法。对于一个矩阵
,若是 能找到向量
和标量
,使得下面这个式子建设:
那么,我们就说
是矩阵
的特征向量,而
是矩阵
的特征值。矩阵的特征向量和特征值可能不止一个。说到这里,你可能会好奇,特征向量和特征值体现什么意思呢?我们为什么要体贴这两个看法呢?简朴来说,我们可以将向量
左乘一个矩阵
看尴尬刁难
举行 旋转或伸缩,如我们之前所先容 的,这种旋转和伸缩都是由于左乘矩阵
后发生的“运动”导致的。特征向量
体现矩阵
运动的偏向,特征值
体现运动的幅度,这两者团结 就能形貌 左乘矩阵X所带来的效果,因此被看作矩阵的“特征”。PCA中的主因素 就是指特征向量,对应的特征值的巨细就体现这个特征向量或者说主因素 的主要 水平。特征值越大,主要 水平越高,越要优先使用这个主因素 ,并使用 这个主因素 对原始数据举行 转换。
我们先来看看给定一个矩阵,怎样 盘算它的特征值和特征向量,并完成PCA的剩余步骤。盘算特征值的推导历程如下:
其中,
是单元矩阵。对于上面推导中的最后一步,需要盘算矩阵的行列式:
最后,通过解这个方程式,我们就能求得种种
的解,而这些解就是特征值。盘算完特征值,我们可以将差异的
值代入
来获取特征向量。
4.遵照 特征值的巨细挑选主要的特征向量假设我们获得了
个特征值和对应的特征向量,就会有:
凭证 所对应的
数值的巨细,对这
组的
排序。排名靠前的
就是最主要 的特征向量。假设我们只取
个特征中前
个最主要 的特征,那么我们使用这
个特征向量,组成一个
维的矩阵
。将包罗原始数据的
维矩阵
左乘矩阵
,就能重新获得一个
维的矩阵,从而到达降维的目的。
有的时间 ,我们无法确定
取几多合适。一种常见的做法是,看前
个特征值的和占所有特征值总和的百分比。假设一共有10个特征值,总和是100,最大的特征值是80,那么第一大特征值占整个特征值总和的80%,我们就以为 它能体现80%的信息量,若是 还不够多,我们就继续看第二大的特征值,它是15,前两个特征值之和是95,占比到达了95%,若是 我们以为 足够了,那么就可以只选前两大特征值,将原始数据的特征维数从10维降到2维。
所有这些形貌 可能有一些抽象,让我们实验一个详细 的案例。假设我们有一个样本荟萃,包罗了3个样本,每个样本有3维特征
、
和
,对应的矩阵如下:
在尺度化的时间 ,需要注重 的是,我们的分母都使用
而不是
,这是为了和之后Python中sklearn库的默认实现保持一致。首先需要获取尺度化之后的数据。第一维特征的数据是
,均值是
,方差是
。以是 ,尺度化之后第一维特征的数据是
,
,
。以此类推,我们可以获得第二维和第三维特征尺度化之后的数据。虽然,所有 手工盘算的事情量不小,这时可以让盘算机做它善于 的事情:重复性盘算。代码清单14-1展示了怎样 对样本矩阵的数据举行 尺度化。
代码清单14-1 矩阵尺度化
import numpy as npfrom numpy import linalg as LAfrom sklearn.preprocessing import scale# 原始数据,包罗了3个样本和3个特征,每一行体现一个样本,每一列体现一维特征x = np.mat([[1, 3, -7], [2, 5, -14], [-3, -7, 2]])# 矩阵按枚举 行 尺度化x_std = scale(x, with_mean=True, with_std=True, axis=0)print('尺度化后的矩阵:\n', x_std, '\n')其中,scale函数使用了
,体现对枚举 行 尺度化,由于 现在 的矩阵排列中,每一列代表一个特征维度,这一点需要注重 。若是 矩阵排列中每一行代表一个特征维度,那么可以使用
对行举行 尺度化。最终尺度化之后的矩阵是这样的:
接下来是协方差的盘算。对于第一维向量的方差是
。第二维和第二维向量之间的协方差是
。以此类推,我们就可以获得完整的协方差矩阵。同样,为了镌汰 推算的事情量,使用代码清单14-2获得协方差矩阵。
代码清单14-2 获取协方差矩阵
# 盘算协方差矩阵,注重 这里需要先举行 转置,由于 这里的函数是看行与行之间的协方差x_cov = np.cov(x_std.transpose())# 输出协方差矩阵print('协方差矩阵:\n', x_cov, '\n')和sklearn中的尺度化函数scale有所差异,numpy中的协方差函数cov除以的是
,而不是
。最终完整的协方差矩阵如下:
然后,我们要求解协方差矩阵的特征值和特征向量:
通过对行列式的求解,我们可以获得:
最后化简为:
以是
有3个近似解,划分是0、0.0777和4.4223。对于特征向量的求解,若是 手工推算较量 烦琐,我们照旧使用 Python语言直接求出特征值和对应的特征向量,如代码清单14-3所示。
代码清单14-3 获取协方差矩阵
# 求协方差矩阵的特征值和特征向量eigVals, eigVects = LA.eig(x_cov)print('协方差矩阵的特征值:', eigVals)print('协方差矩阵的特征向量(主因素 ):\n', eigVects, '\n')我们可以获得3个特征值及它们对应的特征向量,如表14-2所示。
表14-2 特征值和特征向量
特征值
特征向量(主因素 )
4.42231151e+00
−3.76638147e−16
7.76884923e−02
注重 ,Python代码输出的特征向量是列向量,而表14-2中列出的是行向量。我们继续使用下面的这段代码,找出特征值最大的特征向量,也就是最主要 的主因素 ,然后使用 这个主因素 ,对原始的样本矩阵举行 转换,如代码清单14-4所示。
代码清单14-4 找出主因素 并转换原有矩阵
# 找到最大的特征值,及其对应的特征向量max_eigVal = -1max_eigVal_index = -1for i in range(0, eigVals.size): if eigVals[i] max_eigVal: max_eigVal = eigVals[i] max_eigVal_index = i eigVect_with_max_eigVal = eigVects[:, max_eigVal_index]# 输出最大的特征值及其对应的特征向量,也就是第一个主因素 print('最大的特征值:', max_eigVal)print('最大特征值所对应的特征向量:', eigVect_with_max_eigVal)# 输出转换后的数据矩阵。注重 ,这里的3个值体现3个样本,而特征从3维变为1维了print('转换后的数据矩阵:', x_std.dot(eigVect_with_max_eigVal), '\n')很显着 ,最大的特征值是4.422311507725755,对应的特征向量是是[−0.58077228 −0.57896098 0.57228292],转换后的样本矩阵是:
该矩阵从原来的3个特征维度降维成1个特征维度了。Python的sklearn库也实现了PCA,我们可以通过代码清单14-5来实验一下。
代码清单14-5 找出主因素 并转换原有矩阵
import numpy as npfrom sklearn.preprocessing import scalefrom sklearn.decomposition import PCA# 原始数据,包罗了3个样本和3个特征,每一行体现一个样本,每一列体现一维特征x = np.mat([[1, 3, -7], [2, 5, -14], [-3, -7, 2]])# 矩阵按枚举 行 尺度化x_std = scale(x, with_mean=True, with_std=True, axis=0)print('尺度化后的矩阵:\n', x_std, '\n')# 挑选前2个主因素 pca = PCA(n_components=2)# 举行 PCA剖析 pca.fit(x_std)# 输出转换后的数据矩阵。注重 ,这里的3个值体现3个样本,而特征从3维变为1维了print('方差(特征值): ', pca.explained_variance_)print('主因素 (特征向量)\n', pca.components_)print('转换后的样本矩阵:\n', pca.transform(x_std))print('信息量: ', pca.explained_variance_ratio_)这段代码中,我们将输出的主因素 设置为2,也就是说挑出前2个最主要 的主因素 。响应 地,转换后的样本矩阵有2个特征维度:
除了输出主因素 和转换后的矩阵,sklearn的PCA还提供了信息量的数据,输出如下:
信息量: [0.98273589 0.01726411]它是各个主因素 的方差所占的比例,体现第一个主因素 包罗原始样本矩阵中的98.27%的信息,而第二个主因素 包罗原始样本矩阵中的1.73%的信息,可想而知,最后一个主因素 提供的信息量很少,我们可以忽略不计了。若是 我们以为 95%以上的信息量足够了,就可以只保留第一个主因素 ,将原始的样本矩阵的特征维数降到1维。
14.1.2 PCA背后的焦点头脑虽然,学习的更高境界,不仅要“知其然”,还要做到“知其以是 然”。纵然现在你对PCA的操作步骤了如指掌,可能也照旧有不少疑惑,例如,为什么我们要使用协方差矩阵?这个矩阵的特征值和特征向量又体现什么?为什么选择特征值最大的主因素 ,就能涵盖最多的信息量呢?不用着急,接下来会对此做出更透彻的诠释 ,让你不仅明确 怎样 举行 PCA,同时还明确 为什么要这么做。
1.为什么要使用协方差矩阵首先要回覆的第一个问题是,为什么我们要使用样本数据中各个维度之间的协方差来构建一个新的协方差矩阵?要弄清晰 这一点,首先要回到PCA最终的目的 :降维。降维就是要去除那些表达信息量少,或者冗余的维度。我们首先来看怎样 界说维度的信息量巨细。这里我们以为 样本在某个特征维度上的差异越大,那么这个特征包罗的信息量就越大,就越主要 。反之,信息量就越小,需要被过滤掉。很自然,我们就能想到使用某维特征的方差来界说样本在这个特征维度上的差异。另外,我们要看怎样 发现冗余的信息。若是 两种特征有很高的相关性,那么我们可以从一个维度的值推算出另一个维度的值,这两种特征所表达的信息就是重复的。第二篇“概率统计”先容 过多个变量间的相关性,而在现实 应用中,我们可以使用皮尔森(Pearson)相关系数来形貌 两个变量之间的线性相关水平。这个系数的取值规模是[−1.0, 1.0],绝对值越大,说明相关性越强,正数体现正相关,负数体现负相关。图14-1展示了正相关和负相关的寄义。左侧的
曲线和
曲线有很是近似的转变 趋势,当
上升的时间 ,
往往也是上升的,
下降的时间 ,
往往也下降,这体现两者有较强的正相关性。右侧的
和
两者相反,当
上升的时间 ,
往往是下降的,
下降的时间 ,
往往是上升的,这体现两者有较强的负相关性。
图14-1 两个变量的正负相关性
使用同样的矩阵标志,皮尔森系数的盘算公式如下:
其中,
体现向量维度,
和
划分为两个特征维度
和
在第
个采样上的数值。
和
划分体现两个特征维度上所有样本的均值,
和
划分体现两个特征维度上所有样本的尺度差。我们将皮尔森系数的公式稍加转变 ,来视察一下皮尔森系数和协方差之间的关系:
从上式可以看出,转变 后的分子就是协方差。而分母类似于尺度化数据中的分母。以是 在本质上,皮尔森相关系数和数据尺度化后的协方差是一致的。思量 到协方差既可以权衡信息量的巨细,又可以权衡差异维度之间的相关性,因此我们就使用各个维度之间的协方差所组成的矩阵,作为PCA的工具。就如前面说讲述的,这个协方差矩阵主对角线上的元素是各维度上的方差,也就体现了信息量,而其他元素是两两维度间的协方差,也就体现了相关性。既然协方差矩阵提供了我们所需要的方差和相关性,那么下一步,我们就要思量 对这个矩阵举行 怎样的操作了。
2.为什么要盘算协方差矩阵的特征值和特征向量关于这一点,我们可以从两个角度来明确 。
第一个角度是对角矩阵。所谓对角矩阵,就是只有矩阵主对角线之上的元素有非零值,而其他元素的值都为0。我们刚刚诠释 了协方差矩阵的主对角线上的元素,都是体现信息量的方差,而其他元素都是体现相关性的协方差。既然我们希望尽可能保留大信息量的维度,而去除相关的维度,那么就意味着我们希望对协方差举行 对角化,尽可能地使得矩阵只有主对角线上有非零元素。若是 我们确实可以将矩阵尽可能地对角化,那么对于对角化之后的矩阵,它的主对角线上的元素就是或者靠近 矩阵的特征值,而特征值自己又体现转换后的方差,也就是信息量。此时,对应的各个特征向量之间基本是正交的,也就是相关性极弱甚至没有相关性。
第二个角度是特征值和特征向量的几何意义。之前我们先容 过,在向量空间中,对某个向量左乘一个矩阵,现实 上是对这个向量举行 了一次变换。在这个变换的历程中,被左乘的向量主要发生旋转和伸缩这两种变换。若是 左乘矩阵对某一个向量或某些向量只发生伸缩变换,而差池这些向量发生旋转的效果,那么这些向量就称为这个矩阵的特征向量,而伸缩的比例就是特征值。换句话说,某个矩阵的特征向量体现这个矩阵在空间中的变换偏向,这些偏向都是趋于正交的,而特征值体现每个偏向上伸缩的比例。若是 一个特征值很大,那么说明在对应的特征向量所体现的偏向上,伸缩幅度很大。这也是我们需要使用原始数据去左乘这个特征向量来获取降维后的新数据的缘故原由 。由于 这样做可以资助我们找到一个偏向,让它最大限度地包罗原始的信息。需要注重 的是,这个新的方憧憬往不代表原始的特征,而是多个原始特征的组合和缩放。
以来内容摘自《法式员的数学基础课:从理论到Python实践》
本书紧贴盘算机领域,从法式员的需求出发,全心 挑选了法式员真正用得上的数学知识,通过生动的案例来解读知识中的难点,使法式员更容易对现实 问题举行 数学建模,进而构建出更优化的算法和代码。
本书共分为三大模块:“基础头脑 ”篇梳理编程中常用的数学看法和头脑 ,既由浅入深地精讲数据结构与数学中基础、焦点的数学知识,又剖析 数学对编程和算法的真正意义;“概率统计”篇以概率统计中焦点的贝叶斯公式为基点,向上解说随机变量、概率漫衍等基础看法,向下解说质朴 贝叶斯,并剖析 其在生涯 和编程中的现实 应用,使读者真正明确 概率统计的本质,跨越看法和应用之间的鸿沟;“线性代数”篇从线性代数中的焦点看法向量、矩阵、线性方程入手,逐步深入剖析 这些看法是怎样 与盘算机融会意会 以解决现实 问题的。除了理论知识的叙述 ,本书还通过Python语言,分享了通过大量实践积累下来的名贵履历 和编码,使读者学有所用。
本书的内容从看法到应用,再到本质,层层深入,不光注重作育 读者养成优异 的数学头脑 ,而且起劲 使读者的编程手艺 实现进阶,很是适合希望从本质上提升编程质量的中级法式员阅读和学习。

