Scikit-learn学习系列 | 5. sklearn特征降维可视化展示(t-SNE、PCA、KernelPCA、MDS、SpectralEmbedding)

本文通过使用t-SNE、PCA、KernelPCA和MDS等降维算法,对手写数字数据集进行2D和3D可视化展示。t-SNE在降维效果上表现出色,能清晰地呈现数据分布。PCA和KernelPCA作为线性方法,可能丢失非线性结构信息,而MDS和SpectralEmbedding则在保留非线性结构方面有一定优势。降维选择应考虑时间成本和效果平衡,并注意数据预处理和目的明确。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


如有错误,恳请指出。


以下内容将使用一个非常经典的手写数字数据集来进行降维与可视化展示。在原始的数据中,手写数字的维度是64,因为其像素表示是64,以下内容将分别使用不同的算法对其降维到2~3维并展示。所以分别可以实现2D可视化展示降维效果与3D可视化降维效果。


首先导入必要的工具包:

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

1. t-SNE降维效果

1.1 2D可视化

from sklearn import datasets
from sklearn import preprocessing
from sklearn.manifold import TSNE

# 数据集导入
X, y = datasets.load_digits(return_X_y=True)

# t-SNE降维处理
tsne = TSNE(n_components=2, verbose=1 ,random_state=42)
result = tsne.fit_transform(X)

# 归一化处理
scaler = preprocessing.MinMaxScaler(feature_range=(-1,1))
result = scaler.fit_transform(result)

# 颜色设置
color = ['#FFFAFA', '#BEBEBE', '#000080', '#87CEEB', '#006400',
         '#00FF00', '#4682B4', '#D02090', '#8B7765', '#B03060']

# 可视化展示
plt.figure(figsize=(10, 10))
plt.title('t-SNE process')
# plt.xlim((-1.1, 1.1))
# plt.ylim((-1.1, 1.1))
# for i in range(len(result)):
#     plt.text(result[i,0], result[i,1], str(y[i]), 
#              color=color[y[i]], fontdict={'weight': 'bold', 'size': 9})
plt.scatter(result[:,0], result[:,1], c=y, s=10)

输出:

[t-SNE] Computing 91 nearest neighbors...
[t-SNE] Indexed 1797 samples in 0.000s...
[t-SNE] Computed neighbors for 1797 samples in 0.116s...
[t-SNE] Computed conditional probabilities for sample 1000 / 1797
[t-SNE] Computed conditional probabilities for sample 1797 / 1797
[t-SNE] Mean sigma: 11.585657
[t-SNE] KL divergence after 250 iterations with early exaggeration: 61.555897
[t-SNE] KL divergence after 1000 iterations: 0.743767

在这里插入图片描述

1.2 3D可视化

from sklearn.manifold import TSNE
from sklearn import preprocessing
from sklearn import datasets

# 导入数据
X, y = datasets.load_digits(return_X_y=True)
# t-SNE降维处理
tsne = TSNE(n_components=3, verbose=1 ,random_state=42)
result = tsne.fit_transform(X)
# 归一化处理
scaler = preprocessing.MinMaxScaler(feature_range=(-1,1))
result = scaler.fit_transform(result)
# 3D可视化展示
fig = plt.figure(figsize=(14, 14))
ax = fig.add_subplot(projection='3d')
ax.set_title('t-SNE process')
ax.scatter(result[:,0], result[:,1], result[:,2] , c=y, s=10)

输出:

[t-SNE] Computing 91 nearest neighbors...
[t-SNE] Indexed 1797 samples in 0.000s...
[t-SNE] Computed neighbors for 1797 samples in 0.119s...
[t-SNE] Computed conditional probabilities for sample 1000 / 1797
[t-SNE] Computed conditional probabilities for sample 1797 / 1797
[t-SNE] Mean sigma: 11.585657
[t-SNE] KL divergence after 250 iterations with early exaggeration: 61.700397
[t-SNE] KL divergence after 1000 iterations: 0.615485

在这里插入图片描述

可以看见,t-SNE无论是将数据降维到2维或者是3维,其可视化的效果都是比较好的,可以明显的看出来数据之间的分布是有一定距离的。


2. PCA降维效果

2.1 2D可视化

from sklearn.decomposition import PCA
from sklearn.preprocessing import MinMaxScaler
from sklearn import datasets

# 颜色设置
color = ['#FFFAFA', '#BEBEBE', '#000080', '#87CEEB', '#006400',
         '#00FF00', '#4682B4', '#D02090', '#8B7765', '#B03060']

# 导入数据
X, y = datasets.load_digits(return_X_y=True)
# PCA降维(一种矩阵分解的方法)
pca = PCA(n_components=2, random_state=42)
result = pca.fit_transform(X)
# 归一化处理
scaler = MinMaxScaler(feature_range=(-1., 1.), copy=True)
result = scaler.fit_transform(result)
# 可视化展示
plt.figure(figsize=(10, 10))
plt.xlim((-1.1, 1.1))
plt.ylim((-1.1, 1.1))
plt.title('PCA process')
for i in range(len(result)):
    plt.text(result[i,0], result[i,1], str(y[i]), 
             color=color[y[i]], fontdict={'weight': 'bold', 'size': 9})

在这里插入图片描述

2.2 3D可视化

from sklearn.decomposition import PCA
from sklearn.preprocessing import MinMaxScaler
from sklearn import datasets

# 颜色设置
color = ['#FFFAFA', '#BEBEBE', '#000080', '#87CEEB', '#006400',
         '#00FF00', '#4682B4', '#D02090', '#8B7765', '#B03060']

# 导入数据
X, y = datasets.load_digits(return_X_y=True)
# PCA降维(一种矩阵分解的方法)
pca = PCA(n_components=3, random_state=42)
result = pca.fit_transform(X)
# 归一化处理
scaler = MinMaxScaler(feature_range=(-2., 2.), copy=True)
result = scaler.fit_transform(result)
# 可视化展示
fig = plt.figure(figsize=(14, 14))
ax = fig.add_subplot(111, projection='3d')
# 标题,范围,标签设置
ax.set_title('PCA process')
ax.set_xlim((-2.1, 2.1))
ax.set_ylim((-2.1, 2.1))
ax.set_zlim((-2.1, 2.1))
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
# 绘制散点图(直接在对应位置上画出标签值)
for i in range(len(result)):
    ax.text(result[i, 0], result[i, 1], result[i, 2], str(y[i]), 
             color=color[y[i]], fontdict={'weight': 'bold', 'size': 9})

在这里插入图片描述


3. KernelPCA降维效果

3.1 2D可视化

from sklearn.decomposition import KernelPCA
from sklearn.preprocessing import MinMaxScaler

# 导入数据
X, y = datasets.load_digits(return_X_y=True)
# PCA降维(一种矩阵分解的方法)
pca = KernelPCA(n_components=2, random_state=42)
result = pca.fit_transform(X)
# 归一化处理
scaler = MinMaxScaler(feature_range=(-1, 1), copy=True)
result = scaler.fit_transform(result)
# 可视化展示
plt.figure(figsize=(10, 10))
plt.title('KernelPCA process')
plt.scatter(result[:,0], result[:,1], c=y, s=10)

在这里插入图片描述

3.2 3D可视化

from sklearn.decomposition import KernelPCA
from sklearn.preprocessing import MinMaxScaler
from sklearn import datasets

# 颜色设置
color = ['#000000', '#BEBEBE', '#000080', '#87CEEB', '#006400',
         '#00FF00', '#4682B4', '#D02090', '#8B7765', '#104E8B']

# 导入数据
X, y = datasets.load_digits(return_X_y=True)
# PCA降维(一种矩阵分解的方法)
kernel_pca = KernelPCA(n_components=3, random_state=42)
result = kernel_pca.fit_transform(X)
# 归一化处理
scaler = MinMaxScaler(feature_range=(-2., 2.), copy=True)
result = scaler.fit_transform(result)
# 可视化展示
fig = plt.figure(figsize=(14, 14))
ax = fig.add_subplot(111, projection='3d')
# 标题,范围,标签设置
ax.set_title('KernelPCA process')
ax.set_xlim((-2.1, 2.1))
ax.set_ylim((-2.1, 2.1))
ax.set_zlim((-2.1, 2.1))
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
# 绘制散点图(直接在对应位置上画出标签值)
for i in range(len(result)):
    ax.text(result[i, 0], result[i, 1], result[i, 2], str(y[i]), 
             color=color[y[i]], fontdict={'weight': 'bold', 'size': 9})

在这里插入图片描述


4. MDS降维效果

4.1 2D可视化

from sklearn.manifold import MDS
from sklearn.preprocessing import MinMaxScaler

# 导入数据
X, y = datasets.load_digits(return_X_y=True)
# 数据降维
mds = MDS(n_components=2, verbose=1, random_state=42)
result = mds.fit_transform(X)
# 归一化处理
scaler = MinMaxScaler(feature_range=(-1, 1), copy=True)
result = scaler.fit_transform(result)
# 可视化展示
plt.figure(figsize=(10, 10))
plt.title('MDS process')
plt.scatter(result[:,0], result[:,1], c=y, s=10)

在这里插入图片描述

4.2 3D可视化

from sklearn.manifold import MDS
from sklearn.preprocessing import MinMaxScaler

# 导入数据
X, y = datasets.load_digits(return_X_y=True)
# 数据降维
mds = MDS(n_components=3, verbose=1, random_state=42)
result = mds.fit_transform(X)
# 归一化处理
scaler = MinMaxScaler(feature_range=(-1, 1), copy=True)
result = scaler.fit_transform(result)
# 可视化展示
fig = plt.figure(figsize=(14, 14))
ax = fig.add_subplot(projection='3d')
ax.set_title('MDS process')
ax.scatter(result[:,0], result[:,1], result[:,2] , c=y, s=10)

在这里插入图片描述


5. SpectralEmbedding降维效果

5.1 2D可视化

from sklearn.manifold import SpectralEmbedding
from sklearn.preprocessing import MinMaxScaler


# 导入数据
X, y = datasets.load_digits(return_X_y=True)
# 数据降维
sp = SpectralEmbedding(n_components=2, random_state=42)
result = sp.fit_transform(X)
# 归一化处理
scaler = MinMaxScaler(feature_range=(-1, 1), copy=True)
result = scaler.fit_transform(result)
# 可视化展示
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111)
ax.set_title('SpectralEmbedding process')
ax.scatter(result[:,0], result[:,1], c=y, s=10)

在这里插入图片描述

5.2 3D可视化

from sklearn.manifold import SpectralEmbedding
from sklearn.preprocessing import MinMaxScaler


# 导入数据
X, y = datasets.load_digits(return_X_y=True)
# 数据降维
sp = SpectralEmbedding(n_components=3, random_state=42)
result = sp.fit_transform(X)
# 归一化处理
scaler = MinMaxScaler(feature_range=(-1, 1), copy=True)
result = scaler.fit_transform(result)
# 可视化展示
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(projection='3d')
ax.set_title('SpectralEmbedding process')
ax.scatter(result[:,0], result[:,1], result[:,2] , c=y, s=10)

在这里插入图片描述


6. 总结

通过可视化的比较,可以明显的看得出来,t-SNE的降维效果是最好的,那么如果使用t-SNE降维后再使用一些机器学习的分类方法能否可以超越深度学习的方法呢?这里我做了一个实验,详细见:t-SNE原理介绍与对手写数字MNIST的可视化结果,最后的答案效果是不好的。

线性降维方法包括PCA、LDA时间消耗较少,但是这种线性降维方法会丢失高维空间中的非线性结构信息。相比较而言,非线性降维方法(这里没有提到KPCA和KLDA,有兴趣的可以试一试这两类非线性降维方法)中的流形学习方法可以很好的保留高维空间中的非线性结构信息。虽然典型的流形学习是非监督的方法,但是也存在一些有监督方法的变体。

在进行数据降维时,我们一定要弄清楚我们降维的目的,是为了进行特征提取,使得之后的模型解释性更强或效果提升,还是仅仅为了可视化高维数据。在降维的方法的选择上,我们也要尽量平衡时间成本和降维效果。

另外,在降维时需要注意以下几点:

  • 降维之前,所有特征的尺度是一致的;
  • 重构误差可以用于寻找最优的输出维度𝑑d(此时降维不只是为了可视化),随着维度𝑑d的增加,重构误差将会减小,直到达到实现设定的阈值;
  • 噪音点可能会导致流形出现“短路”,即原本在流形之中很容易分开的两部分被噪音点作为一个“桥梁”连接在了一起;
  • 某种类型的输入数据可能导致权重矩阵是奇异的,比如在数据集有超过两个样本点是相同的,或者样本点被分在了不相交的组内。在这种情况下,特征值分解的实现solver='arpack’将找不到零空间。解决此问题的最简单的办法是使用solver='dense’实现特征值分解,虽然dense可能会比较慢,但是它可以用在奇异矩阵上。除此之外,我们也可以通过理解出现奇异的原因来思考解决的办法:如果是由于不相交集合导致,则可以尝试n_neighbors增大;如果是由于数据集中存在相同的样本点,那么可以尝试去掉这些重复的样本点,只保留其中一个。

这部分的总结来自参考资料2.


参考资料:

1. RGB配色表
2. 十种方法实现图像数据集降维

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Clichong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值