-
记得前几天在汇报时,讲到LLE降维算法时,洋洋洒洒讲了一大堆公式推导,之后老师问了一个很实在的问题:什么是流形,当时支支吾吾说了半天,都没说到点上,后来查阅了一些相关资料,现在总结如下。
-
前面那篇文章已经介绍过如何用主成分分析降维——它可以在减少数据集特征的同时,保留数据点间的必要关系。虽然 PCA 是一个灵活、快速且容易解释的算法,但是它对存在非线性关系的数据集的处理效果并不太好,我们将在后面介绍几个示例。为了弥补这个缺陷,我们选择另外一种方法——流形学习(manifold learning)。流形学习是一种无监督评估器,它试图将一个低维度流形嵌入到一个高维度空间来描述数据集。当你思考流形时,建议你设想有一张纸——一个存在于我们所熟悉的三维世界中的二维物体——它可以从两个维度弯折或卷起。提到流形学习这个术语时,可以把这张纸看成那个嵌入三维空间中二维流形。在三维空间中旋转、重定向或者伸展这张纸,都不会改变它的平面几何特性:这些操作和线性嵌入类似。如果你弯折、卷曲或者弄皱这张纸,它仍然是一个二维流形,但是嵌入到一个三维空间就不再是线性的了。流形学习算法将试图学习这张纸的二维特征,包括将纸弯曲后放入一个三维空间中。
-
为了说明这个情况,我们生成一个hello形状的图片,之后将一些点填充进去,得到如下的图:
输出图像包含了很多二维的点,它们组成了单词“HELLO”的形状。这个数据形状可以帮助我们通过可视化的方式展现算法的使用过程。
3.1 首先看一下多维标度法(MDS):
通过观察这个数据集,可以看到数据集中选中的 x 值和 y 值并不是对数据的最基本描述:即使放大、缩小或旋转数据,“HELLO”仍然会很明显。例如,如果用一个旋转矩阵来旋转数据,x 和 y 的值将会改变,但是数据形状基本还是一样的(如下图所示):
这说明 x 和 y 的值并不是数据间关系的必要基础特征。这个例子中真正的基础特征是每个点与数据集中其他点的距离。表示这种关系的常用方法是关系(距离)矩阵:对于 N 个点,构建一个 N × N 的矩阵,元素 (i, j ) 是点 i 和点 j 之间的距离。对于 N = 1000 个点,获得了一个 1000 × 1000 的矩阵。画出该矩阵,如下图所示:
如果用类似方法为已经做过旋转和平移变换的数据构建一个距离矩阵,将看到同样的结果。这个距离矩阵给出了一个数据集内部关系的表现形式,这种形式与数据集的旋转和投影无关。但距离矩阵的可视化效果却显得不够直观。上图丢失了我们之前在数据中看到的关于“HELLO”的所有视觉特征。虽然从 (x, y) 坐标计算这个距离矩阵很简单,但是从距离矩阵转换回x 坐标值和 y 坐标值却非常困难。这就是多维标度法(MDS)可以解决的问题:它可以将一个数据集的距离矩阵还原成一个 D 维坐标来表示数据集。仅仅依靠描述数据点间关系的 N × N 距离矩阵,MDS 算法就可以为数据还原出一种可行的二维坐标。还原后的效果如图所示:
既然距离矩阵可以从数据的任意维度进行计算,那么这种方法绝对非常实用。既然可以在一个二维平面中简单地旋转数据,那么也可以将其投影到三维空间。效果如下图:
现在可以通过 MDS 评估器输入这个三维数据,计算距离矩阵,然后得出距离矩阵的最优二维嵌入结果。结果还原了原始数据的形状,如下图:
以上就是使用流形学习评估器希望达成的基本目标:给定一个高维嵌入数据,寻找数据的一个低维表示,并保留数据间的特定关系。在 MDS的示例中,保留的数据是每对数据点之间的距离。 -
非线性嵌入:当MDS失败时:
前面介绍了线性嵌入模型,它包括将数据旋转、平移和缩放到一个高维空间的操作。但是当嵌入为非线性时,即超越简单的操作集合时,MDS算法就会失效。现在看看下面这个将输入数据在三维空间中扭曲成“S”形状的示例:
虽然数据点间基本的关系仍然存在,但是这次数据以非线性的方式进行了变换:它被包裹成了“S”形。如果尝试用一个简单的 MDS 算法来处理这个数据,就无法展示数据非线性嵌入的特征,进而导致我们丢失了这个嵌入式流形的内部基本关系特性,即使是最优的二维线性嵌入也不能破解 S 曲线的谜题,而且还丢失了原始数据的 y 轴信息。如下图所示:
非线性流形:局部线性嵌入
那么该如何改进呢?在学习新的内容之前,先来回顾一下问题的源头:MDS 算法构建嵌入时,总是期望保留相距很远的数据点之间的距离。但是如果修改算法,让它只保留比较接近的点之间的距离呢?嵌入的结果可能会与我们的期望更接近。
可以将这两种思路想象成图 所示的情况。(MDS和LLE表示点间距离的差异)
其中每一条细小的线都表示在嵌入时会保留的距离。左图是用 MDS 算法生成的嵌入模型,它会试图保留数据集中每对数据点间的距离;右图是用流形学习算法局部线性嵌入(LLE)生成的嵌入模型,该方法不保留所有的距离,而是仅保留邻节点间的距离——本例选择与每个点最近的 100 个邻节点。看看左图,就能够明白为什么 MDS 算法会失效了:显然不可能在展开数据的同时,保证每条线段的长度完全不变。相比之下,右图的情况就更乐观一些。我们可以想象着通过某种方式将卷曲的数据展开,并且线段的长度基本保持不变。这就是 LLE 算法的工作原理,它通过对成本函数的全局优化来反映这个逻辑。LLE 有好几种表现形式,这里用 modified LLE 算法来还原嵌入的二维流形。通常情况下,modified LLE 的效果比用其他算法还原实现定义好的流形数据的效果好,它几乎不会造成扭曲,如图所示:
比起原始流形,这个结果虽然出现了一定程度的扭曲,但还是保留了数据的基本关系特性。 -
类似的方法还有拉普拉斯特征映射。核心思想也是在流形中相近的结点我们希望它降维之后也越相近,上面都是从直观上理解各种算法原理,实际还有很复杂的公式推导。不论是LLE还是拉普拉斯特征映射,它们都是强调在原空间距离相近的点降维后也越接近,但没有说明在原空间较远的点降维后有什么限制条件,这样通常都会导致经过降维后虽然相近的点距离足够相近,但原先距离相近的点和原先距离较远的点往往没有明显的界限,没有很好的区分性。以手写数字为例:经过降维后常常得到如下的结果:
基于这种问题,引入了t-SNE算法。不像之前一样使用距离,而是计算原空间和降维后空间各个点的相似度,用KL散度来描述前后空间分布的相似度:
P ( x j ∣ x i ) = S ( x i , x j ) ∑ k ≠ i S ( x i , x k ) Q ( z j ∣ z i ) = S ′ ( z i , z j ) ∑ k ≠ i S ′ ( z i , z k ) P\left(x^{j} | x^{i}\right)=\frac{S\left(x^{i}, x^{j}\right)}{\sum_{k \neq i} S\left(x^{i}, x^{k}\right)} \qquad Q\left(z^{j} | z^{i}\right)=\frac{S^{\prime}\left(z^{i}, z^{j}\right)}{\sum_{k \neq i} S^{\prime}\left(z^{i}, z^{k}\right)} P(xj∣xi)=∑k̸=iS(xi,xk)S(xi,xj)Q(zj∣zi)=∑k̸=iS′(zi,zk)S′(zi,zj)
L = ∑ i K L ( P ( ∗ ∣ x i ) ∥ Q ( ∗ ∣ z i ) ) L=\sum_{i} K L\left(P\left(* | x^{i}\right) \| Q\left(* | z^{i}\right)\right) L=i∑KL(P(∗∣xi)∥Q(∗∣zi))
= ∑ i ∑ j P ( x j ∣ x i ) log P ( x j ∣ x i ) Q ( z j ∣ z i ) \quad \quad =\sum_{i} \sum_{j} P\left(x^{j} | x^{i}\right) \log \frac{P\left(x^{j} | x^{i}\right)}{Q\left(z^{j} | z^{i}\right)} =i∑j∑P(xj∣xi)logQ(zj∣zi)P(xj∣xi)
计算原空间和目标空间相似度时,t-SNE 使用不同的计算公式:
S ( x i , x j ) = exp ( − ∥ x i − x j ∥ 2 ) S\left(x^{i}, x^{j}\right)=\exp \left(-\left\|x^{i}-x^{j}\right\|_{2}\right) S(xi,xj)=exp(−∥∥xi−xj∥∥2) S ′ ( z i , z j ) = 1 / 1 + ∥ z i − z j ∥ 2 S^{\prime}\left(z^{i}, z^{j}\right)=1 / 1+\left\|z^{i}-z^{j}\right\|_{2} S′(zi,zj)=1/1+∥∥zi−zj∥∥2
最后的效果可以看到不仅每一个类别的数字都聚在一起,不同类别的数字也区分较明显,效果不错。
参考资料:Python数据科学手册,台大李宏毅机器学习公开课教程。