主成分分析
深入了解PCA理论,解决维度问题,并通过真实数据掌握PCA实现的实践技能。
维度灾难
维度灾难在机器学习中指的是当处理大量特征(高维数据/高维特征空间)时出现的挑战和计算复杂性。随着特征数量或维度的增加,为了维持可靠且有意义的模式,所需的数据量也随之增加,这通常导致对数据和计算资源的需求上升,并增加过拟合的风险。
示例
考虑一个产品推荐系统,每个产品由多个特征描述,例如价格、尺寸、颜色、品牌等。随着特征数量的增加,可能的组合呈指数级增长,使得发现产品与用户偏好之间的有意义关系变得更加困难。这种高维数据会导致数据点稀疏,从而使准确预测更具挑战性,并需要更多数据以避免不可靠的结果,从而体现了维度灾难的问题。
降维
降维是指减少特征数量的过程,可以通过选择最重要的特征,或者将原始特征转换为一组更少的新特征来实现。并非所有降维方法都旨在保留信息(用于重构或解压缩),不同方法可以有不同的目标。
主成分分析(PCA)
主成分分析(PCA) 是一种降维技术,通过将数据投影到低维空间,同时尽可能保留数据中的方差,从而识别数据中的关键模式和关系。
要理解PCA,首先需要理解“维度”的概念。想象你在一款游戏中可以前后、左右移动,这是两个维度;如果还能向上飞行或向下挖掘,就引入了第三个维度。在数据科学中,维度类似于这些方向,但可以是任何变量——如年龄、身高、收入等。
注意:我们最多能直观地可视化三个维度,但如果维度更多呢?这时PCA就派上用场了。它能在尽量保留最重要信息的前提下,降低数据的维度。
PCA的性质
为了说明PCA的核心性质,假设有一个包含 个数据点的 维数据集,将其作为矩阵 的列向量。进一步设矩阵 的列为使用PCA估计出的数据点在 维空间中的投影。
注:维度投影 指的是将原始数据点投影到一个新的低维空间( 维),并尽可能保留原始方差,该过程通过将数据投影到由矩阵 的行所定义的新坐标轴上来实现。
PCA具有以下关键性质:
- PCA是一种线性方法,即存在一个矩阵 ,使得:
- 矩阵 的行是子空间( 维空间)的一组标准正交基。
注:标准正交基 是向量空间中的一组向量,其中每个向量长度为1(单位范数),且彼此相互垂直(正交),这类基在进行线性变换和投影时非常有用。
- 从 对 的重构(记作 )也是线性的,即:
- PCA最小化重构误差,使用Frobenius范数 。
- PCA最大化投影方差,即:
注:投影方差 此处指数据点在低维子空间上的投影分布的离散程度(变异性),PCA的目标是在寻找最优投影矩阵 时使这一方差最大化。
PCA的推导
可以证明,最小化重构误差等价于最大化投影方差,推导如下:
其中 表示矩阵 的第 行,而 被称为散度矩阵。
说明:
- #key# 协方差矩阵:协方差矩阵用于衡量两个随机变量共同变化的程度。#key# 是散度矩阵的一个缩放版本,定义为 。
- 当数据已经中心化(即 )时,协方差矩阵简化为 。
PCA算法步骤
-
数据中心化:对于给定的 维空间中的 个数据点构成的数据矩阵 ,计算每一维的均值,并从每个数据点中减去对应维度的均值,以实现数据中心化。
-
计算协方差矩阵:利用公式
计算中心化后数据的协方差矩阵 ,以衡量各维度之间的协变关系。
- 求解特征值与特征向量:计算协方差矩阵 的特征值()和特征向量()。这些特征向量代表主成分(即新的坐标轴方向),特征值表示对应主成分所捕获的方差大小。它们满足方程:
-
排序特征值:将特征值按降序排列,以确定能捕捉最多方差的主成分。
-
选取前 个特征向量:选择对应最大 个特征值的特征向量,构成一个低维子空间,用于投影原始数据。这些特征向量即为能够最好概括数据并保留最多信息的新维度。
PCA通过选择部分主成分有效降低数据维度,在尽可能保留原始数据方差的同时实现数据压缩和降维。
从零实现PCA
现在,我们将从头开始实现PCA,以应对高维数据带来的问题。以著名的鸢尾花(Iris)数据集为例,该数据集包含来自三种鸢尾花的150个样本,每个样本有四个测量特征。我们的目标是将这四个维度降至两个,以便可视化并更好地进行分析。
第一步:加载并预处理Iris数据集
在此步骤中,我们导入必要的库,并使用 sklearn.datasets 中的 load_iris 函数加载Iris数据集。将特征数据存储在变量 X 中。然后对数据进行预处理:对每个特征减去其均值并除以其标准差。此标准化步骤对PCA的有效运行至关重要。
1import numpy as np 2import pandas as pd 3from sklearn.datasets import load_iris 4 5iris = load_iris() 6X = iris.data 7attribute_names = iris.feature_names # 获取属性名称 8 9# 标准化数据 10X = (X - np.mean(X, axis=0)) / np.std(X, axis=0) 11 12# 使用属性名创建DataFrame 13df = pd.DataFrame(X, columns=attribute_names) 14 15print("预处理后的数据:") 16print(df.head())
第二步:计算协方差矩阵并进行特征分析
在这一步中,我们计算预处理后数据的协方差矩阵。如前所述,协方差矩阵的计算公式为 ,我们使用 np.cov 函数完成计算。
接着,使用 np.linalg.eig 函数对协方差矩阵进行特征分析,得到其特征值和特征向量。特征值表示各个主成分所解释的方差量,特征向量则代表主成分的方向。
1# 计算协方差矩阵 2covariance_matrix = np.cov(X.T) 3 4# 计算特征值和特征向量 5eigenvalues, eigenvectors = np.linalg.eig(covariance_matrix)
第三步:选择主成分并转换数据
在此步骤中,我们将特征值按降序排列,以识别方差最大的主成分。使用 np.argsort 和 [::-1] 实现排序。
然后选择前 k 个特征向量,其中 是我们希望降到的目标维度数。本例中选择 k = 2 以便可视化。
最后,通过将原始数据与选定的特征向量相乘,将数据转换到低维空间。转换后的数据保存在变量 transformed_data 中。
1# 将特征值按降序排序 2sorted_indices = np.argsort(eigenvalues)[::-1] 3sorted_eigenvalues = eigenvalues[sorted_indices] 4sorted_eigenvectors = eigenvectors[:, sorted_indices] 5 6# 选择前k个特征向量 7k = 2 8selected_eigenvectors = sorted_eigenvectors[:, :k] 9 10# 将数据转换到低维空间 11transformed_data = np.dot(X, selected_eigenvectors) 12 13import matplotlib.pyplot as plt 14# 创建字典映射类别标签为名称 15class_labels = {0: 'setosa', 1: 'versicolor', 2: 'virginica'} 16 17# 绘制散点图,类别作为图例 18for class_label in np.unique(iris.target): 19 plt.scatter(transformed_data[iris.target == class_label, 0], 20 transformed_data[iris.target == class_label, 1], 21 label=f'类别 {class_label} ({class_labels[class_label]})') 22 23plt.xlabel('第一主成分') 24plt.ylabel('第二主成分') 25plt.title('Iris数据集 - PCA') 26plt.legend() 27plt.show()
匹配答案
| 左侧 | 右侧 |
|---|---|
| PCA是无监督的。 | 它不需要带标签的数据。 |
| PCA是一种降维技术。 | 它通过创建新特征来减少特征数量。 |
| PCA使用正交变换。 | 它寻找方差最大的方向(主成分)。 |