主成分分析(PCA)是一种常用的线性降维技术。理解它的应用将为处理更复杂的自编码器模型打下良好基础。本次动手练习将引导你使用Python和Scikit-learn在一个常见数据集上实现PCA。我们的目标是在数据集里减少特征数量,同时尽可能多地保留原始信息(方差)。我们还会对结果进行可视化,以便直观地了解PCA的功用。准备PCA:鸢尾花数据集我们将使用Scikit-learn中方便提供的知名鸢尾花数据集。该数据集包含150个鸢尾花样本,每个样本有四个特征:萼片长度、萼片宽度、花瓣长度和花瓣宽度。鸢尾花有三个品种:山鸢尾、变色鸢尾和维吉尼亚鸢尾。首先,让我们加载数据集:from sklearn.datasets import load_iris import numpy as np iris = load_iris() X = iris.data # 特征 y = iris.target # 目标标签(品种) print(f"Original data shape: {X.shape}") # 预期输出:Original data shape: (150, 4)输出显示了150个样本和4个特征,符合预期。特征缩放的重要性PCA对特征的尺度很敏感。如果某个特征的值范围远大于其他特征,它将在PCA计算中占据主导地位。为避免这种情况,我们应该对特征进行标准化,使其具有零均值和单位方差。Scikit-learn的StandardScaler非常适合此用。from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # 你可以验证缩放后数据的均值和标准差 # print(f"Mean of scaled data (approx): {np.mean(X_scaled, axis=0)}") # print(f"Std dev of scaled data (approx): {np.std(X_scaled, axis=0)}")我们的数据经过缩放后,就可以应用PCA了。应用主成分分析我们将使用Scikit-learn的PCA类。PCA的一个主要参数是n_components,它指定了我们希望将数据降到的主成分数量(即新的维度)。让我们首先将鸢尾花数据集的4个特征降至2个主成分,这将使我们能够在2D图中可视化数据。from sklearn.decomposition import PCA # 使用2个分量初始化PCA pca = PCA(n_components=2) # 在缩放后的数据上拟合PCA并进行转换 X_pca = pca.fit_transform(X_scaled) print(f"Shape after PCA: {X_pca.shape}") # 预期输出:Shape after PCA: (150, 2)如你所见,数据现在有150个样本和2个特征(我们的主成分)。这两个分量是PCA构建的新特征,表示原始四个特征的线性组合。可视化降维后的数据既然我们已将维度降至两维,我们可以创建一个散点图,查看不同鸢尾花品种在这个新的2D空间中的分布情况。我们将使用原始目标标签y为点进行颜色编码。{"layout":{"title":{"text":"PCA后鸢尾花数据集(2个分量)"},"xaxis":{"title":{"text":"主成分1"}},"yaxis":{"title":{"text":"主成分2"}},"width":600,"height":400,"showlegend":true},"data":[{"type":"scatter","mode":"markers","x":[-2.2647029,-2.08096166,-2.36422902,-2.29938414,-2.38984223],"y":[0.47417354,-0.67413356,-0.34190801,-0.5973945,-0.64683515],"name":"山鸢尾","marker":{"color":"#228be6","size":8}},{"type":"scatter","mode":"markers","x":[0.58041307,0.65536418,0.01451537,0.71499929,0.50376696],"y":[-0.48620036,-0.03293431,-0.61578554,0.28222102,0.04809102],"name":"变色鸢尾","marker":{"color":"#40c057","size":8}},{"type":"scatter","mode":"markers","x":[1.85402168,1.56409677,1.76434619,1.50100921,1.72776537],"y":[0.3757964,-0.03350123,-0.18054019,-0.00882054,0.1639086],"name":"维吉尼亚鸢尾","marker":{"color":"#fd7e14","size":8}}]}鸢尾花品种在由前两个主成分定义的2D空间中绘制。即使在降维后,也请注意这些类别分离得有多好。这个可视化效果提供了很多信息。它表明前两个主成分捕获了足够的信息,能很好地分辨出三种鸢尾花。山鸢尾品种(蓝色)与变色鸢尾(绿色)和维吉尼亚鸢尾(橙色)明显分离。理解解释方差通过降至2个分量,我们保留了多少信息?PCA通过explained_variance_ratio_属性帮助我们量化这一点。该属性返回一个数组,其中每个值表示每个选定分量所解释的方差百分比。print(f"Explained variance ratio per component: {pca.explained_variance_ratio_}") # 预期输出(约):Explained variance ratio per component: [0.72962445 0.22850762] print(f"Total explained variance by 2 components: {np.sum(pca.explained_variance_ratio_):.4f}") # 预期输出(约):Total explained variance by 2 components: 0.9581第一个主成分解释了大约73%的方差,第二个解释了大约23%。这两个分量共同捕获了原始4维数据中约95.81%的总方差。这是很不错的;我们将维度减半,同时保留了大部分数据的变异性。选择合适的分量数量通常涉及降维和信息损失之间的权衡。一个常见的决定方法是绘制累积解释方差与分量数量的关系图。# 用所有分量拟合PCA以查看完整范围 pca_full = PCA().fit(X_scaled) cumulative_explained_variance = np.cumsum(pca_full.explained_variance_ratio_)现在,让我们可视化这个累积解释方差。{"layout":{"title":{"text":"主成分的累积解释方差"},"xaxis":{"title":{"text":"主成分数量"},"tickvals":[0,1,2,3],"ticktext":["1个分量","2个分量","3个分量","4个分量"]},"yaxis":{"title":{"text":"累积解释方差比"},"range":[0,1.05]},"width":600,"height":400,"template":"plotly_white"},"data":[{"type":"bar","x":["1个分量","2个分量","3个分量","4个分量"],"y":[0.72962445,0.95813207,0.99482129,1.0],"marker":{"color":"#20c997"},"text":[0.7296,0.9581,0.9948,1.0],"texttemplate":"%{y:.2f}","textposition":"outside"},{"type":"scatter","mode":"lines+markers","x":["1个分量","2个分量","3个分量","4个分量"],"y":[0.72962445,0.95813207,0.99482129,1.0],"marker":{"color":"#1098ad"},"line":{"shape":"spline","smoothing":0.5}}]}此图表显示了随主成分数量增加而解释的累积方差。你可以看出,使用2个分量,超过95%的方差被捕获。这个图有助于你决定保留多少个分量。例如,如果你的目标是保留95%的方差,那么对于鸢尾花数据集来说,两个分量就足够了。如果你需要99%,你就会选择三个分量。数据重构(简要)PCA还允许你使用inverse_transform方法将降维后的数据转换回原始的高维空间。重构的数据不会与原始数据完全相同(除非你使用所有分量),因为在降维过程中会丢失一些信息。这种重构的想法是自编码器的核心,我们稍后会看到。X_reconstructed = pca.inverse_transform(X_pca) print(f"Shape of reconstructed data: {X_reconstructed.shape}") # 预期输出:Shape of reconstructed data: (150, 4) # 注意:X_reconstructed是X_scaled的近似值从PCA到自编码器本次动手练习演示了PCA如何有效地降低维度,同时保留数据中的重要方差。你学会了:通过缩放准备数据。使用Scikit-learn应用PCA。解释解释方差以选择分量数量。可视化转换后的数据。PCA执行线性变换。尽管它很强大,但它可能无法有效地捕获数据中复杂的非线性关系。这正是本课程主要主题——自编码器发挥作用的地方。自编码器是能够学习非线性降维的神经网络。将数据编码到较低维空间(如PCA的主成分)然后解码回来的原理对于自编码器来说也很根本。练习了PCA后,你现在能更好地理解自编码器用于特征提取的机制和优点。