九种降维方法汇总

一、 为什么降维?

1、随着数据维度不断降低,数据存储所需的空间也会随之减少。
2、低维数据有助于减少计算/训练用时。
3、一些算法在高维度数据上容易表现不佳,降维可提高算法可用性。
4、降维可以用删除冗余特征解决多重共线性问题。比如我们有两个变量:“一段时间内在跑步机上的耗时”和“卡路里消耗量”。这两个变量高度相关,在跑步机上花的时间越长,燃烧的卡路里自然就越多。因此,同时存储这两个数据意义不大,只需一个就够了。
5、降维有助于数据可视化。如果数据维度很高,可视化会变得相当困难,而绘制二维三维数据的图表非常简单。

二、降维方法。

数据维度的降低方法主要有两种:
1、仅保留原始数据集中最相关的变量(特征选择)。
2、寻找一组较小的新变量,其中每个变量都是输入变量的组合,包含与输入变量基本相同的信息(降维)。

2.1 缺失值比率

假设你有一个数据集,你第一步会做什么?在构建模型前,对数据进行探索性分析必不可少。但在浏览数据的过程中,有时候我们会发现其中包含不少缺失值。如果缺失值少,我们可以填补缺失值或直接删除这个变量;当缺失值在数据集中的占比过高时,一般我会选择直接删除这个变量,因为它包含的信息太少了。但具体删不删、怎么删需要视情况而定,我们可以设置一个阈值,如果缺失值占比高于阈值,删除它所在的列。阈值越高,降维方法越积极。

df.isnull().sum()  #检查每个变量中缺失值的占比
df.isnull().sum() /len(df)*100
# 设定阈值为20%:保存变量中的缺失值
a = df.isnull().sum()/len(df)*100
# 保存列名
variables = df.columns
variable = [ ]
for i in range(0,12):
    if a[i]<=20:   #setting the threshold as 20%
        variable.append(variables[i])

2.2 低方差滤波

如果我们有一个数据集,其中某列的数值基本一致,也就是它的方差非常低,我们通常认为低方差变量携带的信息量也很少,所以可以把它直接删除。放到实践中,就是先计算所有变量的方差大小,然后删去其中最小的几个。需要注意的一点是:方差与数据范围相关的,因此在采用该方法前需要对数据做归一化处理。
实例中,我们先估算缺失值,缺失值填充完毕,进行低方差滤波分析。

# 列出了方差大于10的所有变量
umeric = train[['Item_Weight', 'Item_Visibility', 'Item_MRP', 'Outlet_Establishment_Year']]
var = numeric.var()
numeric = numeric.columns
variable = [ ]
for i in range(0,len(var)):
    if var[i]>=10:   # 将阈值设置为10%
       variable.append(numeric[i+1])

2.3 高相关滤波

如果两个变量之间是高度相关的,这意味着它们具有相似的趋势并且可能携带类似的信息。同理,这类变量的存在会降低某些模型的性能(例如线性和逻辑回归模型)。为了解决这个问题,我们可以计算独立数值变量之间的相关性。如果相关系数超过某个阈值,就删除其中一个变量。
首先,删除因变量,并将剩余的变量保存在新的数据列中进行相关性分析(df.corr())。通常情况下,如果一对变量之间的相关性大于0.5-0.6,那就应该考虑是否要删除一列了。

2.4 随机森林

随机森林是一种广泛使用的特征选择算法,它会自动计算各个特征的重要性,所以无需单独编程。这有助于我们选择较小的特征子集。在开始降维前,我们先把数据转换成数字格式,因为随机森林只接受数字输入

from sklearn.ensemble import RandomForestRegressor
df=df.drop(['Item_Identifier', 'Outlet_Identifier'], axis=1)
model = RandomForestRegressor(random_state=1, max_depth=10)
df=pd.get_dummies(df)
model.fit(df,train.Item_Outlet_Sales)

拟合模型后,根据特征的重要性绘制成图:

features = df.columns
importances = model.feature_importances_
indices = np.argsort(importances[0:9])  # top 10 features
plt.title('Feature Importances')
plt.barh(range(len(indices)), importances[indices], color='b', align='center')
plt.yticks(range(len(indices)), [features[i] for i in indices])
plt.xlabel('Relative Importance')
plt.show()

在这里插入图片描述
基于上图,我们可以手动选择最顶层的特征来减少数据集中的维度。
:如果你用的是sklearn,可以直接使用SelectFromModel,它根据权重的重要性选择特征。

from sklearn.feature_selection import SelectFromModel
feature = SelectFromModel(model)
Fit = feature.fit_transform(df, train.Item_Outlet_Sales)

2.5 反向特征消除

1、先获取数据集中的全部n个变量,然后用它们训练一个模型。
2、计算模型的性能。
3、在删除每个变量(n次)后计算模型的性能,即我们每次都去掉一个变量,用剩余的n-1个变量训练模型。
4、确定对模型性能影响最小的变量,把它删除。
5、重复此过程,直到不再能删除任何变量。
在构建线性回归或逻辑回归时候可以使用这种方法:

from sklearn.linear_model import LinearRegression
from sklearn.feature_selection import RFE
from sklearn import datasets
lreg = LinearRegression()
rfe = RFE(lreg, 10)
rfe = rfe.fit_transform(df, train.Item_Outlet_Sales)

我们需要指定算法和要选择的特征数量,然后返回反向特征消除输出的变量列表。此外,rfe.ranking_可以用来检查变量排名。

2.6 前向特征选择

前向特征选择其实就是反向特征消除的相反过程,即找到能改善模型性能的最佳特征,而不是删除弱影响特征。它背后的思路如下所述:
1、选择一个特征,用每个特征训练模型n次,得到n个模型。
2、选择模型性能最佳的变量作为初始变量。
3、每次添加一个变量继续训练,重复上一过程,最后保留性能提升最大的变量。
4、一直添加,一直筛选,直到模型性能不再有明显提高。

from sklearn.feature_selection import f_regression
ffs = f_regression(df,train.Item_Outlet_Sales )

上述会返回一个数组,其中包括变量F值和每个F对应的p值。在这里,我们选择F值大于10的变量:

variable = [ ]
for i in range(0,len(df.columns)-1):
    if ffs[0][i] >=10:
       variable.append(df.columns[i])

2.7 因子分析

因子分析是一种常见的统计方法,它能从多个变量中提取共性因子,并得到最优解。
基本思想:最大化类间均值,最小化类内方差。意思就是将数据投影在低维度上,并且投影后同种类别数据的投影点尽可能的接近,不同类别数据的投影点的中心点尽可能的远。假设我们有两个变量:收入和教育。它们可能是高度相关的,因为总体来看,学历高的人一般收入也更高,反之亦然。所以它们可能存在一个潜在的共性因子,比如“能力”。
在因子分析中,我们将变量按其相关性分组,即特定组内所有变量的相关性较高,组间变量的相关性较低。我们把每个组称为一个因子,它是多个变量的组合。和原始数据集的变量相比,这些因子在数量上更少,但携带的信息基本一致。
数据集:Fashion MNIST,它共有70,000张图像,其中训练集60,000张,测试集10,000张。我们的目标是训练一个能分类各类服装配饰的模型。

import pandas as pd
import numpy as np
from glob import glob
import cv2
images = [cv2.imread(file) for file in glob('train/*.png')]

:必须使用train文件夹的路径替换glob函数内的路径。
把这些图像转换为numpy数组格式,以便执行数学运算并绘制图像。

images = np.array(images)
images.shape   #(60000, 28, 28, 3)
--这是一个三维数组,但我们的目标是把它转成一维,因为后续只接受一维输入。所以我们还得展平图像:
image = []
for i in range(0,60000):
    img = images[i].flatten()
    image.append(img)
image = np.array(image)

创建一个数据框,其中包含每个像素的像素值,以及它们对应的标签:

train = pd.read_csv("train.csv")     # Give the complete path of your train.csv file
feat_cols = [ 'pixel'+str(i) for i in range(image.shape[1]) ]
df = pd.DataFrame(image,columns=feat_cols)
df['label'] = train['label']

用因子分析分解数据集:

from sklearn.decomposition import FactorAnalysis
FA = FactorAnalysis(n_components = 3).fit_transform(df[feat_cols].values)

这里,n_components 将决定转换数据中的因子数量。转换完成后,可视化结果:

%matplotlib inline
import matplotlib.pyplot as plt
plt.figure(figsize=(12,8))
plt.title('Factor Analysis Components')
plt.scatter(FA[:,0], FA[:,1])
plt.scatter(FA[:,1], FA[:,2])
plt.scatter(FA[:,2],FA[:,0])

在这里插入图片描述
x轴和y轴表示分解因子的值,虽然共性因子是潜在的,很难被观察到,但我们已经成功降维。

2.7.1 因子分析的优缺点:

优点:
1、在降维过程中可以使用类别的先验知识经验,而像PCA这样的无监督学习则无法使用类别先验知识。
2、LDA在样本分类信息依赖均值而不是方差的时候,比PCA之类的算法较优。
缺点:
1、LDA不适合对非高斯分布样本进行降维
2、LDA降维最多降到k-1(k为类别数)的维数,如果我们降维的维度大于k-1,则不能使用LDA。
3、LDA在样本分类信息依赖方差而不是均值的时候,降维效果不好。
4、LDA可能过度拟合数据

2.8 主成分分析(PCA)

基本思想:利用降维思维,将原来具有一定相关性的指标,通过正交变换,重新组合成一组新的相互无关的综合指标,即从原始变量中导出少数几个主成分,使它们尽可能多地保留原始变量的信息,且彼此间互不相关。无关变量称为主成分。

2.8.1 PCA的特点:

1、主成分是原始变量的线性组合。
2、第一个主成分具有最大的方差值。
3、第二主成分试图解释数据集中的剩余方差,并且与第一主成分不相关(正交)。
4、第三主成分试图解释前两个主成分等没有解释的方差。

2.8.2 PCA计算步骤:

1.将数据标准化
2.求出协方差矩阵
3.求出协方差矩阵对应的特征值和特征向量
4.将特征向量按对应特征值大小从上到下按行排列,取k行组成矩阵p
5.Y=PX即为降维到k维后的数据

贡献率:总方差中第i个主成分占总p个主成分的比例
载荷:
在这里插入图片描述
实现PCA:

from sklearn.decomposition import PCA
pca = PCA(n_components=4)
pca_result = pca.fit_transform(df[feat_cols].values)

"""查看PCA的一些属性"""
print(pca_result.shape)   # (200000, 10)
print(pca.explained_variance_)    # 属性可以查看降维后的每个特征向量上所带的信息量大小(可解释性方差的大小)
print(pca.explained_variance_ratio_)  # 查看降维后的每个新特征的信息量占原始数据总信息量的百分比
print(pca.explained_variance_ratio_.sum())    # 降维后信息保留量

其中n_components 将决定转换数据中的主成分。接下来,我们看一下这四个主成分解释了多少方差:

plt.plot(range(4), pca.explained_variance_ratio_)
plt.plot(range(4), np.cumsum(pca.explained_variance_ratio_))
plt.title("Component-wise and Cumulative Explained Variance")

在这里插入图片描述
在上图中,蓝线表示分量解释的方差,而橙线表示累积解释的方差。我们只用四个成分就解释了数据集中约60%的方差。

2.8.3 PCA优缺点:

优点:
1、仅仅需要以方差衡量信息量,不受数据集以外的因素影响。 
2、各主成分之间正交,可消除原始数据成分间的相互影响的因素。
3、计算方法简单,主要运算是特征值分解,易于实现。
缺点:
1、主成分各个特征维度的含义具有一定的模糊性,不如原始样本特征的解释性强。
2、方差小的非主成分也可能含有对样本差异的重要信息,因降维丢弃可能对后续数据处理有影响

2.8.4 PCA与LDA的联系与区别:

联系

  两者其本质是要将初始样本映射到维度更低的样本空间中,都有降维和信息浓缩的方法,生成的新变量均代表了原始变量的大部分信息且相互独立。

区别

  (1)PCA是按照方差最大化的方法生成新变量,为了让映射后的样本具有最大的发散性,强调新变量贡献了多大比例的方差,不关心新变量是否具有明确的实际意义。PCA是一种无监督的降维方法。
  (2)LDA着重要求新变量具有实际意义,能解释原始变量间内在结构,LDA不是对原始变量的重新组合,而是为了让映射后的样本有最好的分类性能,对原始变量进行分解,分解为公共因子和特殊因子。LDA是一种有监督的降维方法。

2.9 正则化

正则化减少了过拟合。如果你有太多的特征,正则化控制它们的效果,或者通过缩小特征系数(称为 L2 正则化)或将一些特征系数设置为零(称为 L1 正则化)。
一些模型具有内置的 L1/L2 正则化作为超参数来惩罚特征。可以使用转换器 SelectFromModel 消除这些功能。
让我们实现一个带有惩罚 = ‘l1’ 的 LinearSVC 算法。然后使用 SelectFromModel 删除一些功能。

# implement algorithm
from sklearn.svm import LinearSVC
model = LinearSVC(penalty= 'l1', C = 0.002, dual=False)
model.fit(X,y)
# select features using the meta transformer
selector = SelectFromModel(estimator = model, prefit=True)
X_new = selector.transform(X)
X_new.shape[1]
#输出 2
# names of selected features
feature_names = np.array(X.columns)
feature_names[selector.get_support()]
#输出 array(['wheel-base', 'horsepower'], dtype=object)

三、降维方法使用场景。

缺失值比率:如果数据集的缺失值太多,我们可以用这种方法减少变量数。
低方差滤波:这个方法可以从数据集中识别和删除常量变量,方差小的变量对目标变量影响不大,所以可以放心删去。
高相关滤波:具有高相关性的一对变量会增加数据集中的多重共线性,所以用这种方法删去其中一个是有必要的。
随机森林:这是最常用的降维方法之一,它会明确算出数据集中每个特征的重要性。
前向特征选择和反向特征消除:这两种方法耗时较久,计算成本也都很高,所以只适用于输入变量较少的数据集。
因子分析:这种方法适合数据集中存在高度相关的变量集的情况。
PCA:这是处理线性数据最广泛使用的技术之一。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
降维方法是一种重要的数据处理技术,可以帮助我们在处理高维数据时更好地理解和分析数据。在机器学习和数据挖掘领域,降维方法被广泛应用于特征选择和数据可视化等方面。以下是12种降维方法的终极指南,包括Python代码示例。 1. 主成分分析(PCA):通过线性变换将原始特征空间映射到低维空间,保持数据方差信息的同时实现降维。 2. 线性判别分析(LDA):一种监督学习的降维方法,通过最大化类间距离和最小化类内散布矩阵来找到最佳投影方向。 3. t-分布邻域嵌入(t-SNE):一种非线性降维方法,能够保持高维数据样本之间的局部距离关系。 4. 等距映射(Isomap):基于流形学习的降维方法,能够保持高维数据样本之间的地理距离关系。 5. 局部线性嵌入(LLE):一种非线性降维方法,通过局部线性逼近来保持高维数据样本之间的局部结构。 6. 康明映射(tangent space mapping):一种基于流形学习的降维方法,通过投影到切空间来实现降维。 7. 自编码器(Autoencoder):一种无监督学习的降维方法,通过编码和解码过程来学习数据的低维表示。 8. 随机投影(Random Projection):一种快速的降维方法,通过随机投影矩阵将原始数据映射到低维空间。 9. 核主成分分析(Kernel PCA):一种非线性降维方法,通过核技巧将数据映射到高维特征空间后再进行PCA。 10. 字典学习(Dictionary Learning):一种稀疏表示学习的降维方法,通过学习字典来实现数据的压缩表示。 11. 高维分析(High-Dimensional Analysis):一种基于高维几何特征学习的降维方法,通过学习高维特征的结构来实现降维。 12. 非负矩阵分解(NMF):一种基于非负矩阵分解的降维方法,常用于图像和文本数据的降维处理。 以上是12种降维方法的终极指南,每一种方法都有其适用的场景和特点,根据实际情况选择合适的降维方法可以更好地处理高维数据。下面是Python代码示例: ```python # 使用sklearn库进行PCA降维 from sklearn.decomposition import PCA pca = PCA(n_components=2) X_pca = pca.fit_transform(X) # 使用sklearn库进行t-SNE降维 from sklearn.manifold import TSNE tsne = TSNE(n_components=2) X_tsne = tsne.fit_transform(X) # 使用sklearn库进行Isomap降维 from sklearn.manifold import Isomap isomap = Isomap(n_components=2) X_isomap = isomap.fit_transform(X) # 使用sklearn库进行LLE降维 from sklearn.manifold import LocallyLinearEmbedding lle = LocallyLinearEmbedding(n_components=2) X_lle = lle.fit_transform(X) # 使用keras库进行自编码器降维 from keras.layers import Input, Dense from keras.models import Model input_dim = X.shape[1] input_layer = Input(shape=(input_dim,)) encoded = Dense(2, activation='relu')(input_layer) decoded = Dense(input_dim, activation='sigmoid')(encoded) autoencoder = Model(input_layer, decoded) encoder = Model(input_layer, encoded) X_autoencoder = encoder.predict(X) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值