Sklearn 与 TensorFlow 机器学习实用指南——第八章总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yanying1113/article/details/86470487


第八章主要讲解了降维和聚类(正文没有,代码中有所涉及)相关内容,本文做监督概述,参考 地址,代码 地址
很多机器学习的问题都会涉及到有着几千甚至数百万维的特征的训练实例。这不仅让训练过程变得非常缓慢,同时还很难找到一个很好的解,我们接下来就会遇到这种情况。这种问题通常被称为维数灾难(curse of dimentionality)。

警告:降维肯定会丢失一些信息(这就好比将一个图片压缩成 JPEG 的格式会降低图像的质量),因此即使这种方法可以加快训练的速度,同时也会让你的系统表现的稍微差一点。降维会让你的工作流水线更复杂因而更难维护。所有你应该先尝试使用原始的数据来训练,如果训练速度太慢的话再考虑使用降维。在某些情况下,降低训练集数据的维度可能会筛选掉一些噪音和不必要的细节,这可能会让你的结果比降维之前更好(这种情况通常不会发生;它只会加快你训练的速度)。

本章中,我们将会讨论维数灾难问题并且了解在高维空间的数据。然后,我们将会展示两种主要的降维方法:投影(projection)和流形学习(Manifold Learning),同时我们还会介绍三种流行的降维技术:主成分分析(PCA),核主成分分析(Kernel PCA)和局部线性嵌入(LLE)。

维数灾难

很多物体在高维空间表现的十分不同。比如,如果你在一个正方形单元中随机取一个点(一个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(大致 1000000/6的开方)!这非常违反直觉:当它们都位于同一单元超立方体内时,两点是怎么距离这么远的?这一事实意味着高维数据集有很大风险分布的非常稀疏:大多数训练实例可能彼此远离。当然,这也意味着一个新实例可能远离任何训练实例,这使得预测的可靠性远低于我们处理较低维度数据的预测,因为它们将基于更大的推测(extrapolations)。
简而言之,训练集的维度越高,过拟合的风险就越大。

降维的主要方法

在我们深入研究具体的降维算法之前,我们来看看降低维度的两种主要方法:投影和流形学习。

投影(Projection)

在大多数实际问题中,训练实例并不是在所有维度上均匀分布的。一些特征相关性不大,一些特征高度相关。
比如将3D数据集投影到2D,实现了降维。
在这里插入图片描述
在这里插入图片描述
除了简单地投影到低维空间之外,子空间可能发生扭动和旋转,比如著名地如是滚动玩具数据集。
在这里插入图片描述
在这里插入图片描述

流形学习

上面提到的瑞士卷一个是二维流形的例子。
许多降维算法通过对训练实例所在的流形进行建模从而达到降维目的;这叫做流形学习。它依赖于流形猜想(manifold assumption),也被称为流形假设(manifold hypothesis),它认为大多数现实世界的高维数据集大都靠近一个更低维的流形。这种假设经常在实践中被证实。
流形假设通常包含着另一个隐含的假设:你现在的手上的工作(例如分类或回归)如果在流形的较低维空间中表示,那么它们会变得更简单。

主成分分析(PCA)

主成分分析(Principal Component Analysis)是目前为止最流行的降维算法。首先它找到接近数据集分布的超平面,然后将所有的数据都投影到这个超平面上。

保留(最大)方差

在将训练集投影到较低维超平面之前,您首先需要选择正确的超平面。下图右边是将数据集投影到每个轴上的结果。正如你所看到的,投影到实线上保留了最大方差,而在点线上的投影只保留了非常小的方差,投影到虚线上保留的方差则处于上述两者之间。
在这里插入图片描述
选择保持最大方差的轴看起来是合理的,因为它很可能比其他投影损失更少的信息。证明这种选择的另一种方法是,选择这个轴使得将原始数据集投影到该轴上的均方距离最小。这是就 PCA 背后的思想,相当简单。

主成分(Principle Componets)

PCA 寻找训练集中可获得最大方差的轴。

概述: 主成分的方向不稳定:如果您稍微打乱一下训练集并再次运行 PCA,则某些新 PC 可能会指向与原始 PC 方向相反。但是,它们通常仍位于同一轴线上。在某些情况下,一对 PC 甚至可能会旋转或交换,但它们定义的平面通常保持不变。

那么如何找到训练集的主成分呢?幸运的是,有一种称为奇异值分解(SVD)的标准矩阵分解技术,可以将训练集矩阵X分解为三个矩阵U·Σ·VT的点积,其中VT包含我们想要的所有主成分。

警告:PCA 假定数据集以原点为中心。正如我们将看到的,Scikit-Learn 的PCA类负责为您的数据集中心化处理。但是,如果您自己实现 PCA(如前面的示例所示),或者如果您使用其他库,不要忘记首先要先对数据做中心化处理。

投影到d维空间

一旦确定了所有的主成分,你就可以通过将数据集投影到由前d个主成分构成的超平面上,从而将数据集的维数降至d维。选择这个超平面可以确保投影将保留尽可能多的方差。

为了将训练集投影到超平面上,可以简单地通过计算训练集矩阵X和Wd的点积,Wd定义为包含前d个主成分的矩阵(即由VT的前d列组成的矩阵)。
将训练集投影到d维空间
在这里插入图片描述

使用 Scikit-Learn

Scikit-Learn 的 PCA 类使用 SVD 分解(奇异值分解)来实现,就像我们之前做的那样。以下代码应用 PCA 将数据集的维度降至两维(请注意,它会自动处理数据的中心化):

from sklearn.decomposition import PCA
pca=PCA(n_components=2)
X2D=pca.fit_transform(X)

将 PCA 转化器应用于数据集后,可以使用components_访问每一个主成分(注意,它返回以 PC 作为水平向量的矩阵,因此,如果我们想要获得第一个主成分则可以写成pca.components_.T[:,0])。

方差解释率(Explained Variance Ratio)

另一个非常有用的信息是每个主成分的方差解释率,可通过explained_variance_ratio_变量获得。它表示位于每个主成分轴上的数据集方差的比例。
例如,让我们看一下上图中表示的三维数据集前两个分量的方差解释率:

print(pca.explained_variance_ratio_)
array([0.84248607, 0.14631839])

这表明,84.2% 的数据集方差位于第一轴,14.6% 的方差位于第二轴。第三轴的这一比例不到1.2%,因此可以认为它可能没有包含什么信息。

选择正确的维度

通常我们倾向于选择加起来到方差解释率能够达到足够占比(例如 95%)的维度的数量,而不是任意选择要降低到的维度数量。
下面的代码在不降维的情况下进行 PCA,然后计算出保留训练集方差 95% 所需的最小维数:

pca=PCA()
pac.fit(X)
cumsum=np.cumsum(pca.explained_variance_ratio_)
d=np.argmax(cumsum>=0.95)+1

你可以设置n_components = d并再次运行 PCA。但是,有一个更好的选择:不指定你想要保留的主成分个数,而是将n_components设置为 0.0 到 1.0 之间的浮点数,表明您希望保留的方差比率:

pca=PCA(n_components=0.95)
X_reduced=pca.fit_transform(X)

PCA压缩

在降维之后,训练集占用的空间要少得多。例如,尝试将 PCA 应用于 MNIST 数据集,同时保留 95% 的方差。你应该发现每个实例只有 150 多个特征,而不是原来的 784 个特征。因此,尽管大部分方差都保留下来,但数据集现在还不到其原始大小的 20%!这是一个合理的压缩比率,您可以看到这可以如何极大地加快分类算法。

通过应用 PCA 投影的逆变换,也可以将缩小的数据集解压缩回 784 维。原始数据和重构数据之间的均方距离(压缩然后解压缩)被称为重构误差(reconstruction error)。
PCA逆变换,回退到原来的数据维度
在这里插入图片描述

增量 PCA(Incremental PCA)

先前 PCA 实现的一个问题是它需要在内存中处理整个训练集以便 SVD 算法运行。幸运的是,我们已经开发了增量 PCA(IPCA)算法:您可以将训练集分批,并一次只对一个批量使用 IPCA 算法。这对大型训练集非常有用,并且可以在线应用 PCA(即在新实例到达时即时运行)。

随机 PCA(Randomized PCA)

Scikit-Learn 提供了另一种执行 PCA 的选择,称为随机 PCA。这是一种随机算法,可以快速找到前d个主成分的近似值。它的计算复杂度是O(m × d2) + O(d3),而不是O(m × n2) + O(n3),所以当d远小于n时,它比之前的算法快得多。

rnd_pca=PCA(n_components=154,svd_solver='randomized')
X_reduced=rnd_pca.fit_transform(X_mnist)

核 PCA(Kernel PCA)

在第 5 章中,我们讨论了核技巧,一种将实例隐式映射到非常高维空间(称为特征空间)的数学技术,让支持向量机可以应用于非线性分类和回归。回想一下,高维特征空间中的线性决策边界对应于原始空间中的复杂非线性决策边界。

事实证明,同样的技巧可以应用于 PCA,从而可以执行复杂的非线性投影来降低维度。这就是所谓的核 PCA(kPCA)。它通常能够很好地保留投影后的簇,有时甚至可以展开分布近似于扭曲流形的数据集。

选择一种核并调整超参数

由于 kPCA 是无监督学习算法,因此没有明显的性能指标可以帮助您选择最佳的核方法和超参数值。但是,降维通常是监督学习任务(例如分类)的准备步骤,因此您可以简单地使用网格搜索来选择可以让该任务达到最佳表现的核方法和超参数。
例如,下面的代码创建了一个两步的流水线,首先使用 kPCA 将维度降至两维,然后应用 Logistic 回归进行分类。然后它使用Grid SearchCV为 kPCA 找到最佳的核和gamma值,以便在最后获得最佳的分类准确性:

from sklearn.model_selection import GridSearchCV 
from sklearn.linear_model import LogisticRegression 
from sklearn.pipeline import Pipeline

clf = Pipeline([
        ("kpca", KernelPCA(n_components=2)),
        ("log_reg", LogisticRegression())
])
param_grid = [{
        "kpca__gamma": np.linspace(0.03, 0.05, 10),
        "kpca__kernel": ["rbf", "sigmoid"]
    }]
grid_search = GridSearchCV(clf, param_grid, cv=3)
grid_search.fit(X, y)

另一种完全为非监督的方法,是选择产生最低重建误差的核和超参数。

LLE

局部线性嵌入(Locally Linear Embedding)是另一种非常有效的非线性降维(NLDR)方法。这是一种流形学习技术,不依赖于像以前算法那样的投影。简而言之,LLE 首先测量每个训练实例与其最近邻(c.n.)之间的线性关系,然后寻找能最好地保留这些局部关系的训练集的低维表示。这使得它特别擅长展开扭曲的流形,尤其是在没有太多噪音的情况下。

其他降维方法

多维缩放(MDS)在尝试保持实例之间距离的同时降低了维度。

Isomap 通过将每个实例连接到最近的邻居来创建图形,然后在尝试保持实例之间的测地距离时降低维度。

t-分布随机邻域嵌入(t-Distributed Stochastic Neighbor Embedding,t-SNE)可以用于降低维​​度,同时试图保持相似的实例临近并将不相似的实例分开。它主要用于可视化,尤其是用于可视化高维空间中的实例(例如,可以将MNIST图像降维到 2D 可视化)。

线性判别分析(Linear Discriminant Analysis,LDA)实际上是一种分类算法,但在训练过程中,它会学习类之间最有区别的轴,然后使用这些轴来定义用于投影数据的超平面。LDA 的好处是投影会尽可能地保持各个类之间距离,所以在运行另一种分类算法(如 SVM 分类器)之前,LDA 是很好的降维技术。

习题

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

猜你喜欢

转载自blog.csdn.net/yanying1113/article/details/86470487