先来了解一张降维汇总图,降维的算法比较多,这里就只简单说MDS,PCA以及流行学习的Isomap和LLE。

多维缩放MDS:Multiple Dimensional Scaling
低维嵌入:在很多时候, 人们观测或收集到的数据样本虽是高维的,但与学习任务密切相关的也许仅是某个低维分布,即高维空间中的一个低维”嵌入” (embedding) . 图 10.2 给出 了 一个直观的例子. 原始高维空间中的样本点,在这个低维嵌入子空间中更容易进行学习。

MDS的目标是在降维的过程中将数据的dissimilarity(差异性)保持下来,也可以理解降维让高维空间中的距离关系与低维空间中距离关系保持不变。这里的距离用矩阵表示,N个样本的两两距离用矩阵D的每一项$dist_{ij}$ 表示,并且假设在低维空间中的距离是欧式距离。而降维后的数据表示为$Z_i$,那么就有
令$B=ZZ^T$ ,右边的三项统一用内积矩阵B来表示$b_{ij}=z_iz_j^T$ ,所以有
这时只要求出内积矩阵B即可求出降为后的矩阵Z(思路D-B-Z)。距离矩阵D去中心化之后(减去均值),內积矩阵B的每一行每一列之和都是0,可以推导得出

其中 tr(.) 表示矩阵的迹(trace),$tr(E)=\sum_{i=1}^m\Vert z_i \Vert^2=\sum_{i=1}^mb_{ii}$,令

联立上(1)-(7),消除$b_{ii},b_{jj}$后,可以得到
i⋅与⋅j是指某列或者某列总和,从而建立了距离矩阵D与内积矩阵B之间的关系.由此即可通过降维前后保持不变的距离矩阵 D 求取内积矩阵 B。对矩阵 B 做特征值分解(eigenvalue decomposition),$B=VAV^T$,其中$A=diag(λ_1,λ_2,…λ_d)$为特征值构成的对角矩阵,$λ_1\geq λ_2\geq …\geq λ_d$,V 为特征向量矩阵.假定其中有d* 个非零特征值,它们构成对角矩阵$A=diag(λ_1,λ_2,…λ_{d})$,令 V*表示相应的特征向量矩阵,联立之前的$B=ZZ^T$,则最后Z可表达为
在现实应用中为了有效降维,往往仅需降维后的距离与原始空间中的距离尽可能接近?而不必严格相等.此时可取 d’<< d 个最大特征值构成对角矩阵。

主成分分析PCA: Principal Component Analysis
向量內积
由$A⋅B=|A||B|cos(a)$, A与B的内积等于A到B的投影长度乘以B的模。再进一步,如果我们假设B的模为1,则A与B的内积值等于A向B所在直线投影的矢量长度!

基
向量(x,y)实际上表示线性组合,$x(1,0)^T+y(0,1)^T$,不难证明所有二维向量都可以表示为这样的线性组合。此处(1,0)和(0,1)叫做二维空间中的一组基。但实际上任何两个线性无关的二维向量都可以成为一组基,所谓线性无关在二维平面内可以直观认为是两个不在一条直线上的向量.例如,(1,1)和(−1,1)也可以成为一组基。一般来说,我们希望基的模是1,实际上,对应任何一个向量我们总可以找到其同方向上模为1的向量,只要让两个分量分别除以模就好了。例如,上面的基可以变为$(\frac{1}{\sqrt{2}},\frac{1}{\sqrt{2}})$和$(-\frac{1}{\sqrt{2}},\frac{1}{\sqrt{2}})$
基变换的矩阵表示:
下面我们找一种简便的方式来表示基变换。还是拿上面的例子,想一下,将(3,2)变换为新基上的坐标,就是用(3,2)与第一个基做内积运算,作为第一个新的坐标分量,然后用(3,2)与第二个基做内积运算,作为第二个新坐标的分量。实际上,我们可以用矩阵相乘的形式简洁的表示这个变换,其中矩阵的两行分别为两个基,乘以原向量,其结果刚好为新基的坐标:

协方差矩阵及优化目标
面我们讨论了选择不同的基可以对同样一组数据给出不同的表示,而且如果基的数量少于向量本身的维数,则可以达到降维的效果。但是我们还没有回答一个最最关键的问题:如何选择基才是最优的。或者说,如果我们有一组N维向量,现在要将其降到K维(K小于N),那么我们应该如何选择K个基才能最大程度保留原有的信息?

现在问题来了:如果我们必须使用一维来表示上面这些数据,又希望尽量保留原始的信息,你要如何选择?
通过上一节对基变换的讨论我们知道,这个问题实际上是要在二维平面中选择一个方向,将所有数据都投影到这个方向所在直线上,用投影值表示原始记录。这是一个实际的二维降到一维的问题。
那么如何选择这个方向(或者说基)才能尽量保留最多的原始信息呢?一种直观的看法是:希望投影后的投影值尽可能分散。
我们希望投影后投影值尽可能分散,而这种分散程度,可以用数学上的方差来表述。此处,一个字段的方差可以看做是每个元素与字段均值的差的平方和的均值,即:
通过去中心化(字段所有数值减去字段均值),将每个字段的均值都化为0了,因此方差可以直接用每个元素的平方和除以元素个数表示:
于是上面的问题被形式化表述为:寻找一个一维基,使得所有数据变换为这个基上的坐标表示后,方差值最大.
协方差
对于上面二维降成一维的问题来说,找到那个使得方差最大的方向就可以了。不过对于更高维,还有一个问题需要解决。考虑三维降到二维问题。与之前相同,首先我们希望找到一个方向使得投影后方差最大,这样就完成了第一个方向的选择,继而我们选择第二个投影方向。
如果我们还是单纯只选择方差最大的方向,很明显,这个方向与第一个方向应该是“几乎重合在一起”,显然这样的维度是没有用的,因此,应该有其他约束条件。从直观上说,让两个字段尽可能表示更多的原始信息,我们是不希望它们之间存在(线性)相关性的,因为相关性意味着两个字段不是完全独立,必然存在重复表示的信息。
数学上可以用两个字段的协方差表示其相关性,由于已经让每个字段均值为0,则:
可以看到,在字段均值为0的情况下,两个字段的协方差简洁的表示为其内积除以元素数m。
当协方差为0时,表示两个字段完全独立。为了让协方差为0,我们选择第二个基时只能在与第一个基正交的方向上选择。因此最终选择的两个方向一定是正交的。
至此,我们得到了降维问题的优化目标:将一组N维向量降为K维(K大于0,小于N),其目标是选择K个单位(模为1)正交基,使得原始数据变换到这组基上后,各字段两两间协方差为0,而字段的方差则尽可能大(在正交的约束下,取最大的K个方差)。
协方差矩阵
我们看到,最终要达到的目的与字段内方差及字段间协方差有密切关系。因此我们希望能将两者统一表示,仔细观察发现,两者均可以表示为内积的形式,而内积又与矩阵相乘密切相关。
假设我们只有a和b两个字段,那么我们将它们按行组成矩阵X:

然后我们用X乘以X的转置,并乘上系数1/m:

奇迹出现了!这个对角线上的两个元素分别是两个字段的方差,而其它元素是a和b的协方差。两者被统一到了一个矩阵的。
根据矩阵相乘的运算法则,这个结论很容易被推广到一般情况:设我们有m个n维数据记录,将其按列排成n乘m的矩阵X,设$C=\frac{1}{m}XX^𝖳$ ,则C是一个对称矩阵,其对角线分别个各个字段的方差,而第i行j列和j行i列元素相同,表示i和j两个字段的协方差。
协方差矩阵对角化
根据上述推导,我们发现要达到优化条件,等价于将协方差对角化:即除对角线外的其它元素化为0,并且在对角线上将元素按大小从上到下排列,这样我们就达到了优化目的。这样说可能还不是很明晰,我们进一步看下原矩阵与基变换后矩阵协方差矩阵的关系:
设原始数据矩阵X对应的协方差矩阵为C,而P是一组基按行组成的矩阵,设$Y=PX$,则Y为X对P做基变换后的数据。设Y的协方差矩阵为D,我们推导一下D与C的关系:
现在事情很明白了,我们要找的P不是别的,而是能让原始协方差矩阵对角化的P。换句话说,优化目标变成了寻找一个矩阵P,满足$PCP^T$是一个对角矩阵,并且对角元素按从小到大依次排列,那么P的前K行就是要寻找的基,用P的前K行组成的矩阵乘以X就使得X从N维降到了K维并满足上述优化条件。
现在所有焦点都聚焦在了协方差矩阵对角化问题上,由上文知道,协方差矩阵C是一个是对称矩阵,在线性代数上,实对称矩阵有一系列非常好的性质:
- 1)实对称矩阵不同特征值对应的特征向量必然正交。
- 2)设特征向量λ重数为r,则必然存在r个线性无关的特征向量对应于λ,因此可以将这r个特征向量单位正交化。
由上面两条可知,一个n行n列的实对称矩阵一定可以找到n个单位正交特征向量,设这n个特征向量为$e_1,e_2,⋯,e_n$,我们将其按列组成矩阵:
则对协方差矩阵C有如下结论:
其中Λ为对角矩阵,其对角元素为各特征向量对应的特征值(可能有重复)。以上结论不再给出严格的数学证明,对证明感兴趣的朋友可以参考线性代数书籍关于“实对称矩阵对角化”的内容。
到这里,我们发现我们已经找到了需要的矩阵P:P是协方差矩阵的特征向量单位化后按行排列出的矩阵,其中每一行都是C的一个特征向量。如果设P按照Λ中特征值的从大到小,将特征向量从上到下排列,则用P的前K行组成的矩阵乘以原始数据矩阵X,就得到了我们需要的降维后的数据矩阵Y
于是,只需对协方差矩阵$XX^T$进行特征值分解,将求得的特征值排序:$λ_1\geq λ_2\geq …\geq λ_d$,再再取前 d’ 个特征值对应的特征向量构成 $W=(w_1,w_2,..,w_d’)$.这就是主成分分析的解.要注意降维后低维空间的维数 d’ 通常是由用户事先指定。
简单回顾一下:给定原始数据矩阵X,其协方差矩阵$C=\frac{1}{M}XX^T$对角元素代表了方差,其余元素代表相关性。假定降维后的数据矩阵为Y,其协方差D会满足对角元素最大,其余元素为0,这样才会代表降维后的要求。设Y=PX,P代表要与矩阵相乘的基,有$D=PCP^T$的关系。这个等式的形式与实对称矩阵对角化一样,这时候只要找出C的特征值对应的特征向量,组合起来即为我们需要求得P。最后Y=PX得到降维后的数据矩阵。

PCA 仅需保留 W 与 样本 的均值向 量即可通过简单的向量减法和矩阵”向量乘法将新样本投影至低维空间中 . 显然,低维空间与原始高维空间必有不同,因为对应于最小的d-d’个特征值的特征 向量被舍弃了,这是降维导致的结果.但舍弃这部分信息往往是必要的- 一方面舍弃这部分信息之后能使样本的采样密度增大,这正是降维 的重要动机; 另一方面,当数据受到 噪声影响时, 最小的特征值所对应的特征 向量往往与噪声有关?将它们舍弃能在一定程度上起到去噪的效果.
流行学习算法Isomap:等度量映射
等度量映射(Isometric Mapping,简称 Isomap) 的基本 出发点,是认为低维流Î~嵌入到 高维空 间之后,直接在高维空间 中计算直线距离具有误导性,因为高维空间中的直线距离在低维嵌入流形上是不可达的.如图 所示,低维嵌入流形上两点间的距离是”测地线” (geodesic)距离。

那么,如何计算测地线距离呢?这时我们可利用流形在局部上与 欧氏空间同胚这个性质,对每个点基于欧 氏距离找出其近邻点,然后就能建立一个近邻连接图,图中近邻点之间存在连接,而非近邻点之间不存在连接, 于是,计算两点之间测地线距离的问题就转变为计算近邻连接图上两点之间的最短路径问题.
在近邻连接图上计算两点间的最短路径?可采用著名的Dijkstra算法或Floyd算法,在得到任意两点的距离之后,就可通过MDS 方法来获得样本点在低维空间中的坐标。

流行学习算法LLE:局部线性嵌入
LLE首先假设数据在较小的局部是线性的,也就是说,某一个数据可以由它邻域中的几个样本来线性表示。比如我们有一个样本x1,我们在它的原始高维邻域里用K-近邻思想找到和它最近的三个样本x2,x3,x4. 然后我们假设x1可以由x2,x3,x4线性表示,即
其中,w12,w13,w14为权重系数。在我们通过LLE降维后,我们希望x1在低维空间对应的投影x′1和x2,x3,x4对应的投影x′2,x′3,x′4也尽量保持同样的线性关系,即
也就是说,投影前后线性关系的权重系数w12,w13,w14是尽量不变或者最小改变的。
从上面可以看出,线性关系只在样本的附近起作用,离样本远的样本对局部的线性关系没有影响,因此降维的复杂度降低了很多。
对于LLE算法,我们首先要确定邻域大小的选择,即我们需要多少个邻域样本来线性表示某个样本。假设这个值为k。我们可以通过和KNN一样的思想通过距离度量比如欧式距离来选择某样本的k个最近邻。
在寻找到某个样本的xi的k个最近邻之后我们就需要找到找到xi和这k个最近邻之间的线性关系,也就是要找到线性关系的权重系数。找线性关系,这显然是一个回归问题。假设我们有m个n维样本{x1,x2,…,xm},我们可以用均方差作为回归问题的损失函数:即:
一般我们也会对权重系数$w_{ij}$做归一化的限制,即权重系数需要满足
对于不在样本$x_i$邻域内的样本$x_j$,我们令对应的$w_{ij}=0$.也就是我们需要通过上面两个式子求出我们的权重系数。一般我们可以通过矩阵和拉格朗日子乘法来求解这个最优化问题。(这个推导就不写了)
最后得到
其中$W_i=(w_{i1},w_{i2},…w_{ik})^T$ ,矩阵$Z_i=(x_i−x_j)^T(x_i−x_j)$,其中$1_k$ 为k维全1向量。
在我们得到了高维的权重系数,那么我们希望这些权重系数对应的线性关系在降维后的低维一样得到保持。假设我们的n维样本集{x1,x2,…,xm}在低维的d维度对应投影为{y1,y2,…,ym}, 则我们希望保持线性关系,也就是希望对应的均方差损失函数最小,即最小化损失函数J(Y)如下:
这个优化目标与之前的同形,唯一的区别是之前需要确定权重系数$w_i$,而现在是知道权重系数,需要确定的是$x_i$对应的低维空间坐标$y_i$。
令$M=(I-W)^T(I-W)$ ,则优化函数转变为最小化下式:$J(Y) = tr(Y^TMY)$,tr为迹函数。约束函数矩阵化为:$Y^TY=mI$
上式可通过特征值分解求解:M 最小的 d’ 个特征值对应的特征向量组成的矩阵即为 $Z^T$.
算法流程:

从图中可以看出,LLE算法主要分为三步,第一步是求K近邻的过程,这个过程使用了和KNN算法一样的求最近邻的方法。第二步,就是对每个样本求它在邻域里的K个近邻的线性关系,得到线性关系权重系数W,第三步就是利用权重系数来在低维里重构样本数据。

应用
我们将会展示两种主要的降维方法:投影(projection)和流形学习(Manifold Learning),同时我们还会介绍三种流行的降维技术:主成分分析(PCA),核主成分分析(Kernel PCA)和局部线性嵌入(LLE)。
主成分分析(PCA)
主成分分析(Principal Component Analysis)是目前为止最流行的降维算法。首先它找到接近数据集分布的超平面,然后将所有的数据都投影到这个超平面上。
保留(最大)方差
在将训练集投影到较低维超平面之前,您首先需要选择正确的超平面。例如图左侧是一个简单的二维数据集,以及三个不同的轴(即一维超平面)。图右边是将数据集投影到每个轴上的结果。正如你所看到的,投影到实线上保留了最大方差,而在点线上的投影只保留了非常小的方差,投影到虚线上保留的方差则处于上述两者之间。

选择保持最大方差的轴看起来是合理的,因为它很可能比其他投影损失更少的信息。证明这种选择的另一种方法是,选择这个轴使得将原始数据集投影到该轴上的均方距离最小。这是就 PCA 背后的思想,相当简单。
主成分(Principle Componets)
PCA 寻找训练集中可获得最大方差的轴。在上图中,它是一条实线。它还发现了一个与第一个轴正交的第二个轴,选择它可以获得最大的残差。在这个 2D 例子中,没有选择:就只有这条点线。但如果在一个更高维的数据集中,PCA 也可以找到与前两个轴正交的第三个轴,以及与数据集中维数相同的第四个轴,第五个轴等。 定义第i个轴的单位矢量被称为第i个主成分(PC)。在图中,第一个 PC 是c1,第二个 PC 是c2。在投影图中,前两个 PC 用平面中的正交箭头表示,第三个 PC 与上述 PC 形成的平面正交(指向上或下)
概述: 主成分的方向不稳定:如果您稍微打乱一下训练集并再次运行 PCA,则某些新 PC 可能会指向与原始 PC 方向相反。但是,它们通常仍位于同一轴线上。在某些情况下,一对 PC 甚至可能会旋转或交换,但它们定义的平面通常保持不变。
那么如何找到训练集的主成分呢?幸运的是,有一种称为奇异值分解(SVD)的标准矩阵分解技术,可以将训练集矩阵X分解为三个矩阵$U·Σ·V^T$的点积,其中$V^T$$包含我们想要的所有主成分,如下所示。

下面的 Python 代码使用了 Numpy 提供的svd()函数获得训练集的所有主成分,然后提取前两个 PC:
1 | X_centered=X-X.mean(axis=0) # 中心化 |
警告:PCA 假定数据集以原点为中心。正如我们将看到的,Scikit-Learn 的PCA类负责为您的数据集中心化处理。但是,如果您自己实现 PCA(如前面的示例所示),或者如果您使用其他库,不要忘记首先要先对数据做中心化处理。
投影到d维空间:
一旦确定了所有的主成分,你就可以通过将数据集投影到由前d个主成分构成的超平面上,从而将数据集的维数降至d维。选择这个超平面可以确保投影将保留尽可能多的方差。
为了将训练集投影到超平面上,可以简单地通过计算训练集矩阵X和Wd的点积,Wd定义为包含前d个主成分的矩阵(即由V^T的前d列组成的矩阵)
将训练集投影到d维空间的公式:
下面的 Python 代码将训练集投影到由前两个主成分定义的超平面上:
1 | W2=V.T[:,:2] # 降为2维 |
使用 Scikit-Learn
Scikit-Learn 的 PCA 类使用 SVD 分解来实现,就像我们之前做的那样。以下代码应用 PCA 将数据集的维度降至两维(请注意,它会自动处理数据的中心化):
1 | from sklearn.decomposition import PCA |
将 PCA 转化器应用于数据集后,可以使用components_访问每一个主成分(注意,它返回以 PC 作为水平向量的矩阵,因此,如果我们想要获得第一个主成分则可以写成pca.components_.T[:,0])。
方差解释率(Explained Variance Ratio)
另一个非常有用的信息是每个主成分的方差解释率,可通过explained_variance_ratio_变量获得。它表示位于每个主成分轴上的数据集方差的比例。例如,让我们看下图中表示的三维数据集前两个分量的方差解释率:
1 | print(pca.explained_variance_ratio_) |
这表明,84.2% 的数据集方差位于第一轴,14.6% 的方差位于第二轴。第三轴的这一比例不到1.2%,因此可以认为它可能没有包含什么信息
选择正确的维度
通常我们倾向于选择加起来到方差解释率能够达到足够占比(例如 95%)的维度的数量,而不是任意选择要降低到的维度数量。当然,除非您正在为数据可视化而降低维度 — 在这种情况下,您通常希望将维度降低到 2 或 3。
下面的代码在不降维的情况下进行 PCA,然后计算出保留训练集方差 95% 所需的最小维数:
1 | pca=PCA() |
你可以设置n_components = d并再次运行 PCA。但是,有一个更好的选择:不指定你想要保留的主成分个数,而是将n_components设置为 0.0 到 1.0 之间的浮点数,表明您希望保留的方差比率:
1 | pca=PCA(n_components=0.95) |
另一种选择是画出方差解释率关于维数的函数(简单地绘制cumsum)。曲线中通常会有一个肘部,方差解释率停止快速增长。您可以将其视为数据集的真正的维度。在这种情况下,您可以看到将维度降低到大约100个维度不会失去太多的可解释方差。
PCA 压缩
显然,在降维之后,训练集占用的空间要少得多。例如,尝试将 PCA 应用于 MNIST 数据集,同时保留 95% 的方差。你应该发现每个实例只有 150 多个特征,而不是原来的 784 个特征。因此,尽管大部分方差都保留下来,但数据集现在还不到其原始大小的 20%!这是一个合理的压缩比率,您可以看到这可以如何极大地加快分类算法(如 SVM 分类器)的速度。
通过应用 PCA 投影的逆变换,也可以将缩小的数据集解压缩回 784 维。当然这并不会返回给你最原始的数据,因为投影丢失了一些信息(在5%的方差内),但它可能非常接近原始数据。原始数据和重构数据之间的均方距离(压缩然后解压缩)被称为重构误差(reconstruction error)。例如,下面的代码将 MNIST 数据集压缩到 154 维,然后使用inverse_transform()方法将其解压缩回 784 维。图 8-9 显示了原始训练集(左侧)的几位数字在压缩并解压缩后(右侧)的对应数字。您可以看到有轻微的图像质量降低,但数字仍然大部分完好无损。
1 | pca=PCA(n_components=154) |

PCA逆变换公式,回退到原来的数据维度
增量 PCA(Incremental PCA)
先前 PCA 实现的一个问题是它需要在内存中处理整个训练集以便 SVD 算法运行。幸运的是,我们已经开发了增量 PCA(IPCA)算法:您可以将训练集分批,并一次只对一个批量使用 IPCA 算法。这对大型训练集非常有用,并且可以在线应用 PCA(即在新实例到达时即时运行)。
下面的代码将 MNIST 数据集分成 100 个小批量(使用 NumPy 的array_split()函数),并将它们提供给 Scikit-Learn 的IncrementalPCA类,以将 MNIST 数据集的维度降低到 154 维(就像以前一样)。请注意,您必须对每个最小批次调用partial_fit()方法,而不是对整个训练集使用fit()方法
1 | from sklearn.decomposition import IncrementalPCA |
或者,您可以使用 NumPy 的memmap类,它允许您操作存储在磁盘上二进制文件中的大型数组,就好像它完全在内存中;该类仅在需要时加载内存中所需的数据。由于增量 PCA 类在任何时间内仅使用数组的一小部分,因此内存使用量仍受到控制。这可以调用通常的fit()方法,如下面的代码所示:
1 | X_mm=np.memmap(filename,dtype='float32',mode='readonly',shape=(m,n)) |
随机 PCA(Randomized PCA)
Scikit-Learn 提供了另一种执行 PCA 的选择,称为随机 PCA。这是一种随机算法,可以快速找到前d个主成分的近似值。它的计算复杂度是O(m × d^2) + O(d^3),而不是O(m × n^2) + O(n^3),所以当d远小于n时,它比之前的算法快得多。
1 | rnd_pca=PCA(n_components=154,svd_solver='randomized') |
核 PCA(Kernel PCA)
例如,下面的代码使用 Scikit-Learn 的KernelPCA类来执行带有 RBF 核的 kPCA
1 | from sklearn.decomposition import KernelPCA |

选择一种核并调整超参数
由于 kPCA 是无监督学习算法,因此没有明显的性能指标可以帮助您选择最佳的核方法和超参数值。但是,降维通常是监督学习任务(例如分类)的准备步骤,因此您可以简单地使用网格搜索来选择可以让该任务达到最佳表现的核方法和超参数。例如,下面的代码创建了一个两步的流水线,首先使用 kPCA 将维度降至两维,然后应用 Logistic 回归进行分类。然后它使用Grid SearchCV为 kPCA 找到最佳的核和gamma值,以便在最后获得最佳的分类准确性:
1 | from sklearn.model_selection import GridSearchCV from sklearn.linear_model import LogisticRegression from sklearn.pipeline import Pipeline |
你可以通过调用best_params_变量来查看使模型效果最好的核和超参数:
1 | print(grid_search.best_params_) |
另一种完全为非监督的方法,是选择产生最低重建误差的核和超参数。但是,重建并不像线性 PCA 那样容易。这里是原因:图 8-11 显示了原始瑞士卷 3D 数据集(左上角),并且使用 RBF 核应用 kPCA 后生成的二维数据集(右上角)。由于核技巧,这在数学上等同于使用特征映射φ将训练集映射到无限维特征空间(右下),然后使用线性 PCA 将变换的训练集投影到 2D。请注意,如果我们可以在缩减空间中对给定实例实现反向线性 PCA 步骤,则重构点将位于特征空间中,而不是位于原始空间中(例如,如图中由x表示的那样)。由于特征空间是无限维的,我们不能找出重建点,因此我们无法计算真实的重建误差。幸运的是,可以在原始空间中找到一个贴近重建点的点。这被称为重建前图像(reconstruction pre-image)。一旦你有这个前图像,你就可以测量其与原始实例的平方距离。然后,您可以选择最小化重建前图像错误的核和超参数。

您可能想知道如何进行这种重建。一种解决方案是训练一个监督回归模型,将预计实例作为训练集,并将原始实例作为训练目标。如果您设置了fit_inverse_transform = True,Scikit-Learn 将自动执行此操作,代码如下所示:
1 | rbf_pca = KernelPCA(n_components = 2, kernel="rbf", gamma=0.0433,fit_inverse_transform=True) |
概述:默认条件下,fit_inverse_transform = False并且KernelPCA没有inverse_tranfrom()方法。这种方法仅仅当fit_inverse_transform = True的情况下才会创建。
你可以计算重建前图像误差:
1 | from sklearn.metrics import mean_squared_error |
现在你可以使用交叉验证的方格搜索来寻找可以最小化重建前图像误差的核方法和超参数。
局部线性嵌入LLE
局部线性嵌入(Locally Linear Embedding)是另一种非常有效的非线性降维(NLDR)方法。这是一种流形学习技术,不依赖于像以前算法那样的投影。简而言之,LLE 首先测量每个训练实例与其最近邻(c.n.)之间的线性关系,然后寻找能最好地保留这些局部关系的训练集的低维表示(稍后会详细介绍) 。这使得它特别擅长展开扭曲的流形,尤其是在没有太多噪音的情况下。
例如,以下代码使用 Scikit-Learn 的LocallyLinearEmbedding类来展开瑞士卷。得到的二维数据集如图所示。正如您所看到的,瑞士卷被完全展开,实例之间的距离保存得很好。但是,距离不能在较大范围内保留的很好:展开的瑞士卷的左侧被挤压,而右侧的部分被拉长。尽管如此,LLE 在对流形建模方面做得非常好。
1 | from sklearn.manifold import LocallyLinearEmbedding |

其他降维方法
多维缩放(MDS)在尝试保持实例之间距离的同时降低了维度
Isomap 通过将每个实例连接到最近的邻居来创建图形,然后在尝试保持实例之间的测地距离时降低维度。
t-分布随机邻域嵌入(t-Distributed Stochastic Neighbor Embedding,t-SNE)可以用于降低维度,同时试图保持相似的实例临近并将不相似的实例分开。它主要用于可视化,尤其是用于可视化高维空间中的实例(例如,可以将MNIST图像降维到 2D 可视化)。
线性判别分析(Linear Discriminant Analysis,LDA)实际上是一种分类算法,但在训练过程中,它会学习类之间最有区别的轴,然后使用这些轴来定义用于投影数据的超平面。LDA 的好处是投影会尽可能地保持各个类之间距离,所以在运行另一种分类算法(如 SVM 分类器)之前,LDA 是很好的降维技术。

练习题
- 减少数据集维度的主要动机是什么?主要缺点是什么?
- 什么是维度爆炸?
- 一旦对某数据集降维,我们可能恢复它吗?如果可以,怎样做才能恢复?如果不可以,为什么?
- PCA 可以用于降低一个高度非线性对数据集吗?
- 假设你对一个 1000 维的数据集应用 PCA,同时设置方差解释率为 95%,你的最终数据集将会有多少维?
- 在什么情况下你会使用普通的 PCA,增量 PCA,随机 PCA 和核 PCA?
- 你该如何评价你的降维算法在你数据集上的表现?
- 将两个不同的降维算法串联使用有意义吗?
1、动机:为了加速后续训练算法(在某些情况下,它甚至可以消除噪声和冗余特征,使训练算法表现更好); 通过可视化数据深入了解最重要的特征; 节省空间(压缩)。缺点:某些信息丢失,可能会降低后续训练算法的性能; 计算密集; 为机器学习管道增加了一些复杂性;转换后的功能通常难以解释。
2、在机器学习中,一个常见的表现是随机采样的高维向量通常非常稀疏,增加了过拟合的风险,并且在没有足够的训练数据的情况下很难识别数据中的模式。
3、一旦使用我们讨论过的算法减少了数据集的维数,几乎总是不可能完全逆转操作,因为在降维期间某些信息会丢失。 此外,虽然一些算法(例如PCA)具有可以重建与原始数据相对类似的数据集的简单反向变换过程,但是其他算法(例如T-SNE)则不然。
4、PCA可用于显着降低大多数数据集的维度,即使它们是高度非线性的,因为它至少可以消除无用的维度。 但是,如果没有无用的维度 - 例如,瑞士卷 - 那么使用PCA降低维数将失去太多信息。 你想要展开瑞士卷,而不是挤压它。
5、这是一个棘手的问题:它取决于数据集。 让我们看看两个极端的例子。 首先,假设数据集由几乎完全对齐的点组成。 在这种情况下,PCA可以将数据集减少到一维,同时仍然保留95%的方差。 现在想象一下,数据集由完全随机的点组成,分散在1000个维度周围。 在这种情况下,需要所有1,000个维度来保持95%的方差。 所以答案是,它取决于数据集,它可以是1到1,000之间的任何数字。 将解释的方差绘制为维数的函数是一种粗略了解数据集内在维度的方法。
6、常规PCA是默认值,但仅当数据集有足够内存时才有效。 当您需要在每次新实例到达时动态应用PCA,增量PCA对于在线任务很有用。 当您想要显着降低维度并且有足够内存时,随机PCA非常有用; 在这种情况下,它比普通PCA快得多。 最后,Kernel PCA对非线性数据集非常有用。
7、直观地说,如果从数据集中消除了大量维度而不会丢失太多信息,则降维算法表现良好。 衡量这种情况的一种方法是应用反向变换并测量重建误差。 但是,并非所有降维算法都提供逆向变换。
8、链接两个不同的降维算法绝对有意义。 一个常见的例子是使用PCA快速摆脱大量无用的维度,然后应用另一个慢得多的降维算法,如LLE。 这种两步法可能会产生与仅使用LLE相同的性能,但只需要很短的时间。