目录
一、PCA的介绍
PCA(Principal Component Analysis,主成分分析) 是一种常用的数据分析方法,主要用于数据的降维和特征提取。它通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量,转换后的这组变量叫主成分。
PCA的主要特点:
- 降维:PCA通过减少数据的维度,可以在保留数据主要特征的同时,减少计算量和存储需求。
- 特征提取:PCA可以提取数据中的主要特征,使得数据在更少的维度上依然能够保持其主要的结构和变化。
- 去相关性:PCA转换后的主成分之间是不相关的,这有助于减少数据中的冗余信息。
二、PCA的优缺点
PCA作为一种常用的数据降维和特征提取方法,具有其独特的优点和缺点。
优点:
-
简化数据结构:PCA能够将高维数据降低到低维空间,同时保留数据中的主要特征信息,使得数据结构更加简单,易于理解和分析。
-
去除相关性:PCA通过正交变换消除原始数据中的相关性,减少数据中的冗余信息,降低数据的复杂性。
-
减少计算成本:降维后的数据具有更少的特征,因此在进行机器学习模型训练时,可以减少计算量和存储需求,加速训练过程。
-
可视化:对于二维或三维的数据,PCA能够直接进行可视化,帮助人们直观地理解数据的分布和特性。
-
无监督学习:PCA是一种无监督学习方法,不需要数据的标签信息,因此可以广泛应用于各种数据集。
PCA的缺点:
-
信息损失:PCA在降维过程中会丢失一部分信息,尤其是那些与所选择的主成分不相关的特征信息。因此,在降维时需要根据实际需求和数据特性选择合适的维度。
-
对异常值和噪声敏感:PCA对数据的分布假设较强,如果数据中存在异常值或噪声,可能会对主成分的计算产生较大影响,导致降维效果不佳。
-
非线性数据处理能力有限:PCA是一种基于线性变换的方法,对于非线性数据的处理能力有限。如果数据中存在非线性关系,可能需要使用其他方法(如核PCA、流形学习等)进行降维。
-
解释性较差:PCA降维后的特征通常是原始特征的线性组合,这些组合特征可能难以解释其实际意义。因此,在需要解释性的应用场景中,PCA可能不是最佳选择。
-
对参数选择敏感:PCA中需要选择降维后的维度数(即主成分的数量),这个参数的选择对降维效果有重要影响。如果选择的维度数过少,可能会导致信息损失过多;如果选择的维度数过多,则可能无法达到预期的降维效果。因此,在实际应用中需要根据经验和数据特性进行参数选择。
三、PCA的步骤
1. 数据预处理
- 标准化:首先,对原始数据进行标准化处理,使得每个特征(或称为变量)具有零均值和单位方差。这是因为PCA对数据的尺度敏感,标准化可以消除量纲和数量级的影响。
2. 计算协方差矩阵
- 计算标准化后数据的协方差矩阵。协方差矩阵表示了数据各维度之间的相关性。对于n个样本,p个特征的数据集,协方差矩阵是一个p×p的矩阵,其中每个元素C_{ij}表示第i个特征和第j个特征之间的协方差。
3. 计算协方差矩阵的特征值和特征向量
- 对协方差矩阵进行特征分解,得到特征值和对应的特征向量。特征值表示了对应的主成分的重要性(或方差),而特征向量则代表了主成分的方向。
4. 选择主成分
- 按照特征值的大小,对特征向量进行排序,并选择前k个最大的特征值对应的特征向量。这k个特征向量将构成一个新的k维空间,即主成分空间。
- 选择k的值是一个权衡信息保留和降维程度的过程。通常,可以根据特征值的累积贡献率(即前k个特征值之和占总特征值之和的比例)来确定k的值。
5. 数据转换(投影)
- 将原始数据投影到新的k维空间中,得到降维后的数据。这可以通过将原始数据乘以选定的k个特征向量构成的矩阵来实现。
- 具体来说,假设原始数据矩阵为X(n×p),选定的k个特征向量构成的矩阵为P(p×k),则降维后的数据矩阵Y(n×k)可以通过Y = XP计算得到。
四、PCA实例
1.假设一个二维数据集
# 假设有一个二维数据集X
X = np.array([[1, 2], [1, 4], [1, 0], [1, 1],[4, 2], [4, 4], [4, 0],[4, 1],[4, 3]])
2.数据预处理
# 计算均值和标准差
mean_vec = np.mean(X, axis=0)
std_dev = np.std(X, axis=0, ddof=1)
# 标准化数据
X_std = (X - mean_vec) / std_dev
3.计算协方差矩阵
#计算协方差矩阵
cov_mat = np.cov(X_std, rowvar=False)
4.计算协方差矩阵的特征值和特征向量
#计算协方差矩阵的特征值和特征向量
eigen_vals, eigen_vecs = np.linalg.eig(cov_mat)
5.选择主成分
# 选择主成分
# 排序特征值和对应的特征向量
idx = eigen_vals.argsort()[::-1]
eigen_vals_sorted = eigen_vals[idx]
eigen_vecs_sorted = eigen_vecs[:,idx]
# 选择主成分数量,例如选择前1个主成分
k = 1
eigen_vecs_k = eigen_vecs_sorted[:,:k]
6.投影数据
#投影数据到新的主成分空间
X_pca = X_std.dot(eigen_vecs_k)
7.绘制并打印降维结果
#绘制原始数据和降维后的数据
plt.figure(figsize=(8, 6))
#绘制原始数据
plt.subplot(1, 2, 1)
plt.scatter(X[:, 0], X[:, 1], c='blue', label='Original Data')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('Original Data')
#绘制降维后的数据
plt.subplot(1, 2, 2)
plt.scatter(X_pca[:, 0], np.zeros_like(X_pca[:, 0]), c='red', label='PCA transformed Data')
plt.xlabel('Principal Component 1')
plt.ylabel(' ') # 因为只有一个主成分,所以y轴没有标签
plt.title('PCA transformed Data')
# 添加图例
plt.legend()
# 显示图形
plt.tight_layout()
plt.show()
# 打印结果
print("选择的特征向量:\n", eigen_vecs_k)
print("投影后的数据X_pca:\n", X_pca)
8.结果
选择的特征向量:
[[0.70710678]
[0.70710678]]
投影后的数据X_pca:
[[-0.69422499]
[ 0.22613299]
[-1.61458298]
[-1.15440399]
[ 0.64741579]
[ 1.56777378]
[-0.27294219]
[ 0.1872368 ]
[ 1.10759479]]
9.完整代码
import numpy as np
import matplotlib.pyplot as plt
# 假设有一个二维数据集X
X = np.array([[1, 2], [1, 4], [1, 0], [1, 1],[4, 2], [4, 4], [4, 0],[4, 1],[4, 3]])
#数据预处理(标准化)
mean_vec = np.mean(X, axis=0)
std_dev = np.std(X, axis=0, ddof=1)
X_std = (X - mean_vec) / std_dev
#计算协方差矩阵
cov_mat = np.cov(X_std, rowvar=False)
#计算协方差矩阵的特征值和特征向量
eigen_vals, eigen_vecs = np.linalg.eig(cov_mat)
#选择主成分
# 排序特征值和对应的特征向量
idx = eigen_vals.argsort()[::-1]
eigen_vals_sorted = eigen_vals[idx]
eigen_vecs_sorted = eigen_vecs[:,idx]
# 选择主成分数量,例如选择前1个主成分
k = 1
eigen_vecs_k = eigen_vecs_sorted[:,:k]
#投影数据到新的主成分空间
X_pca = X_std.dot(eigen_vecs_k)
#绘制原始数据和降维后的数据
plt.figure(figsize=(8, 6))
#绘制原始数据
plt.subplot(1, 2, 1)
plt.scatter(X[:, 0], X[:, 1], c='blue', label='Original Data')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('Original Data')
#绘制降维后的数据
plt.subplot(1, 2, 2)
plt.scatter(X_pca[:, 0], np.zeros_like(X_pca[:, 0]), c='red', label='PCA transformed Data')
plt.xlabel('Principal Component 1')
plt.ylabel(' ') # 因为只有一个主成分,所以y轴没有标签
plt.title('PCA transformed Data')
# 添加图例
plt.legend()
# 显示图形
plt.tight_layout()
plt.show()
# 打印结果
print("选择的特征向量:\n", eigen_vecs_k)
print("投影后的数据X_pca:\n", X_pca)
五、总结
PCA是一种无监督学习方法,即在进行降维时不需要使用数据的标签信息。此外,PCA对数据的分布假设较强,如果数据中存在异常值或噪声,可能会对主成分的计算产生较大影响,导致降维效果不佳。因此,在实际应用中需要根据数据特性和需求选择合适的降维方法。由于降维后的数据保留了原始数据的主要特征信息,因此可以用于后续的机器学习模型训练、数据可视化等任务。