业务范围 你的位置:欧陆注册 > 业务范围 > 数据降维的 7 种方法,附 Python 代码
数据降维的 7 种方法,附 Python 代码

发布日期:2024-10-14 13:11    点击次数:146


图片

大侠幸会,在下全网同名[算法金]

图片

0 基础转 AI 上岸,多个算法赛 Top[日更万日,让更多人享受智能乐趣]

数据降维是一种通过减少数据的维度来提取最重要信息的技术,其重要性在于简化数据集、加快模型训练速度、减少存储空间需求,并帮助发现数据中的潜在结构和模式,特别适用于高维数据下的计算复杂性和过拟合问题。介绍 7 种 降维方法

1. 线性降维方法:

1.1 主成分分析(PCA) 1.2 独立成分分析(ICA) 1.3 线性判别分析(LDA) 2. 非线性降维方法:

2.1 t-分布邻域嵌入(t-SNE) 2.2 自编码器(Autoencoder) 2.3 局部线性嵌入(LLE) 3. 保持距离关系的降维方法:

3.1多维缩放(MDS)

图片

1 线性降维方法1.1 主成分分析(PCA)是一种常用的线性降维技术,通过寻找数据中方差最大的方向,将原始高维数据映射到一个低维子空间中,以保留尽可能多的信息。

图片

下面我们使用 sklearn 里面的 PCA 工具,在一组人脸数据上直观感受下,# 导入必要的库import numpy as npimport matplotlib.pyplot as pltfrom sklearn.datasets import fetch_olivetti_facesfrom sklearn.decomposition import PCA# 加载Olivetti人脸数据集faces_data = fetch_olivetti_faces()X = faces_data.data# 可视化原始图像和对应的主成分n_images = 4 # 每行显示的图像数量n_rows = 4 # 总共的行数fig, axes = plt.subplots(n_rows, 2*n_images, figsize=(16, 10), subplot_kw={'xticks':[], 'yticks':[]})# 使用PCA降维n_components = 50 # 设置PCA保留的主成分数量pca = PCA(n_components=n_components, whiten=True, random_state=42)X_pca = pca.fit_transform(X)for r in range(n_rows): for i in range(n_images): index = r * n_images + i axes[r, 2*i].imshow(X[index].reshape(64, 64), cmap='gray') axes[r, 2*i].set_title(f'大侠 {index+1} 图像', fontproperties='SimHei') # 手动设置字体 axes[r, 2*i+1].imshow(pca.inverse_transform(X_pca[index]).reshape(64, 64), cmap='bone') axes[r, 2*i+1].set_title(f'大侠 {index+1} 主成分', fontproperties='SimHei') # 手动设置字体plt.tight_layout()plt.show()

我们保留了前 50 个主成分

通过可视化对比图直观感受下,信息保留了多多少,损失了多少

通过对比图可以看到,某一张人脸的基本信息都保留了下来

如果保留 前 100 个主成分,那就更接近原始图片了

你也可以试下,保留 1 个主成分会怎样?通过保留的信息你还认得出来哪过大侠是哪过吗

图片

图片

更多 PCA 相关内容,见往期文章 PCA 主成分分析这你看不懂,我吃!1.2 独立成分分析(ICA)独立成分分析(ICA)是一种用于将混合信号分解为独立源信号的技术,其工作原理是通过找到最大独立性来估计源信号特点是可以有效地分离混合信号中的独立成分,例如音频信号中的不同讲话者经典示例是图像降噪、时间序列数据中的伪影消除或金融数据中驱动组件的识别这儿有个有趣的示例:https://github.com/akcarsten/Independent_Component_Analysis1.3 线性判别分析(LDA)通过最大化类间距离和最小化类内距离,将数据投影到低维空间中,以实现数据的分类和可视化,适用于数据分类、特征提取和可视化分析等场景。异同:LDA是一种监督学习方法,需要有数据样本的标签;PCA是一种无监督学习方法,没有标签下也能使用
import numpy as npimport matplotlib.pyplot as pltfrom sklearn.datasets import make_classification# 设置matplotlib支持中文显示plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文显示plt.rcParams['axes.unicode_minus'] = False # 正确显示负号# 生成虚拟武侠人物数据集np.random.seed(42)X, y = make_classification(n_samples=1000, n_features=4, n_informative=3, n_redundant=1, n_classes=3, n_clusters_per_class=2, random_state=42)# 根据类别重新命名y_names = {0: '正派', 1: '中立', 2: '反派'}y_labels = np.vectorize(lambda x: y_names[x])(y)# 创建 LDA 模型并拟合数据lda = LinearDiscriminantAnalysis(n_components=2)X_r = lda.fit(X, y).transform(X)# 绘制降维后的数据plt.figure(figsize=(8, 6))colors = ['navy', 'turquoise', 'darkorange']lw = 2for color, i, target_name in zip(colors, [0, 1, 2], ['正派', '中立', '反派']):    plt.scatter(X_r[y == i, 0], X_r[y == i, 1], color=color, alpha=.8, lw=lw, label=target_name)plt.legend(loc='best', shadow=False, scatterpoints=1)plt.title('LDA of Martial Arts Heroes dataset')plt.xlabel('LD1')plt.ylabel('LD2')plt.show()

图片

这个可视化结果展示了经过线性判别分析(LDA)降维后的数据在二维空间中的分布情况。每个点代表一个虚拟武侠人物数据样本,其位置由 LDA 转换后的两个新特征(LD1 和 LD2)决定。更多内容,见免费知识星球

图片

2. 非线性降维方法

2.1 t-分布邻域嵌入(t-SNE)

t-分布邻域嵌入(t-SNE)是一种非线性降维技术,旨在将高维数据映射到二维或三维空间,保持数据点之间的局部结构,适用于可视化高维数据和发现数据中的潜在结构。

t-SNE 的工作原理是通过测量数据点之间的相似度,然后在低维空间中尽可能地保持相似度,特点是能够有效地保留数据点之间的局部结构和聚类信息,但不保持全局结构。

import numpy as npimport matplotlib.pyplot as pltfrom sklearn.datasets import load_irisfrom sklearn.manifold import TSNE# 加载鸢尾花数据集iris = load_iris()X = iris.datay = iris.target# 使用 t-SNE 进行降维tsne = TSNE(n_components=2, random_state=42)X_tsne = tsne.fit_transform(X)# 绘制降维后的数据plt.figure(figsize=(8, 6))colors = ['navy', 'turquoise', 'darkorange']lw = 2for color, i, target_name in zip(colors, [0, 1, 2], iris.target_names): plt.scatter(X_tsne[y == i, 0], X_tsne[y == i, 1], color=color, alpha=.8, lw=lw, label=target_name)plt.legend(loc='best', shadow=False, scatterpoints=1)plt.title('t-SNE of IRIS dataset')plt.xlabel('t-SNE Component 1')plt.ylabel('t-SNE Component 2')plt.show()

图片

2.2 自编码器(Autoencoder)

一种无监督学习的技术,旨在通过学习数据的压缩表示,将高维数据映射到低维空间,适用于特征提取和数据重建。

工作原理:通过神经网络将输入数据压缩到一个低维编码,然后再解码回原始维度,使得重构误差最小化,特点是能够学习数据中的有效特征表达,适用于无监督特征学习、降噪和图像去噪等场景。

import numpy as npimport matplotlib.pyplot as pltfrom keras.datasets import mnistfrom keras.models import Modelfrom keras.layers import Input, Dense# 加载 MNIST 数据集(X_train, _), (X_test, _) = mnist.load_data()# 数据预处理X_train = X_train.astype('float32') / 255.X_test = X_test.astype('float32') / 255.X_train = X_train.reshape((len(X_train), np.prod(X_train.shape[1:])))X_test = X_test.reshape((len(X_test), np.prod(X_test.shape[1:])))# 构建自编码器模型input_img = Input(shape=(784,))encoded = Dense(32, activation='relu')(input_img)  # 编码层,将输入压缩到32维decoded = Dense(784, activation='sigmoid')(encoded)  # 解码层,将编码结果解压缩到784维autoencoder = Model(input_img, decoded)autoencoder.compile(optimizer='adam', loss='binary_crossentropy')# 训练自编码器模型autoencoder.fit(X_train, X_train, epochs=50, batch_size=256, shuffle=True, validation_data=(X_test, X_test))# 使用训练好的自编码器模型进行数据降维encoder = Model(input_img, encoded)encoded_imgs = encoder.predict(X_test)# 可视化降维后的结果n = 10  # 可视化的数字数量plt.figure(figsize=(20, 4))for i in range(n):    ax = plt.subplot(2, n, i + 1)    plt.imshow(X_test[i].reshape(28, 28))    plt.gray()    ax.get_xaxis().set_visible(False)    ax.get_yaxis().set_visible(False)    ax = plt.subplot(2, n, i + 1 + n)    plt.imshow(encoded_imgs[i].reshape(8, 4))  # 将32维的编码结果reshape为8x4的图像    plt.gray()    ax.get_xaxis().set_visible(False)    ax.get_yaxis().set_visible(False)plt.show()

2.3 局部线性嵌入(LLE)

一种非线性降维方法,通过保持局部数据之间的线性关系,在保留数据结构的同时将高维数据映射到低维空间,适用于保持局部结构的降维需求。

工作原理:在局部邻域内利用线性关系重建数据,通过最小化重建误差来学习数据的低维表示,特点是能够保持数据之间的局部结构和流形形状,适用于高维数据的可视化、图像处理和模式识别等场景。

import numpy as npimport matplotlib.pyplot as pltfrom sklearn.datasets import make_swiss_rollfrom sklearn.manifold import LocallyLinearEmbedding# 设置matplotlib支持中文显示plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文显示plt.rcParams['axes.unicode_minus'] = False # 正确显示负号# 生成Swiss Roll数据集X, _ = make_swiss_roll(n_samples=1000, noise=0.2, random_state=42)# 使用局部线性嵌入进行降维lle = LocallyLinearEmbedding(n_components=2, n_neighbors=10, random_state=42)X_lle = lle.fit_transform(X)# 绘制降维后的数据plt.figure(figsize=(8, 6))plt.scatter(X_lle[:, 0], X_lle[:, 1], c=X[:, 1], cmap='viridis')plt.colorbar(label='Swiss Roll中的高度')plt.title('局部线性嵌入(LLE)降维')plt.xlabel('新特征1')plt.ylabel('新特征2')plt.show()

图片

图片

3. 保持距离关系的降维方法

3.1多维缩放(MDS)

一种用于将高维数据映射到低维空间的技术,以保持数据点之间的距离关系为目标,适用于可视化高维数据和发现数据之间的相似性。

工作原理:通过优化数据点之间的距离或相似度矩阵,将高维数据点映射到低维空间,特点是能够保持数据点之间的全局距离关系。

import numpy as npimport matplotlib.pyplot as pltfrom sklearn.datasets import load_irisfrom sklearn.manifold import MDS# 加载鸢尾花数据集iris = load_iris()X = iris.datay = iris.target# 使用多维缩放进行降维mds = MDS(n_components=2, random_state=42)X_mds = mds.fit_transform(X)# 绘制降维后的数据plt.figure(figsize=(8, 6))plt.scatter(X_mds[:, 0], X_mds[:, 1], c=y, cmap='viridis')plt.colorbar(label='鸢尾花类别')plt.title('多维缩放(MDS)降维')plt.xlabel('新特征1')plt.ylabel('新特征2')plt.show()

图片

免费知识星球,欢迎加入交流[ 抱个拳,总个结 ]

选择合适的数据降维方法取决于多个因素,包括数据类型、降维目标、计算资源和算法特点等。以下是一些考虑因素:

数据类型:首先要考虑数据的类型,包括数据的维度、结构和特征类型。例如,对于结构化数据(如表格数据),主成分分析(PCA)通常是一个不错的选择;对于非线性数据或流形结构数据(如图像、文本、时间序列等),t-分布邻域嵌入(t-SNE)和局部线性嵌入(LLE)可能更适合。

降维目标:确定降维的目标是重要的。有时候我们仅仅是为了可视化数据,而有时我们需要保留尽可能多的信息以便后续的机器学习任务。如果目标是可视化数据,则应选择能够有效保留数据结构和相似性的方法,如t-SNE;如果目标是尽可能保留数据的信息,则PCA可能更合适。

计算资源:一些降维方法在处理大规模数据时可能需要大量的计算资源和时间。例如,t-SNE 的计算复杂度较高,对于大规模数据集可能不太适用。在这种情况下,可以考虑使用PCA或增量式的降维方法来处理大规模数据。

算法特点:不同的降维方法有不同的算法特点和假设条件。例如,PCA 假设数据是线性可分的,适用于线性相关的数据;t-SNE 假设数据在高维空间中呈现流形结构,适用于非线性数据。因此,要根据数据的特点选择合适的降维方法。

[ 算法金,碎碎念 ]

图片

带小朋友去商场玩,中午在初满吃饭点了一份拉面,面还挺好吃其中有有一个蛋,我用筷子一夹心里暗叫一声:不好这个蛋怎么这么软姐姐看出了我的心思,问:你是不是想这个蛋没弄好,咋这么软我忙点头称是,她哈哈笑了起来,说:这叫溏心蛋,是他们家的特色害,我那个尴尬啊。没见识,真可怕希望今天的日更能给大家涨些见识,hhh全网同名,日更万日,让更多人享受智能乐趣,今日 116/10000 本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报。

Powered by 欧陆注册 @2013-2022 RSS地图 HTML地图