为何sns.scatterplot与plt.scatter对同一MNIST PCA数据输出不同?
MNIST PCA可视化两种方法结果差异的原因分析
问题背景
尝试用两种方式可视化MNIST手写数字数据集的PCA降维结果:
- 使用
sns.FacetGrid结合plt.scatter - 使用
sns.scatterplot
但两种方法生成的图差异明显,尤其是数字9的位置完全相反,需分析原因并判断结果正确性。
核心代码与可视化结果
数据预处理与PCA降维代码
from keras.datasets import mnist import matplotlib.pyplot as plt import numpy as np import seaborn as sns import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.decomposition import PCA (X_train, y_train), (X_test, y_test) = mnist.load_data() dim_1 = X_train.shape[0] dim_2 = X_train.shape[1] dim_3 = X_train.shape[2] arr = X_train.reshape(dim_1, dim_2 * dim_3) sc = StandardScaler() norm_arr = sc.fit_transform(arr) pca = PCA(n_components=2) pca_arr = pca.fit_transform(norm_arr) pca_arr = np.vstack((pca_arr.T, y_train)).T pca_df = pd.DataFrame(data=pca_arr, columns=("1st_principal", "2nd_principal", "label")) pca_df = pca_df.astype({'label': 'int32'})
方法1:FacetGrid + plt.scatter
代码:
sns.FacetGrid(pca_df, hue="label", height=6).map(plt.scatter, '1st_principal', '2nd_principal').add_legend() plt.show()
可视化结果:
方法2:sns.scatterplot
代码:
plt.figure(figsize=(7,7)) sns.scatterplot(x = pca_arr_combo[:, 0], y = pca_arr_combo[:, 1], hue = pca_arr_combo[:, 2], palette = sns.hls_palette(10), legend = 'full') plt.show()
可视化结果:
差异原因分析
两张图的核心差异并非来自FacetGrid或scatterplot的API差异,而是第二个代码中存在变量使用错误:
- 观察第二张图的x轴范围为0-9,正好对应MNIST的数字标签(0-9),说明代码中
x = pca_arr_combo[:, 0]实际取的是标签列,而非PCA的第一主成分列。 - 结合预处理代码可知,正确的降维后数据结构是
[第一主成分, 第二主成分, 标签](对应pca_arr的列顺序),但pca_arr_combo的列顺序大概率被错误调整(比如变成了[标签, 第一主成分, 第二主成分]),导致x轴误用了标签数据,完全偏离了PCA可视化的初衷。
正确性判断
- 第一种方法(FacetGrid + plt.scatter)的可视化是正确的:它以PCA的两个主成分为坐标轴,按标签区分颜色,符合降维后数据分布的可视化需求。
- 第二种方法的结果是错误的,根源在于变量列索引使用错误,导致坐标轴含义完全偏离预期。
内容的提问来源于stack exchange,提问作者Nemo
相关产品推荐
相关产品推荐

