Sklearn 与 TensorFlow 机器学习实用指南第二版(六)

Sklearn 与 TensorFlow 机器学习实用指南第二版(六) 协议CC BY-NC-SA 4.0八、降维译者loveSnowBest校对者飞龙、PeterHo、yanmengk、XinQiu、Lisanaaa很多机器学习的问题都会涉及到有着几千甚至数百万维的特征的训练实例。这不仅让训练过程变得非常缓慢同时还很难找到一个很好的解我们接下来就会遇到这种情况。这种问题通常被称为维数灾难curse of dimentionality。幸运的是在现实生活中我们经常可以极大的降低特征维度将一个十分棘手的问题转变成一个可以较为容易解决的问题。例如对于 MNIST 图片集第 3 章中提到图片四周边缘部分的像素几乎总是白的因此你完全可以将这些像素从你的训练集中扔掉而不会丢失太多信息。图 7-6 向我们证实了这些像素的确对我们的分类任务是完全不重要的。同时两个相邻的像素往往是高度相关的如果你想要将他们合并成一个像素比如取这两个像素点的平均值你并不会丢失很多信息。警告降维肯定会丢失一些信息这就好比将一个图片压缩成 JPEG 的格式会降低图像的质量因此即使这种方法可以加快训练的速度同时也会让你的系统表现的稍微差一点。降维会让你的工作流水线更复杂因而更难维护。所有你应该先尝试使用原始的数据来训练如果训练速度太慢的话再考虑使用降维。在某些情况下降低训练集数据的维度可能会筛选掉一些噪音和不必要的细节这可能会让你的结果比降维之前更好这种情况通常不会发生它只会加快你训练的速度。降维除了可以加快训练速度外在数据可视化方面或者 DataViz也十分有用。降低特征维度到 2或者 3维从而可以在图中画出一个高维度的训练集让我们可以通过视觉直观的发现一些非常重要的信息比如聚类。在这一章里我们将会讨论维数灾难问题并且了解在高维空间的数据。然后我们将会展示两种主要的降维方法投影projection和流形学习Manifold Learning同时我们还会介绍三种流行的降维技术主成分分析PCA核主成分分析Kernel PCA和局部线性嵌入LLE。维数灾难我们已经习惯生活在一个三维的世界里以至于当我们尝试想象更高维的空间时我们的直觉不管用了。即使是一个基本的 4D 超正方体也很难在我们的脑中想象出来见图 8-1更不用说一个 200 维的椭球弯曲在一个 1000 维的空间里了。https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/8-1.gif图 8-1 点线方形立方体和超正方体0D 到 4D 超正方体这表明很多物体在高维空间表现的十分不同。比如如果你在一个正方形单元中随机取一个点一个1×1的正方形那么随机选的点离所有边界大于 0.001靠近中间位置的概率为 0.4%1 - 0.998^2换句话说一个随机产生的点不大可能严格落在某一个维度上。但是在一个 1,0000 维的单位超正方体一个1×1×...×1的立方体有 10,000 个 1这种可能性超过了 99.999999%。在高维超正方体中大多数点都分布在边界处。还有一个更麻烦的区别如果你在一个平方单位中随机选取两个点那么这两个点之间的距离平均约为 0.52。如果您在单位 3D 立方体中选取两个随机点平均距离将大致为 0.66。但是在一个 1,000,000 维超立方体中随机抽取两点呢那么平均距离信不信由你大概为 408.25大致√(1,000,000/6)这非常违反直觉当它们都位于同一单元超立方体内时两点是怎么距离这么远的这一事实意味着高维数据集有很大风险分布的非常稀疏大多数训练实例可能彼此远离。当然这也意味着一个新实例可能远离任何训练实例这使得预测的可靠性远低于我们处理较低维度数据的预测因为它们将基于更大的推测extrapolations。简而言之训练集的维度越高过拟合的风险就越大。理论上来说维数爆炸的一个解决方案是增加训练集的大小从而达到拥有足够密度的训练集。不幸的是在实践中达到给定密度所需的训练实例的数量随着维度的数量呈指数增长。如果只有 100 个特征比 MNIST 问题要少得多并且假设它们均匀分布在所有维度上那么如果想要各个临近的训练实例之间的距离在 0.1 以内您需要比宇宙中的原子还要多的训练实例。降维的主要方法在我们深入研究具体的降维算法之前我们来看看降低维度的两种主要方法投影和流形学习。投影Projection在大多数现实生活的问题中训练实例并不是在所有维度上均匀分布的。许多特征几乎是常数而其他特征则高度相关如前面讨论的 MNIST。结果所有训练实例实际上位于或接近高维空间的低维子空间内。这听起来有些抽象所以我们不妨来看一个例子。在图 8-2 中您可以看到由圆圈表示的 3D 数据集。https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/8-2.jpeg图 8-2 一个分布接近于 2D 子空间的 3D 数据集注意到所有训练实例的分布都贴近一个平面这是高维3D空间的较低维2D子空间。现在如果我们将每个训练实例垂直投影到这个子空间上就像将短线连接到平面的点所表示的那样我们就可以得到如图 8-3 所示的新 2D 数据集。铛铛铛我们刚刚将数据集的维度从 3D 降低到了 2D。请注意坐标轴对应于新的特征z1和z2平面上投影的坐标。https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/8-3.gif图 8-3 一个经过投影后的新的 2D 数据集但是投影并不总是降维的最佳方法。在很多情况下子空间可能会扭曲和转动比如图 8-4 所示的着名瑞士滚动玩具数据集。https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/8-4.jpeg图 8-4 瑞士滚动数玩具数据集简单地将数据集投射到一个平面上例如直接丢弃x3会将瑞士卷的不同层叠在一起如图 8-5 左侧所示。但是你真正想要的是展开瑞士卷所获取到的类似图 8-5 右侧的 2D 数据集。https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/8-5.jpeg图 8-5 投射到平面的压缩左vs 展开瑞士卷右流形学习瑞士卷一个是二维流形的例子。简而言之二维流形是一种二维形状它可以在更高维空间中弯曲或扭曲。更一般地一个d维流形是类似于d维超平面的n维空间其中d n的一部分。在我们瑞士卷这个例子中d 2n 3它有些像 2D 平面但是它实际上是在第三维中卷曲。许多降维算法通过对训练实例所在的流形进行建模从而达到降维目的这叫做流形学习。它依赖于流形猜想manifold assumption也被称为流形假设manifold hypothesis它认为大多数现实世界的高维数据集大都靠近一个更低维的流形。这种假设经常在实践中被证实。让我们再回到 MNIST 数据集所有手写数字图像都有一些相似之处。它们由连线组成边界是白色的大多是在图片中中间的等等。如果你随机生成图像只有一小部分看起来像手写数字。换句话说如果您尝试创建数字图像那么您的自由度远低于您生成任何随便一个图像时的自由度。这些约束往往会将数据集压缩到较低维流形中。流形假设通常包含着另一个隐含的假设你现在的手上的工作例如分类或回归如果在流形的较低维空间中表示那么它们会变得更简单。例如在图 8-6 的第一行中瑞士卷被分为两类在三维空间中图左上分类边界会相当复杂但在二维展开的流形空间中图右上分类边界是一条简单的直线。但是这个假设并不总是成立。例如在图 8-6 的最下面一行决策边界位于x1 5图左下。这个决策边界在原始三维空间一个垂直平面看起来非常简单但在展开的流形中却变得更复杂了四个独立线段的集合图右下。简而言之如果在训练模型之前降低训练集的维数那训练速度肯定会加快但并不总是会得出更好的训练效果这一切都取决于数据集。希望你现在对于维数爆炸以及降维算法如何解决这个问题有了一定的理解特别是对流形假设提出的内容。本章的其余部分将介绍一些最流行的降维算法。https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/8-6.jpeg图 8-6 决策边界并不总是会在低维空间中变的简单主成分分析PCA主成分分析Principal Component Analysis是目前为止最流行的降维算法。首先它找到接近数据集分布的超平面然后将所有的数据都投影到这个超平面上。保留最大方差在将训练集投影到较低维超平面之前您首先需要选择正确的超平面。例如图 8-7 左侧是一个简单的二维数据集以及三个不同的轴即一维超平面。图右边是将数据集投影到每个轴上的结果。正如你所看到的投影到实线上保留了最大方差而在点线上的投影只保留了非常小的方差投影到虚线上保留的方差则处于上述两者之间。https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/8-7.jpeg图 8-7 选择投射到哪一个子空间选择保持最大方差的轴看起来是合理的因为它很可能比其他投影损失更少的信息。证明这种选择的另一种方法是选择这个轴使得将原始数据集投影到该轴上的均方距离最小。这是就 PCA 背后的思想相当简单。主成分Principle ComponetsPCA 寻找训练集中可获得最大方差的轴。在图 8-7 中它是一条实线。它还发现了一个与第一个轴正交的第二个轴选择它可以获得最大的残差。在这个 2D 例子中没有选择就只有这条点线。但如果在一个更高维的数据集中PCA 也可以找到与前两个轴正交的第三个轴以及与数据集中维数相同的第四个轴第五个轴等。定义第i个轴的单位向量被称为第i个主成分PC。在图 8-7 中第一个 PC 是c1第二个 PC 是c2。在图 8-2 中前两个 PC 用平面中的正交箭头表示第三个 PC 与上述 PC 形成的平面正交指向上或下。概述 主成分的方向不稳定如果您稍微打乱一下训练集并再次运行 PCA则某些新 PC 可能会指向与原始 PC 方向相反。但是它们通常仍位于同一轴线上。在某些情况下一对 PC 甚至可能会旋转或交换但它们定义的平面通常保持不变。那么如何找到训练集的主成分呢幸运的是有一种称为奇异值分解SVD的标准矩阵分解技术可以将训练集矩阵X分解为三个矩阵U·Σ·V^T的点积其中V^T包含我们想要的所有主成分如公式 8-1 所示。公式 8-1 主成分矩阵https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/e-8-1.gif下面的 Python 代码使用了 Numpy 提供的svd()函数获得训练集的所有主成分然后提取前两个 PC:X_centeredX-X.mean(axis0)U,s,Vnp.linalg.svd(X_centered)c1V.T[:,0]c2V.T[:,1]警告PCA 假定数据集以原点为中心。正如我们将看到的Scikit-Learn 的PCA类负责为您的数据集中心化处理。但是如果您自己实现 PCA如前面的示例所示或者如果您使用其他库不要忘记首先要先对数据做中心化处理。投影到d维空间一旦确定了所有的主成分你就可以通过将数据集投影到由前d个主成分构成的超平面上从而将数据集的维数降至d维。选择这个超平面可以确保投影将保留尽可能多的方差。例如在图 8-2 中3D 数据集被投影到由前两个主成分定义的 2D 平面保留了大部分数据集的方差。因此2D 投影看起来非常像原始 3D 数据集。为了将训练集投影到超平面上可以简单地通过计算训练集矩阵X和Wd的点积Wd定义为包含前d个主成分的矩阵即由V^T的前d列组成的矩阵如公式 8-2 所示。公式 8-2 将训练集投影到d维空间https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/tex-4d58b6f45f2e33f3ceb537b2b174c09b.gif下面的 Python 代码将训练集投影到由前两个主成分定义的超平面上W2V.T[:,:2]X2DX_centered.dot(W2)好了你已经知道这个东西了你现在已经知道如何给任何一个数据集降维而又能尽可能的保留原数据集的方差了。使用 Scikit-LearnScikit-Learn 的 PCA 类使用 SVD 分解来实现就像我们之前做的那样。以下代码应用 PCA 将数据集的维度降至两维请注意它会自动处理数据的中心化fromsklearn.decompositionimportPCA pcaPCA(n_components2)X2Dpca.fit_transform(X)将 PCA 转化器应用于数据集后可以使用components_访问每一个主成分注意它返回以 PC 作为水平向量的矩阵因此如果我们想要获得第一个主成分则可以写成pca.components_.T[:,0]。方差解释率Explained Variance Ratio另一个非常有用的信息是每个主成分的方差解释率可通过explained_variance_ratio_变量获得。它表示位于每个主成分轴上的数据集方差的比例。例如让我们看一下图 8-2 中表示的三维数据集前两个分量的方差解释率 print(pca.explained_variance_ratio_) array([0.84248607, 0.14631839])这表明84.2% 的数据集方差位于第一轴14.6% 的方差位于第二轴。第三轴的这一比例不到 1.2%因此可以认为它可能没有包含什么信息。选择正确的维度通常我们倾向于选择加起来到方差解释率能够达到足够占比例如 95%的维度的数量而不是任意选择要降低到的维度数量。当然除非您正在为数据可视化而降低维度 – 在这种情况下您通常希望将维度降低到 2 或 3。下面的代码在不降维的情况下进行 PCA然后计算出保留训练集方差 95% 所需的最小维数pcaPCA()pac.fit(X)cumsumnp.cumsum(pca.explained_variance_ratio_)dnp.argmax(cumsum0.95)1你可以设置n_components d并再次运行 PCA。但是有一个更好的选择不指定你想要保留的主成分个数而是将n_components设置为 0.0 到 1.0 之间的浮点数表明您希望保留的方差比率pcaPCA(n_components0.95)X_reducedpca.fit_transform(X)另一种选择是画出方差解释率关于维数的函数简单地绘制cumsum参见图 8-8。曲线中通常会有一个肘部方差解释率停止快速增长。您可以将其视为数据集的真正的维度。在这种情况下您可以看到将维度降低到大约 100 个维度不会失去太多的可解释方差。https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/8-8.jpeg图 8-8 可解释方差关于维数的函数PCA 压缩显然在降维之后训练集占用的空间要少得多。例如尝试将 PCA 应用于 MNIST 数据集同时保留 95% 的方差。你应该发现每个实例只有 150 多个特征而不是原来的 784 个特征。因此尽管大部分方差都保留下来但数据集现在还不到其原始大小的 20%这是一个合理的压缩比率您可以看到这可以如何极大地加快分类算法如 SVM 分类器的速度。通过应用 PCA 投影的逆变换也可以将缩小的数据集解压缩回 784 维。当然这并不会返回给你最原始的数据因为投影丢失了一些信息在 5% 的方差内但它可能非常接近原始数据。原始数据和重构数据之间的均方距离压缩然后解压缩被称为重构误差reconstruction error。例如下面的代码将 MNIST 数据集压缩到 154 维然后使用inverse_transform()方法将其解压缩回 784 维。图 8-9 显示了原始训练集左侧的几位数字在压缩并解压缩后右侧的对应数字。您可以看到有轻微的图像质量降低但数字仍然大部分完好无损。pcaPCA(n_components154)X_mnist_reducedpca.fit_transform(X_mnist)X_mnist_recoveredpca.inverse_transform(X_mnist_reduced)https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/8-9.gif图 8-9 MNIST 保留 95 方差的压缩逆变换的公式如公式 8-3 所示公式 8-3 PCA 逆变换回退到原来的数据维度https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/tex-9c33b504c86e9c53fd2dab1952e0db41.gif增量 PCAIncremental PCA先前 PCA 实现的一个问题是它需要在内存中处理整个训练集以便 SVD 算法运行。幸运的是我们已经开发了增量 PCAIPCA算法您可以将训练集分批并一次只对一个批量使用 IPCA 算法。这对大型训练集非常有用并且可以在线应用 PCA即在新实例到达时即时运行。下面的代码将 MNIST 数据集分成 100 个小批量使用 NumPy 的array_split()函数并将它们提供给 Scikit-Learn 的IncrementalPCA类以将 MNIST 数据集的维度降低到 154 维就像以前一样。请注意您必须对每个最小批次调用partial_fit()方法而不是对整个训练集使用fit()方法fromsklearn.decompositionimportIncrementalPCA n_batches100inc_pcaIncrementalPCA(n_components154)forX_batchinnp.array_spplit(X_mnist,n_batches):inc_pca.partial_fit(X_batch)X_mnist_reducedinc_pca.transform(X_mnist)或者您可以使用 NumPy 的memmap类它允许您操作存储在磁盘上二进制文件中的大型数组就好像它完全在内存中该类仅在需要时加载内存中所需的数据。由于增量 PCA 类在任何时间内仅使用数组的一小部分因此内存使用量仍受到控制。这可以调用通常的fit()方法如下面的代码所示X_mmnp.memmap(filename,dtypefloat32,modereadonly,shape(m,n))batch_sizem//n_batches inc_pcaIncrementalPCA(n_components154,batch_sizebatch_size)inc_pca.fit(X_mm)随机 PCARandomized PCAScikit-Learn 提供了另一种执行 PCA 的选择称为随机 PCA。这是一种随机算法可以快速找到前d个主成分的近似值。它的计算复杂度是O(m × d^2) O(d^3)而不是O(m × n^2) O(n^3)所以当d远小于n时它比之前的算法快得多。rnd_pcaPCA(n_components154,svd_solverrandomized)X_reducedrnd_pca.fit_transform(X_mnist)核 PCAKernel PCA在第 5 章中我们讨论了核技巧一种将实例隐式映射到非常高维空间称为特征空间的数学技术让支持向量机可以应用于非线性分类和回归。回想一下高维特征空间中的线性决策边界对应于原始空间中的复杂非线性决策边界。事实证明同样的技巧可以应用于 PCA从而可以执行复杂的非线性投影来降低维度。这就是所谓的核 PCAkPCA。它通常能够很好地保留投影后的簇有时甚至可以展开分布近似于扭曲流形的数据集。例如下面的代码使用 Scikit-Learn 的KernelPCA类来执行带有 RBF 核的 kPCA有关 RBF 核和其他核的更多详细信息请参阅第 5 章fromsklearn.decompositionimportKernelPCA rbf_pcaKernelPCA(n_components2,kernelrbf,gamma0.04)X_reducedrbf_pca.fit_transform(X)图 8-10 展示了使用线性核等同于简单的使用 PCA 类RBF 核sigmoid 核Logistic将瑞士卷降到 2 维。https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/8-10.jpeg图 8-10 使用不同核的 kPCA 将瑞士卷降到 2 维选择一种核并调整超参数由于 kPCA 是无监督学习算法因此没有明显的性能指标可以帮助您选择最佳的核方法和超参数值。但是降维通常是监督学习任务例如分类的准备步骤因此您可以简单地使用网格搜索来选择可以让该任务达到最佳表现的核方法和超参数。例如下面的代码创建了一个两步的流水线首先使用 kPCA 将维度降至两维然后应用 Logistic 回归进行分类。然后它使用Grid SearchCV为 kPCA 找到最佳的核和gamma值以便在最后获得最佳的分类准确性fromsklearn.model_selectionimportGridSearchCVfromsklearn.linear_modelimportLogisticRegressionfromsklearn.pipelineimportPipeline clfPipeline([(kpca,KernelPCA(n_components2)),(log_reg,LogisticRegression())])param_grid[{kpca__gamma:np.linspace(0.03,0.05,10),kpca__kernel:[rbf,sigmoid]}]grid_searchGridSearchCV(clf,param_grid,cv3)grid_search.fit(X,y)你可以通过调用best_params_变量来查看使模型效果最好的核和超参数print(grid_search.best_params_){kpca__gamma:0.043333333333333335,kpca__kernel:rbf}另一种完全为非监督的方法是选择产生最低重建误差的核和超参数。但是重建并不像线性 PCA 那样容易。这里是原因图 8-11 显示了原始瑞士卷 3D 数据集左上角并且使用 RBF 核应用 kPCA 后生成的二维数据集右上角。由于核技巧这在数学上等同于使用特征映射φ将训练集映射到无限维特征空间右下然后使用线性 PCA 将变换的训练集投影到 2D。请注意如果我们可以在缩减空间中对给定实例实现反向线性 PCA 步骤则重构点将位于特征空间中而不是位于原始空间中例如如图中由x表示的那样。由于特征空间是无限维的我们不能找出重建点因此我们无法计算真实的重建误差。幸运的是可以在原始空间中找到一个贴近重建点的点。这被称为重建前图像reconstruction pre-image。一旦你有这个前图像你就可以测量其与原始实例的平方距离。然后您可以选择最小化重建前图像错误的核和超参数。https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/8-11.jpeg图 8-11 核 PCA 和重建前图像误差您可能想知道如何进行这种重建。一种解决方案是训练一个监督回归模型将预计实例作为训练集并将原始实例作为训练目标。如果您设置了fit_inverse_transform TrueScikit-Learn 将自动执行此操作代码如下所示rbf_pcaKernelPCA(n_components2,kernelrbf,gamma0.0433,fit_inverse_transformTrue)X_reducedrbf_pca.fit_transform(X)X_preimagerbf_pca.inverse_transform(X_reduced)概述默认条件下fit_inverse_transform False并且KernelPCA没有inverse_tranfrom()方法。这种方法仅仅当fit_inverse_transform True的情况下才会创建。你可以计算重建前图像误差fromsklearn.metricsimportmean_squared_errormean_squared_error(X,X_preimage)32.786308795766132现在你可以使用交叉验证的方格搜索来寻找可以最小化重建前图像误差的核方法和超参数。LLE局部线性嵌入Locally Linear Embedding是另一种非常有效的非线性降维NLDR方法。这是一种流形学习技术不依赖于像以前算法那样的投影。简而言之LLE 首先测量每个训练实例与其最近邻c.n.之间的线性关系然后寻找能最好地保留这些局部关系的训练集的低维表示稍后会详细介绍 。这使得它特别擅长展开扭曲的流形尤其是在没有太多噪音的情况下。例如以下代码使用 Scikit-Learn 的LocallyLinearEmbedding类来展开瑞士卷。得到的二维数据集如图 8-12 所示。正如您所看到的瑞士卷被完全展开实例之间的距离保存得很好。但是距离不能在较大范围内保留的很好展开的瑞士卷的左侧被挤压而右侧的部分被拉长。尽管如此LLE 在对流形建模方面做得非常好。fromsklearn.manifoldimportLocallyLinearEmbedding lleLocallyLinearEmbedding(n_components2,n_neighbors10)X_reducedlle.fit_transform(X)https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/8-12.jpeg图 8-12 使用 LLE 展开瑞士卷这是 LLE 的工作原理首先对于每个训练实例x^(i)该算法识别其最近的k个邻居在前面的代码中k 10中然后尝试将x^(i)重构为这些邻居的线性函数。更具体地找到权重w[i, j]从而使x^(i)和Σ w[i, j] x^(j), j 1 - m之间的平方距离尽可能的小假设如果x^(j)不是x^(i)的k个最近邻时w[i, j] 0。因此LLE 的第一步是方程 8-4 中描述的约束优化问题其中W是包含所有权重w[i, j]的权重矩阵。第二个约束简单地对每个训练实例x^(i)的权重进行归一化。公式 8-2 LLE 第一步对局部关系进行线性建模https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/e-8-2.gif在这步之后权重矩阵W_hat包含权重w_hat[i,j]对训练实例的线形关系进行编码。现在第二步是将训练实例投影到一个d维空间d n中去同时尽可能的保留这些局部关系。如果z^(i)是x^(i)在这个d维空间的图像那么我们想要z^(i)和Σ w_hat[i, j] z^(j), j 1 - m之间的平方距离尽可能的小。这个想法让我们提出了公式 8-5 中的非限制性优化问题。它看起来与第一步非常相似但我们要做的不是保持实例固定并找到最佳权重而是恰相反保持权重不变并在低维空间中找到实例图像的最佳位置。请注意Z是包含所有z^(i)的矩阵。公式 8-3 LLE 第二步保持关系的同时进行降维https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/e-8-3.gifScikit-Learn 的 LLE 实现具有如下的计算复杂度查找k个最近邻为O(m log(m) n log(k))优化权重为O(m n k^3)建立低维表示为O(d m^2)。不幸的是最后一项m^2使得这个算法在处理大数据集的时候表现较差。其他降维方法还有很多其他的降维方法Scikit-Learn 支持其中的好几种。这里是其中最流行的多维缩放MDS在尝试保持实例之间距离的同时降低了维度参见图 8-13Isomap 通过将每个实例连接到最近的邻居来创建图形然后在尝试保持实例之间的测地距离时降低维度。t-分布随机邻域嵌入t-Distributed Stochastic Neighbor Embeddingt-SNE可以用于降低维​​度同时试图保持相似的实例临近并将不相似的实例分开。它主要用于可视化尤其是用于可视化高维空间中的实例例如可以将 MNIST 图像降维到 2D 可视化。线性判别分析Linear Discriminant AnalysisLDA实际上是一种分类算法但在训练过程中它会学习类之间最有区别的轴然后使用这些轴来定义用于投影数据的超平面。LDA 的好处是投影会尽可能地保持各个类之间距离所以在运行另一种分类算法如 SVM 分类器之前LDA 是很好的降维技术。https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/hsn-ml-2e/img/8-13.jpeg图 8-13 使用不同的技术将瑞士卷降维至 2D练习减少数据集维度的主要动机是什么主要缺点是什么什么是维度爆炸一旦对某数据集降维我们可能恢复它吗如果可以怎样做才能恢复如果不可以为什么PCA 可以用于降低一个高度非线性对数据集吗假设你对一个 1000 维的数据集应用 PCA同时设置方差解释率为 95%你的最终数据集将会有多少维在什么情况下你会使用普通的 PCA增量 PCA随机 PCA 和核 PCA你该如何评价你的降维算法在你数据集上的表现将两个不同的降维算法串联使用有意义吗加载 MNIST 数据集在第 3 章中介绍并将其分成一个训练集和一个测试集将前 60,000 个实例用于训练其余 10,000 个用于测试。在数据集上训练一个随机森林分类器并记录了花费多长时间然后在测试集上评估模型。接下来使用 PCA 降低数据集的维度设置方差解释率为 95%。在降维后的数据集上训练一个新的随机森林分类器并查看需要多长时间。训练速度更快接下来评估测试集上的分类器它与以前的分类器比较起来如何使用 t-SNE 将 MNIST 数据集缩减到二维并使用 Matplotlib 绘制结果图。您可以使用 10 种不同颜色的散点图来表示每个图像的目标类别。或者您可以在每个实例的位置写入彩色数字甚至可以绘制数字图像本身的降维版本如果绘制所有数字则可视化可能会过于混乱因此您应该绘制随机样本或只在周围没有其他实例被绘制的情况下绘制。你将会得到一个分隔良好的的可视化数字集群。尝试使用其他降维算法如 PCALLE 或 MDS并比较可视化结果。练习答案请见附录 A。