一
sklearn中的PCA
sklearn封装的PCA与前几个小节我们自己封装的PCA,虽然他们大体流程基本一致,但是他们之间还是有很多不同的地方。
在前一个小节的时候,我们使用梯度上升法求解PCA在构造的虚拟二维数据集上得到的第一个主成分结果是:
array([[ 0.75483587, 0.65591372]])
但是本小节使用sklearn封装的PCA方法在相同的数据集上得到的第一主成分的结果是:
array([[-0.77556359, -0.63126945]])
由于构造数据集的随机性,因此数值上的些许的偏差不必关心。对于上面两个第一主成分最大的不同在于求解的方向是相反的。向量加上负号,得到向量的方向与原始向量方向相反。产生这样的差异是由于我们自己封装的PCA和sklearn中封装的PCA实现的基本方法不同。
当然我们不需要关心这一点,因为虽然求出的主成分方向相反,但是不会影响到我们最终的降维的结果。通过可视化的方式也可以看出,虽然求出的方向相反,但是两个不同方式降维后的结果是一样的。
二
PCA对digits数据集降维
接下来使用sklearn中封装的PCA对真实的手写数字识别数据集进行降维操作,并且看一看在sklearn中封装的PCA还有哪些额外的功能。
上面就是使用KNN算法进行分类的流程,测试集上的f1准确率大致可以到98%。接下来,引入PCA对数据进行降维后KNN算法的分类效果如何。
从两个角度来看:
对于具体降维到多少,这个参数应该如何来设置,当然最简单的方法就是通过循环遍历,使用网格搜索的方式来寻找最优的超参数。不过在sklearn中封装的PCA为我们提供了一个特殊的指标,通过这个指标我们可以非常方便的找到对于某一个数据集来说需要保留多少特征信息足够。这个指标就是explained_variance_ratio_解释方差相应的比例。
# 解释方差相应的比例
pca.explained_variance_ratio_
array([0.14566817, 0.13735469])
其实这个很好解释,我们获取前两个主成分。此时的explained_variance_ratio_属性得到的两个数值分别表示对应的两个主成分分别能够解释原数据的方差比率。
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%的信息在我们可以接受的范围之内。选择丢失一定的信息还有一种情况,就是可能丢失的信息是噪声信息,这些噪声对我们的任务没有帮助反而可能影响最终的效果,当然对于不同的数据来说,影响的效果是不确定的。丢失一些信息大致可能有下面两种情况:
由于从64维降低到了28维,相对应的时间效率大大的提升,但是在测试集上的精度上达到了98%和没有使用pca降维的精度低了0.6%,差距还是比较小的。虽然没有像前面所说的丢弃5%的噪声信息,准确率有所提升。但是在一定时间内来换取识别精度上稍微的丢失。如果我们的样本数量巨大,可能需要10天半个月的时间,但是通过降维的方式选择k个主成分,训练的时间可能大大的缩短,并且最终精度也不会差距太大,在这种情况下,我们可能更倾向于通过时间来换取识别率上的丢失。
前面的digits数据集上将64维降低到2维,看到其实效果并不好,但是将数据降维到2维并不是完全没有意义。在一开始介绍PCA算法的时候,PCA降维还有一个非常重要的作用,就是可视化。我们可以将数据降维到2维数据,通过可视化的方式来直观的观察数据。比如在digits数据中,将其降维到2维数据,然后对其进行可视化。
虽然在matplotlib中并没有显示的指定颜色,但是matplotlib会自动为我们指定颜色。上图的结果看起来还是比较乱的,但是如果仔细看,可以发现红色点,蓝色点,粉色点,紫色点在二维数据中区分度很明显。通过观察可视化的数据,我们可以从中发现很多有用的结论。比如对于digits数据集来说,如果仅仅是为了区分蓝色点和紫色点,二维数据就足够了。
本文分享自 AI机器学习与深度学习算法 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!