前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >机器学习入门 7-6 scikit-learn中的PCA

机器学习入门 7-6 scikit-learn中的PCA

作者头像
触摸壹缕阳光
发布2019-11-13 10:22:28
8820
发布2019-11-13 10:22:28
举报
本系列是《玩转机器学习教程》一个整理的视频笔记。前几个小节封装了我们自己的PCA方法。这一小节就来看看sklearn中对于PCA是如何进行封装的,然后通过构造的虚拟数据集以及真实的digits手写数字识别数据集来展示PCA降维的效果。

sklearn中的PCA

sklearn封装的PCA与前几个小节我们自己封装的PCA,虽然他们大体流程基本一致,但是他们之间还是有很多不同的地方。

在前一个小节的时候,我们使用梯度上升法求解PCA在构造的虚拟二维数据集上得到的第一个主成分结果是:

代码语言:javascript
复制
array([[ 0.75483587,  0.65591372]])

但是本小节使用sklearn封装的PCA方法在相同的数据集上得到的第一主成分的结果是:

代码语言:javascript
复制
array([[-0.77556359, -0.63126945]])

由于构造数据集的随机性,因此数值上的些许的偏差不必关心。对于上面两个第一主成分最大的不同在于求解的方向是相反的。向量加上负号,得到向量的方向与原始向量方向相反。产生这样的差异是由于我们自己封装的PCA和sklearn中封装的PCA实现的基本方法不同。

  1. 我们自己封装的PCA,通过寻找使得映射到轴上的样本方差最大,进而推导出效用函数,然后通过迭代求解的梯度上升法求解使得效用函数(方差)最大的单位方向向量,即为求解的第一个主成分;
  2. sklearn封装的PCA,通过数学的方式进行求解,设有m条n维的样本数据X,数学求解PCA大致过程如下:
    1. 将样本数据按列组合成n行m列,即X矩阵的转置;
    2. 对X样本矩阵的n维特征进行demean操作,即让每一个特征零均值化;
    3. 求出协方差矩阵C = 1 \ m XX^{T};
    4. 求出协方差矩阵的特征值及相对应的特征向量;
    5. 将特征向量按对应的特征值大小从上到下的按行排列成矩阵,取前k行组成矩阵P,此时的k即为前k个主成分;
    6. X_reduction = PX,此时的X_reduction即为降维到k维后的样本数据。

当然我们不需要关心这一点,因为虽然求出的主成分方向相反,但是不会影响到我们最终的降维的结果。通过可视化的方式也可以看出,虽然求出的方向相反,但是两个不同方式降维后的结果是一样的。

PCA对digits数据集降维

接下来使用sklearn中封装的PCA对真实的手写数字识别数据集进行降维操作,并且看一看在sklearn中封装的PCA还有哪些额外的功能。

上面就是使用KNN算法进行分类的流程,测试集上的f1准确率大致可以到98%。接下来,引入PCA对数据进行降维后KNN算法的分类效果如何。

从两个角度来看:

  1. 时间上,不对数据进行处理的KNN算法分类时间为6.98ms,而使用PCA将64维的数据降到2维的数据后进行KNN算法分类的时间为2.99ms,这得益于数据特征维度的大幅降低,当然这也是降维的一个非常重要的意义,对于非常高维的数据来说,降维到低维空间之后,将大大节省计算的时间;
  2. 分类精度上,使不使用PCA降维对于分类精度来说影响巨大,不使用PCA降维KNN分类精度可以轻松到达98%左右,但是将数据从64维降到2维后的分类精度为60%左右,差距非常大。当然这也很好理解,因为毕竟原始数据是64维的数据,如果降低到2维的话,特征信息损失的非常多。

对于具体降维到多少,这个参数应该如何来设置,当然最简单的方法就是通过循环遍历,使用网格搜索的方式来寻找最优的超参数。不过在sklearn中封装的PCA为我们提供了一个特殊的指标,通过这个指标我们可以非常方便的找到对于某一个数据集来说需要保留多少特征信息足够。这个指标就是explained_variance_ratio_解释方差相应的比例

代码语言:javascript
复制
# 解释方差相应的比例
pca.explained_variance_ratio_
array([0.14566817, 0.13735469])

其实这个很好解释,我们获取前两个主成分。此时的explained_variance_ratio_属性得到的两个数值分别表示对应的两个主成分分别能够解释原数据的方差比率。

  1. 对于第一个主成分来说能够解释14.5%左右的原数据方差;
  2. 对于第二个主成分来说能够解释12.7%左右的原数据方差;

PCA算法就是为了寻找使得原来数据相应的方差维持最大,而此时的explained_variance_ratio_告诉我们保留的k个主成分能够维持我们原来数据所有方差的百分之多少。通过实验的两个结果可以看出,对于从64维降到2维的数据来说,2维数据能够保留原来数据总方差的14.5% + 13.7% = 28.2%,而剩下71.8%在将数据从64维降到2维的过程中丢失了。很显然丢失的信息过多,而实际上我们可以通过explained_variance_ratio_变量来找到我们将数据降到多少维。

下面通过实验来说明:

我们保留了全部的64个主成分,通过explained_variance_ratio_得到64个从大到小依次排列的数值。同理,这些数值表示对于每一个主成分来说,依次可以解释的方差是多少,通过输出的结果可以看出,最后一个数值为7.15189459e-34,这个数值可以说非常非常小了,因此完全可以丢弃这最后一个主成分,相应的第一个数值1.45668166e-01保留了原数据的14.5%的方差,这个数值所占的比例还是挺大的,因此需要保留。当然我们也可以简单的把这些数值理解成每一个主成分相应的重要程度。

我们可以将上面功能绘制折线图,横轴表示保留k个主成分,对于降维来说就是降到k维度,纵轴取前k个轴解释原数据方差的总和。具体的折线图如下。

比如选定前30个主成分的话,找到相应的横轴30的位置,对应横轴30找到相应的纵轴数值,大概为90%左右,也就是如果保留前30个主成分,将64个维度降到30维的时候,能够保留原数据90%左右的信息。保留越多的维度,相应解释原数据的方差也就越来越大。我们可以通过曲线来看需要将我们的数据降低到多少维度,也就是保留多少个主成分。

比如我们希望将数据信息保持在95%以上,在上面的折线图中找到相应的95%相对应的横轴数值就好了。

介绍了这么多,上面的功能sklearn中为我们封装好了,也就是通过指定需要保留原数据方差比例来自动决定选取的主成分个数。

在创建PCA对象的时候传入0.95这个参数,表示能够解释原来数据的95%以上的方差,根据保留的比例,sklearn能够自动的选定主成分。丢失的5%的信息在我们可以接受的范围之内。选择丢失一定的信息还有一种情况,就是可能丢失的信息是噪声信息,这些噪声对我们的任务没有帮助反而可能影响最终的效果,当然对于不同的数据来说,影响的效果是不确定的。丢失一些信息大致可能有下面两种情况:

  1. 数据处理的过程中对数据进行降维,虽然后期任务的效果上比保留全部维度效果要差,但是可以大大的节省后期任务的时间,这对于样本量巨大的数据来说,可以牺牲一些精度来换取一定的时间;
  2. 获取的数据通常可能会有噪声数据,降维可能会把噪声数据的信息丢失掉,这样在后期任务中不仅时间上大大的减少,而且精度上可能会比保留全部特征要好一些;

由于从64维降低到了28维,相对应的时间效率大大的提升,但是在测试集上的精度上达到了98%和没有使用pca降维的精度低了0.6%,差距还是比较小的。虽然没有像前面所说的丢弃5%的噪声信息,准确率有所提升。但是在一定时间内来换取识别精度上稍微的丢失。如果我们的样本数量巨大,可能需要10天半个月的时间,但是通过降维的方式选择k个主成分,训练的时间可能大大的缩短,并且最终精度也不会差距太大,在这种情况下,我们可能更倾向于通过时间来换取识别率上的丢失。

前面的digits数据集上将64维降低到2维,看到其实效果并不好,但是将数据降维到2维并不是完全没有意义。在一开始介绍PCA算法的时候,PCA降维还有一个非常重要的作用,就是可视化。我们可以将数据降维到2维数据,通过可视化的方式来直观的观察数据。比如在digits数据中,将其降维到2维数据,然后对其进行可视化。

虽然在matplotlib中并没有显示的指定颜色,但是matplotlib会自动为我们指定颜色。上图的结果看起来还是比较乱的,但是如果仔细看,可以发现红色点,蓝色点,粉色点,紫色点在二维数据中区分度很明显。通过观察可视化的数据,我们可以从中发现很多有用的结论。比如对于digits数据集来说,如果仅仅是为了区分蓝色点和紫色点,二维数据就足够了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI机器学习与深度学习算法 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档