sklearn-降维

  |  

摘要: sklearn 降维基础

【对算法,数学,计算机感兴趣的同学,欢迎关注我哈,阅读更多原创文章】
我的网站:潮汐朝夕的生活实验室
我的公众号:算法题刷刷
我的知乎:潮汐朝夕
我的github:FennelDumplings
我的leetcode:FennelDumplings


维度是什么

对于 np.ndarray,维度就是 shape 返回的结果,shape 返回了几个数字,就是几维。除了索引以外,如果不分行列就是一维(shape 返回(n,));有行列之分是二维(shape 返回(m, n)),此时称为表。一张表最多二维,复数张表构成更高维度(shape 返回 (更高维度, m, n))。

数组中的每一张表,都可以是一个特征矩阵或一个 DataFrame。其中行是样本,列是特征。对于每张表,维度指的是样本的数量或特征的数量。除了索引之外,一个特征的是一维,两个特征的是两维,n 个特征的是 n 维。

对于图像来说,维度就是图像中特征向量的数量。特征向量可以理解为坐标轴,一个特征向量定义为一条直线也就是一维,两个特征向量定义为一个平面也就是二维,n 个特征向量定义为 n 维空间,人类无法想象 n 维空间。

降维算法中的降维指的是降低特征矩阵中特征的数量。对一组特征使用合适的降维算法有以下几个作用:

  • 算法运算更快
  • 算法效果更好
  • 数据可视化

图像和特征矩阵可以相互对应:一个特征对应一个特征向量,即对应一条坐标轴。因此三维以下的特征矩阵可以被可视化,这个特性可以帮助我们理解数据的分布。

sklearn 中的降维算法

sklearn 中降维算法都在 decomposition 中, 这个模块本质是一个矩阵分解模块。矩阵分解可以用在降维, 深度学习, 聚类分析, 数据预处理, 低纬度特征学习, 推荐系统等场景,这里只关心降维相关的用法。

说明
PCA 主成分分析
IncrementalPCA 增量主成分分析
KernelPCA 核主成分分析
MiniBatchSparsePCA 小批量系数主成分分析
SparsePCA 稀疏主成分分析
TruncatedSVD 截断SVD
FactorAnalysis 因子分析
FastICA 快速独立成分分析
DictionaryLearning 字典学习
MiniBatchDictionaryLearning 小批量字典学习
dict_learning 字典学习用于矩阵分解
dict_learning_online 在线字典学习用于矩阵分解
LatectDirichletAllocation 具有在线扁粉贝叶斯算法的隐含狄利克雷分布
NMF 非负矩阵分解
SparseCoder 稀疏编码

PCA 与 SVD

SVD 与 PCA 都属于矩阵分解算法中的入门算法,都是通过分解特征矩阵进行降维。

降维的过程会减少特征量,因此意味着删除数据,数据量变少意味着模型可以获取的信息会变少,模型的表现可能会降低,但也可能升高。

另外在高维数据中,必然有一些特征不带有效信息(例如噪声),或者有一些特征带有的信息与其它特征重复(例如特征间线性相关),因此在降维的时候,我们希望将不带有效信息的特征,以及持有重复信息的特征去掉。

降维的目标是减少特征数量,又保留大部分有效信息(将带有重复信息的特征合并,删除带无效信息的特征)。因此需要一种衡量特征的信息量的指标来指导降维的过程。

PCA 的信息量衡量

在特征工程中的过滤法特征选择算法中,有一种是方差过滤,即如果一个特征的方差很小,则意味着该特征上很可能大量取值都相同,则这个特征的取值对样本而言没有区分度,就不带有有效信息。而如果一个特征的方差很大,则说明这个特征上带有大量信息。PCA 也是用方差衡量特征信息量的。

PCA 用的信息量衡量指标是样本方差,方差越大,特征所带信息量越多。

公式备注:

  • n 为样本个数,xi 表示样本 x 在特征 i 的取值。
  • 分母为 n - 1,是为了得到样本方差的无偏估计。

降维过程的主要步骤(2维与n维对比)

步骤 2维特征矩阵 n维特征矩阵
step1 输入原始数据 (m, 2)
找出原本2个特征对应的直角坐标系,即找到这两个特征构成的二维平面
输入原始数据 (m, n)
找出原本的n个特征向量构成的n维空间V
step2 确定降维后的特征数量 1 确定降维后的特征数量 k
step3 旋转,找出一个新坐标系
本质是找2个新的特征向量,构成新的2维平面
新特征向量让数据被压缩到少数特征上且信息量损失不太多
通过某种变化,找到 n 个新的特征向量,以及它们构成的新 n 维空间 V
step4 找出数据点在新坐标系上 2 个新坐标轴上的坐标 找出原始数据在新特征空间 V 中的 N 个新特征向量上对应的值(将数据映射到新空间中)
step5 选取第1个方差最大的特征向量,删掉没有选中的特征,将 2 维降为 1维 选取前 k 个信息量最大的特征,删掉没被选中的特征,n 维空间 V 将为 k 维。

在 step3 中,【找出 n 个新特征向量,新特征向量让数据被压缩到少数特征上且信息量损失不太多】这件事就是矩阵分解做的。

PCA 和 SVD 是两种不同的降维算法,且流程都是上面的表格,只是两种算法的矩阵分解方法不同,信息量衡量指标不同。

注:以下结论的数学推导需要找其它资料补充

  • PCA: 方差是信息量指标,特征值分解找 V

其中 $\boldsymbol{\Sigma}$ 是对角矩阵,对角线上的元素就是方差,降维完成后每个新的特征向量为主成分。被丢弃的特征认为信息量很少,很可能是噪声。

  • SVD: 奇异值是信息量指标,奇异值分解找 V

其中 $\boldsymbol{\Sigma}$ 是对角矩阵,对角线上元素是奇异值,这些奇异值也是 SVD 中用来衡量特征上的信息量的指标。$\boldsymbol{U}$ 和 $\boldsymbol{V}^{T}$ 分别是左奇异矩阵和右奇异矩阵(辅助矩阵)。


PCA 后的特征,无法知道是原特征怎么组合来的。这相当于特征工程中的特征创造
PCA 一般不适用于探索特征和标签之间关系的模型(例如线性回归),因为无法解释新特征和标签的关系。

PCA 和 SVD 都需要遍历所有特征和样本来计算信息量指标,且在矩阵分解过程中会产生比原特征矩阵更大的矩阵,计算量巨大。

PCA 与特征选择的区别

特征选择是从已存在的特征中选取携带信息最多的, 选完之后的特征依然具有可解释性, 即知道这个特征在原数据的哪个位置, 代表原数据上的什么含义。

而PCA,是将已存在的特征进行压缩,降维完毕后的特征不是原本的特征矩阵中的任何一个特征,而是通过某些方式组合起来的新特征

无法判断 PCA 得到的新特征矩阵的特征是从原数据中的什么特征组合而来,新特征虽然带有原始数据的信息,但已经不是原数据上代表着的含义了。因此 PCA 可以理解为是特征工程中特征创造的一种方式。

PCA 的参数

PCA 是矩阵分解的核心算法,参数不多,但每个参数都有比较难的数学原理。

  • n_components
  • copy
  • whiten
  • svd_solver
  • tol
  • iterator_power
  • random_state

(1) n_components

降维后需要的维度,即降维后需要保留的特征数量,取 [0, min(X.shape)]。这个值不能太大也不能太小。以下为取值的一些经验

  • 取 n_components 为 2 或 3。

当想要可视化数据的时候,可以取 n_components 为 2 或 3。

  • 取 n_components 为默认值 min(X.shape)

当参数 n_components 中不填写任何值, 默认返回min(X.shape)个特征,一般样本量都会大于特征数目,所以什么都不填就相当于转换了新特征空间但没有减少特征的个数。

一般不会使用这种输入方式。但可以使用这种输入方式来画出累计可解释方差贡献率曲线,以此选择最好的n_components的整数取值

  • 最大似然估计自选超参数

让 PCA 用最大似然估计(MLE)自选超参,n_components="mle"即可

  • 按信息量占比选超参

取 n_components 为 [0, 1] 之间的浮点数,表示留多少百分比信息量,且 svd_solver=full

(2) svd_solver

svd_solver是奇异值分解器。可以用 SVD 做 PCA 的原因是 SVD 可以不计算协方差矩阵而直接找出一个新特征向量组成的 n 维空间,这个 n 维空间就是奇异值分解后的 $\boldsymbol{V}^{T}$。

记 $\boldsymbol{X}_{dr}$ 为 PCA 降维后的特征矩阵,右奇异矩阵 $\boldsymbol{V}^{T}$ 有以下性质:

因此对奇异值分解后的 $\boldsymbol{V}$ 取 [:k] 切片,并与原特征矩阵形成可以直接得到 PCA 后的m行k列特征矩阵 $\boldsymbol{X}_{dr}$

虽然 SVD 过程比 PCA 快速,但 SVD 的信息量衡量指标复杂,理解奇异值不如理解方差容易,因此 sklearn 将 PCA 分为两步:

  1. 通过奇异值分解求 $\boldsymbol{V}$ (sklearn中 $\boldsymbol{U}$ 和 $\boldsymbol{\Sigma}$ 始终没有用, fit 之后就弃掉了)
  2. 在 $\boldsymbol{V}$ 中找到信息量最大的 k 个,结果保存在 components_ 属性中。

以上两步实现了即用 SVD 的性质减少计算量又让信息量评估指标为方差

  • fit(X) 求 $\boldsymbol{V}[:k]^{T}$
  • transform(x) 求 $\boldsymbol{X}_{dr} = \boldsymbol{X} \times \boldsymbol{V}[:k]^{T}$

svd_solver 的 4 中选择

  • auto

数据尺寸大于 $500 \times 500$ 且保留特征数小于 min(X.shape) 的 80%,则启用更高效的 randomized 方法,否则启用 full,计算精确完整的 SVD,截断会在矩阵分解完成后有选择地发生

  • full

scipy.linalg.svd 调用标准 LAPACK 分解器,生成精确 SVD。适合数据量适中,计算时间充足的情况。

  • arpack

scipy.sparse.linalg.svds 调用 ARPACK 分解器运行截断奇异值分解,分解时就将特征数量降到 k。适合特征矩阵很大且为稀疏矩阵的情况,含义一定随机性

  • randomized

随机算法,先生成多个随即向量,然后一一检测是否有任何一个能满足分解需求,留下符合的向量,然后基于此向量构建后续的向量空间。适合特征矩阵巨大,计算量庞大的情况。

由于 arpack 和 randomized 含随机性,可以配合 random_state 参数控制随机模式,方便复现。

属性 components_

V(k, n) 是新特征空间,是要将原始数据进行映射的哪些新特征向量组成的矩阵,用于计算新的特征矩阵。

PCA 在新的特征矩阵生成之前,无法知道 PCA 都建立了怎样的新特征向量,新特征矩阵生成后也就不具有可读性。但矩阵分解时 PCA 是有目标的:在原有特征基础上,找出能够让信息尽量聚集的新特征向量。在 sklearn 中(PCA 和 SVD 联合) 的降维方法中,这些新特征向量组成的新特征空间就是 V(k, n),当 V(k, n) 是数字,无法判断 V(k, n) 与原有特征的联系,但如果原特征矩阵是图像,V(k, n) 就可以被可视化,进而将两张图来比较,看新特征空间从原始数据里提取了什么重要信息。

接口 inverse_transform

在 sklearn 的归一化,标准化,做过哑变量的特征矩阵可以还原会原始数据的特征矩阵。也是 inverse_transform 接口。

但对于 PCA,inverse_transform 并没有将数据完全逆转,原数据中舍弃的信息不可能回来了。它的工作原理是基于 $\boldsymbol{V}_{dr}$ 中的数据进行升维,将数据重新映射到原数据所在的特征空间中。


Jupyter 脚本链接


Share