首页
Preview

2021年你应该了解的11种降维技术

在统计学和机器学习中,数据集中属性、特征或输入变量的数量被称为其维度。例如,我们来看一个非常简单的数据集,包含2个属性,分别为_身高_和_体重_。这是一个2维数据集,该数据集的任何观察结果都可以在2D图中绘制。

如果我们在同一数据集中添加另一个维度,比如_年龄_,它就变成了一个3维数据集,其中任何观察结果都位于3维空间中。

同样,现实世界的数据集具有许多属性。这些数据集的观察结果位于高维空间中,很难想象。以下是数据科学家、统计学家和机器学习工程师考虑的与维度相关的数据集的一般几何解释。

在包含行和列的表格数据集中,列代表n维特征空间的维度,而行是位于该空间中的数据点。

降维只是指在尽可能保留原始数据集中的变化的同时,减少数据集中属性数量的过程。这是一个数据预处理步骤,这意味着我们在训练模型之前执行降维。在本文中,我们将讨论11种这样的降维技术,并使用Python和Scikit-learn库在真实世界的数据集上实现它们。

降维的重要性

当我们降低数据集的维度时,我们会失去一定百分比(通常是1%-15%,取决于我们保留的组件或特征的数量)的原始数据的可变性。但是,不要担心失去原始数据中这么多可变性,因为降维会带来以下优势。

  • 数据中的维数较低意味着更少的训练时间和更少的计算资源,并提高了机器学习算法的整体性能 - 涉及许多特征的机器学习问题使训练非常缓慢。高维空间中的大多数数据点都非常靠近该空间的边界。这是因为高维空间中有很多空间。在高维数据集中,大多数数据点可能彼此之间距离很远。因此,算法无法有效地、高效地训练高维数据。在机器学习中,这种问题被称为维数诅咒 - 这只是一个你不需要担心的技术术语!
  • 降维避免了过度拟合的问题 - 当数据中有许多特征时,模型变得更加复杂,并倾向于过度拟合训练数据。要了解此问题,请阅读我的“如何通过降维减轻过度拟合”文章。
  • 降维对于数据可视化非常有用 - 当我们将高维数据的维数降低到两个或三个组件时,数据可以轻松地绘制在2D或3D图中。要了解此操作,请阅读我的“使用Scikit-learn进行主成分分析(PCA)”文章。
  • 降维处理多重共线性 - 在回归中,多重共线性是指一个独立变量与数据集中的一个或多个其他独立变量高度相关。降维利用这一点,将这些高度相关的变量组合成一组不相关的变量。这将解决多重共线性问题。要了解此操作,请阅读我的“如何将PCA应用于逻辑回归以消除多重共线性?”文章。
  • 降维对于因子分析非常有用 - 这是一种有用的方法,用于查找单个变量中未直接测量的潜在变量,而是从数据集中的其他变量推断出来的潜在变量。这些潜在变量称为因子。要了解此操作,请阅读我的“使用R和Python对女子径赛记录数据进行因子分析”文章。
  • 降维消除了数据中的噪声 - 通过仅保留最重要的特征并删除冗余特征,降维消除了数据中的噪声。这将提高模型准确性。
  • 降维可用于图像压缩 - _图像压缩_是一种技术,可以最小化图像的字节数,同时尽可能保留图像的质量。构成图像的像素可以被视为图像数据的维度(列/变量)。我们执行PCA以保持平衡图像数据中解释的可变性和图像质量的最佳组件数。要了解此操作,请阅读我的“使用主成分分析(PCA)进行图像压缩”文章。
  • 降维可用于将非线性数据转换为线性可分离形式 - 阅读本文的Kernel PCA部分,了解其工作原理!# 降维方法

有几种可以用于不同数据类型、不同需求的降维方法。下表总结了这些降维方法。

(图片来自作者)

主要有两种降维方法,它们通过不同的方式降低维度。很重要的是要区分这两种方法。其中一种方法只保留数据集中最重要的特征,移除多余的特征,没有对特征集进行转换。反向消元、正向选择和随机森林是这种方法的例子。另一种方法找到一组新的特征,对特征集应用适当的转换,新的特征集包含与原始值不同的值。这种方法可以进一步分为线性方法和非线性方法。非线性方法众所周知为流形学习。主成分分析(PCA)、因子分析(FA)、线性判别分析(LDA)和截断奇异值分解(SVD)是线性降维方法的例子。核PCA、t分布随机邻居嵌入(t-SNE)、多维缩放(MDS)和等度量映射(Isomap)是非线性降维方法的例子。

让我们详细讨论每种方法。请注意,对于PCA和FA,我包括了链接到我以前的工作内容,最好描述这两种方法的理论和实现。对于所有其他方法,我将在本文中包含理论、Python代码和可视化。

线性方法

线性方法涉及将原始数据线性投影到低维空间中。我们将在线性方法下讨论PCA、FA、LDA和截断SVD。这些方法适用于线性数据,在非线性数据上表现不佳。

主成分分析(PCA)

PCA是我最喜欢的机器学习算法之一。PCA是一种线性降维技术(算法),它将一组相关变量(p)转换为较小的k(k<p)个不相关的变量,称为主成分,同时尽可能保留原始数据集中的变化。在机器学习(ML)的背景下,PCA是一种无监督的机器学习算法,用于降低维度。

由于这是我最喜欢的算法之一,我之前已经写过几篇关于PCA的内容。如果你想了解PCA背后的理论和其Scikit-learn实现,可以阅读我写的以下内容。

因子分析(FA)

因子分析(FA)主成分分析(PCA)都是降维技术。因子分析的主要目标不仅仅是降低数据的维度。因子分析是一种有用的方法,用于发现在单个变量中没有直接测量的潜在变量,而是从数据集中的其他变量推断出来的。这些潜在变量称为因子

如果你想了解FA背后的理论和其Scikit-learn实现,可以阅读我写的以下内容。

线性判别分析(LDA)

LDA通常用于多类分类。它也可以用作降维技术。LDA通过其类别最佳分离或判别(因此称为LDA)训练实例。LDA和PCA之间的主要区别在于LDA找到输入特征的线性组合,优化类别可分离性,而PCA试图找到数据集中方差最大的一组不相关组件。两者之间的另一个关键区别是PCA是无监督算法,而LDA是监督算法,它考虑了类别标签。

LDA有一些限制。要应用LDA,数据应服从正态分布。数据集还应包含已知的类别标签。LDA可以找到的最大分量数是类别数减1。如果数据集中只有3个类别标签,则LDA在降维中只能找到2个(3-1)分量。不需要执行特征缩放以应用LDA。另一方面,PCA需要缩放数据。但是,PCA不需要类别标签。PCA可以找到的最大分量数是原始数据集中的输入特征数。

降低维度的LDA不应与多类分类的LDA混淆。这两种情况都可以使用Scikit-learn **LinearDiscriminantAnalysis()函数实现。在使用fit(X,y)拟合模型之后,我们使用LDA对象的predict(X)方法进行多类分类。这将把新实例分配到原始数据集中的类别中。我们可以使用LDA对象的transform(X)**方法进行降维。这将找到一组新特征的线性组合,以优化类别可分离性。

以下Python代码描述了LDA和PCA技术在Iris数据集上的实现,并显示了两者之间的差异。原始的Iris数据集有四个特征。LDA和PCA将特征数量减少到两个,并启用2D可视化。

请稍等,正在加载Python代码!

(图片来自作者)

截断奇异值分解(SVD)本方法通过截断奇异值分解(SVD)来进行线性降维。它对于其中许多行值为零的稀疏数据表现良好。相比之下,PCA对于密集数据表现良好。截断SVD也可以与密集数据一起使用。截断SVD和PCA之间的另一个关键区别是,SVD的分解是在数据矩阵上完成的,而PCA的分解是在协方差矩阵上完成的。

Scikit-learn实现的截断SVD非常简单。可以使用**TruncatedSVD()**函数实现。以下Python代码描述了在Iris数据集上实现截断SVD和PCA技术。

等待加载Python代码!

(图片由作者提供)

非线性方法(流形学习)

如果我们处理的是现实世界中经常使用的非线性数据,则迄今为止讨论的线性方法在降维方面表现不佳。在本节中,我们将讨论可以用于非线性数据的四种非线性降维方法。

核PCA

核PCA是一种使用核函数的非线性降维技术。它也可以被认为是正常PCA的非线性形式。核PCA适用于正常PCA无法有效使用的非线性数据集。

核PCA背后的直觉很有趣。首先,将数据通过核函数运行,暂时将它们投影到一个新的高维特征空间中,在该空间中,类变得线性可分(可以通过画一条直线来划分类)。然后,算法使用正常PCA将数据投影回低维空间。通过这种方式,核PCA将非线性数据转换为可与线性分类器一起使用的数据的低维空间。

在核PCA中,我们需要指定3个重要的超参数——我们想要保留的成分数、核的类型和核系数(也称为_gamma_)。对于核的类型,我们可以使用“linear”、“poly”、“rbf”、“sigmoid”、“cosine”rbf核,也称为径向基函数核,是最流行的核之一。

现在,我们将使用Scikit-learn的**make_moons()**函数生成非线性数据,然后实现一个RBF核PCA。

等待加载Python代码!

非线性数据(图片由作者提供)

我们可以清楚地看到,上述非线性数据的两个类无法通过画一条直线来分开。

让我们对上述数据执行PCA和Kernel PCA,看看会发生什么!

等待加载Python代码!

(图片由作者提供)

如上图所示,正常的PCA无法将非线性数据转换为线性形式。将Kernel PCA应用于相同的数据后,两个类被线性地分离(现在,类可以通过画一条垂直的直线来划分)。

这里,原始数据的维度为2,绘制的数据也具有2个维度。那么,Kernel PCA实际上降低了数据的维度吗?答案是**“是”**,因为RBF核函数将2维数据暂时投影到一个新的高维特征空间中,在该空间中,类变得线性可分,然后算法将该高维数据投影回2维数据,可以在2D图中绘制。在类变得线性可分的同时,降维过程已在幕后进行。

使用Kernel PCA进行降维的一个限制是,我们必须在运行算法之前指定_gamma_超参数的值。它需要实现一个超参数调整技术,如网格搜索,以找到_gamma_的最佳值。这超出了本文的范围。但是,你可以通过阅读我的**“平实英语解释的k折交叉验证”**来获得有关超参数调整过程的帮助。

t分布随机邻居嵌入(t-SNE)

这也是一种非线性降维方法,主要用于数据可视化。除此之外,它在图像处理和NLP中广泛使用。如果数据集中的特征数大于50,则Scikit-learn文档建议在t-SNE之前使用PCA或截断SVD。以下是在PCA之后执行t-SNE的一般语法。还要注意,在PCA之前需要进行特征缩放。

from sklearn.decomposition import PCA
from sklearn.manifold import TSNE
from sklearn.preprocessing import StandardScalersc = StandardScaler()
X_scaled = sc.fit_transform(X)pca = PCA()
X_pca = pca.fit_transform(X_scaled)tsne = TSNE()
X_tsne = tsne.fit_transform(X_pca)

上面的代码可以使用Scikit-learn管道简化。

from sklearn.pipeline import Pipeline
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE
from sklearn.preprocessing import StandardScalersc = StandardScaler()
pca = PCA()
tsne = TSNE()tsne_after_pca = Pipeline([
    ('std_scaler', sc),
    ('pca', pca),
    ('tsne', tsne)
])X_tsne = tsne_after_pca.fit_transform(X)

现在,我们将t-SNE应用于Iris数据集。它只有4个特征。因此,在t-SNE之前我们不需要运行PCA。

等待加载Python代码!

(图片由作者提供)

多维缩放(MDS)

MDA是另一种非线性降维技术,它尝试在降低非线性数据的维度的同时保留实例之间的距离。有两种类型的MDS算法:度量和非度量。Scikit-learn中的MDS()类通过将metric超参数设置为True(度量类型)或False(非度量类型)来实现这两种类型。

以下代码将MDS实现到Iris数据集中。

等待加载Python代码!

## 等距映射(Isomap)

这种方法通过等距映射进行非线性降维。它是MDS或Kernel PCA的扩展。它通过计算到其最近邻的“曲线”或“测地线”距离来连接每个实例并减少维数。每个点要考虑的邻居数量可以通过Scikit-learn中实现等距映射算法的Isomap()类的n_neighbors超参数来指定。

以下代码将Isomap实现到Iris数据集中。

等待Python代码加载!

其他方法

在此类别下,我们将讨论3种方法。这些方法仅保留数据集中最重要的特征并删除冗余特征。因此,它们主要用于特征选择。但是,在选择最佳特征时自动发生降维!因此,它们也可以被视为降维方法。这些方法将提高模型的准确性得分或提高在非常高维数据集上的性能。

向后消除

该方法通过递归特征消除(RFE)过程从数据集中消除(删除)特征。该算法首先尝试在数据集中的初始特征集上训练模型并计算模型的性能(通常是分类模型的准确性得分和回归模型的RMSE)。然后,该算法每次删除一个特征(变量),在剩余特征上训练模型并计算性能分数。该算法重复消除特征,直到检测到模型性能的小(或没有)变化并在那里停止!

在Scikit-learn中,可以使用位于sklearn.feature_selection模块中的RFE()类来实现向后消除。该类的第一个参数应该是具有fit()方法和coef_或feature_importances_属性的有监督学习估计器。第二个参数应该是要选择的特征数。根据Scikit-learn文档,如果我们不指定要选择的特征数(n_features_to_select参数),则选择一半的特征。该方法的一个主要限制是我们不知道要选择的特征数。在这些情况下,最好通过指定不同的n_features_to_select值多次运行此算法。

现在,我们在Iris数据上训练逻辑回归模型并通过向后特征消除识别最重要的特征。

等待Python代码加载!

从输出中,我们可以看到递归特征消除(RFE)算法已从逻辑回归模型中消除了萼片长度(cm)。**萼片长度(cm)**是最不重要的特征。其余特征包含与初始数据集中相同的原始值。正如图表所示,最好在模型中保留其他3个特征。

向前选择

该方法可以被视为向后消除的相反过程。算法试图在数据集中的单个特征上训练模型并计算模型的性能(通常是分类模型的准确性得分和回归模型的RMSE)。然后,该算法每次添加(选择)一个特征(变量),在这些特征上训练模型并计算性能分数。该算法重复添加特征,直到检测到模型性能的小(或没有)变化并在那里停止!

在Scikit-learn中,没有直接的向前特征选择函数。相反,我们可以将f_regression(用于回归任务)和f_classif(用于分类任务)类与SelectKBest类一起使用。f_regression返回回归任务标签/特征之间的F值。f_classif返回分类任务标签/特征之间的ANOVA F值。这些F值可以在特征选择过程中使用。SelectKBest根据特征的F值基于最高分数自动选择特征。SelectKBest的score_func参数应该指定为f_classif或f_regression。k参数定义要选择的前k个特征。

让我们在Iris数据上执行向前特征选择并确定最重要的特征。

等待Python代码加载!

从输出中,我们可以看到向前特征选择过程已选择了具有更高F值的萼片长度(cm)花瓣长度(cm)花瓣宽度(cm)

为了基于截止F值定义k参数的值,我们可以使用以下两行代码。

F_values = f_classif(X,y)[0]
k = len([num for num in F_values if num > 50])

这将计算大于50的F值的数量并将其分配给k。这与上述实现完全相同。

随机森林

随机森林是一种基于树的模型,广泛用于非线性数据的回归和分类任务。它还可以通过其内置的feature_importances_属性用于特征选择,该属性基于“gini”标准(内部节点分割质量的度量)计算每个特征的特征重要性分数在训练模型时。如果你有兴趣了解随机森林如何进行预测,可以阅读我的“随机森林-决策树的集成”文章。

以下Python代码将Random Forest Classifier实现到Iris数据中,并计算并可视化特征重要性。

等待Python代码加载!

通过查看特征重要性,我们可以决定删除**萼片宽度(cm)**特征,因为它对于模型的贡献不足。让我们看看它如何!等待Python代码加载!

(图片由作者提供)

Scikit-learn的SelectFromModel仅选择其重要性大于或等于指定阈值的特征。SelectFromModel返回的值可以用作新的输入X,供随机森林分类器使用,该分类器现在仅对选定的特征进行训练!

rf = RandomForestClassifier(n_estimators=100, max_depth=3,
                            bootstrap=True, n_jobs=-1,
                            random_state=0)rf.fit(features_important, y)

译自:https://towardsdatascience.com/11-dimensionality-reduction-techniques-you-should-know-in-2021-dcb9500d388b

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
alivne
复杂的问题简单化

评论(0)

添加评论