数据降维
数据降维主要有两点好处:
- 数据压缩,因而使用更少的内存或存储空间
- 加速学习算法
一个简单的例子如下,把二维( x1, x2)映射到图中直线上,因而可以用一维数据来表示:
稍微复杂点的例子,把三位数据映射到一个平面上,因而可以用二维坐标来表示:
类似的处理过程可以用来把任何维度 (m) 的数据降到任何想要的维度 (n),例如将1000维的特征降至100维。
如果我们能将数据可视化,降维可以帮助我们:
例如有许多国家的数据,每一个特征向量都有50个特征(如GDP,人均GDP,平均寿命等)。如果要将50维数据可视化是不现实的。
而使用降维的方法将其降至2维,我们便可以将其可视化了。
上面介绍了降维,那如何降维是合理的了?
PCA是其中一个很常见的方法。
原理是当把所有的数据都投射到新的方向向量上时,希望投射平均均方误差(MSE) 尽可能小。 方向向量是一个经过原点的向量,而投射误差是从特征向量向该方向向量作垂线的长度。如下图中蓝色线段所示:
问题描述: 将 n 维数据降至 k 维,目标是找到向量 u(1) , u(2) ,..., u(k) 以最小化总体投射误差(MSE)。
对于上图的例子,看起来是不是很像线性回归? 但PCA和线性回归是不同的算法。PCA最小化的是投射误差(Projected Error),而线性回归最小化的是预测误差。线性回归的目的是预测结果,而主成分分析不作任何预测。下左图是线性回归的误差(垂直于横轴投影),下右图是PCA的误差(垂直于红线投影):
PCA将 n 个特征降维到 k 个,可以用来数据压缩,如果100维的向量最后用10维来表示,那么压缩率为90%。同样图像处理领域的KL变换使用PCA做图像压缩。但PCA要保证降维后,还要保证数据的特性损失最小。
PCA的一大好处是对数据进行降维。可以对新求出的“主元”向量的重要性进行排序,根据需要取前面最重要的部分,将后面的维数省去,可以达到降维从而简化模型或是对数据进行压缩的效果。同时最大程度的保持了原有数据的信息。
此外,PCA是完全无参数限制的。在PCA的计算过程中不需要人为设定参数或是根据任何经验模型对计算进行干预,最后的结果只与数据相关,与用户是独立的。
但,这点同时也是缺点。如果用户对观测对象有一定的先验知识,例如掌握了数据的一些特征,却无法通过参数化等方法对处理过程进行干预,可能无法得到预期的效果。
PCA减少 n 维到 k 维:
- 均值归一化(Mean Normalization)。 计算所有特征的均值 μj,令 xj=xj - μj 。 如果特征是在不同的数量级上,我们还需要将其除以_sj_,可以是最大最小值只差(xmax - xmin),或是标准差 σ 。
- 计算协方差矩阵(covariance matrix) Σ :
- 计算协方差矩阵 Σ 的特征向量(eigenvectors):
[U, S, V] = svd(Sigma)
在Python
里我们可以利用 奇异值分解(singular value decomposition) 来求解:
import numpy as np a = np.diag((1, 2, 3)) U, S, vh = np.linalg.svd(a) # ((3, 3), (3,), (3, 3))
其中 U 是特征向量、 S 是特征值。其实 S 只有对角线上有值,是按照特征值从大到小排序的,U的每一列 uj 与对应位置的 sj 对应的特征向量。其中 UTU = I。
所以,如果要把数据从 n 维映射到 k 维,只需要取特征向量 U 的前 k 维度列向量,构成映射矩阵 Ureduce = U[:, k]。
- z = UTreduce * x 即为映射后的数据,其中 x 为原始数据。
给定 z(i),可能是100维,怎么得到到原来的表示 x(i) ,也许本来是1000维的数组。
在压缩过数据后,可以采用如下方法近似地获得原有的特征:
xapprox=Ureduce z
因为从 x 得到 z 的过程可以看做是 x 在空间 UTreduce 上的映射。 而从 z 得到 xapprox 的过程可以看做反向的映射,也就是在空间 (UTreduce)-1 = Ureduce (A的逆矩阵)上的映射。
下图中为一个恢复的例子:
**关于PCA更多的推导和证明:**请见这里
主要成分分析是减少投射的平均均方误差 MSE。
训练集的方差(Variance)为:
通常是选择 k 值,使 MSE 与 Variance 的比例尽可能小的情况下选择尽可能小:
这个阈值(threshold)通常取值 0.01 (1%)。
如果希望比例小于1%,意味着原本数据的偏差有99%都保留下来了,如果选择保留95%的偏差,便能非常显著地降低模型中特征的维度了。
可以先令 k=1 ,然后执行PCA,获得 Ureduce 和 z ,然后计算比例是否小于1%。如果不是的话再令 k=2 ,如此类推,直到找到可以使得比例小于1%的最小 k 值。
还有一些更好的方式来选择 k ,当使用 numpy.linalg.svd()
函数时,将获得三个参数: U,S,V = numpy.linalg.svd(sigma)
。
其中的 S 是一个 n×n 的矩阵,只有对角线上有值,而其它单元都是0(如下图)。
可以用这个矩阵来计算平均均方误差与训练集方差的比例:
即:
通过svd()
得到的 sii 来计算上面的MSE与Variance比例很很方便的。
假使正在针对一张100×100像素的图片做CV的机器学习,总共10000个特征。
- 第一步是运用主要成分分析将数据压缩至1000个特征
- 然后对训练集运行学习算法
- 在预测时,采用之前学习而来的 Ureduce 将输入的特征 x 转换成特征 z ,然后再进行预测
注:如果我们有交叉验证集合测试集,也采用对训练集学习而来的 Ureduce 。
错误的PCA用法:
- 将其用于减少过拟合(减少了特征的数量)。 非常不好,不如尝试正则化处理。原因在于PCA只是近似地丢弃掉一些特征,它并不考虑任何与结果变量有关的信息,因此可能会丢失非常重要的特征。然而当我们进行正则化处理时,会考虑到结果变量,不会丢掉重要的数据。
- 默认地将PCA作为学习过程中的一部分,虽然PCA很多时候有效果,最好是从所有原始特征开始,只在有必要的时候(算法运行太慢或者用太多内存)才考虑采用PCA。
- 推荐访问Google Drive的共享,直接在Google Colab在线运行ipynb文件:
- 不能翻墙的朋友,可以访问GitHub下载: