主成分分析(Principal Component Analysis,PCA)是一种无监督的机器学习算法,通常用于高维数据的降维、提取主要特征、数据降噪和可视化。PCA的基本思想是将原始数据的多个变量转换为少数几个相互独立的变量(即主成分),这些主成分能够尽可能多地保留原始数据的信息。
目录
基本概念
1.主成分(Principal Component)
通过原始数据集变量的线性组合构成的新变量。第一个主成分捕获了数据中最多的信息(即最大的方差),第二个主成分捕获了剩余方差中最大的部分,且与第一个主成分正交(即无相关性),以此类推。
2.方差(Variance)
衡量数据分布的离散程度。在PCA中,方差越大,表示该成分包含的信息量越多。计算公式为: 。
3.协方差
衡量两个随机变量联合变化趋势的统计量。若两变量的增减趋势相同(即一个变量增加,另一个变量也增加,呈正相关),则协方差 > 0;若一个变量增加而另一个变量减少,则协方差 < 0。计算公式为:
。
4.协方差矩阵
表示各变量间协方差的矩阵,不仅包含变量自身的方差,还包含变量间的协方差。表示为:
,其中 p表示变量数。
若已知 n×p的数据矩阵,其中 n表示观测数。则经过标准化处理,协方差矩阵可以这样计算: 。
5.特征值和特征向量
即协方差矩阵的特征值和特征向量,揭示了数据的内在结构。特征向量表示方向,即主成分的方向,是单位向量;特征值表示方差的大小,反映原始数据点映射到主成分方向上与中心的距离。满足: 。
工作步骤
1.准备数据矩阵
将原始数据整理成一个矩阵,每一行代表一个观测(或样本),每一列代表一个变量。对于有 n个样本和 p个变量的数据集,将得到一个 n×p的矩阵。
2.标准化数据
当变量的量纲或量级差异较大时,会高估或低估其表达的信息量,从而影响分析,因此在应用PCA之前通常需要对数据进行标准化(又称中心化)。常用 z-score标准化,即使每个变量满足均值为0,标准差为1。计算公式为: 。
3.计算协方差矩阵
计算经标准化后数据矩阵的协方差矩阵。协方差矩阵反映了数据中变量之间的线性关系。
4.计算特征值和特征向量
计算协方差矩阵的特征值和对应的特征向量。特征值有多个解,因为协方差矩阵是一个方阵,所以其特征值 ≤ p。按特征值的大小,将对应的特征向量从大到小排序,特征值越大,对应的主成分就越重要(即在该方向上数据的变异性越大)。最后,根据需要保留的信息量(如保留总方差的90%),选择前 k个最大的特征值对应的特征向量作为主成分。
5.构建主成分得分
利用选定的主成分对应的特征向量,将原始数据转换为一组新的低维数据。转换方法为:将数据矩阵与特征向量矩阵相乘得到低维空间的数据矩阵。计算公式为:
,其中
k亦可以解释为原始数据在最重要的 k个方向上的投影。
6.解释主成分
根据特征向量的元素(即载荷),可以用原始变量来表达主成分,并反映原始变量的贡献程度。载荷反映了原始变量在新的主成分方向上的权重,表示为:
,其中 k表示为主成分的个数,p表示为原始变量的个数, 表示为第 k个主成分的载荷, 表示为第 k个主成分的特征向量。故主成分可以表示为:
其中 表示为第 k个主成分, 表示为第 p个原始变量。
通过分析每个主成分的载荷,我们可以进一步解释每个主成分的含义:
高载荷变量:对于第 k个主成分,载荷的绝对值较大的变量对该主成分的形成贡献较大,因此这些变量在解释主成分时更为重要;
载荷的符号:载荷的符号(正或负)有助于理解变量之间的关系。同一主成分中,载荷符号相同的变量表现为正相关,符号不同的变量表现为负相关。
应用
通过 Python sklearn库实现 PCA:
1.准备数据
随机生成一组6维的数据集。
import numpy as np
np.random.seed(42) # 确保数据可重复
mean = np.zeros(6) # 随机生成6维数据的均值向量
cov = np.diag(np.arange(1, 7)) # 创建一个6x6的协方差矩阵,方差从1到6
X = np.random.multivariate_normal(mean, cov, 200) # 随机生成200个数据点
X
2.PCA降维
将数据降维到2维。
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
# 标准化数据
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 应用PCA
pca = PCA(n_components=2) # 降至2维
X_pca = pca.fit_transform(X_scaled)
3.数据可视化
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 8))
plt.scatter(X_pca[:, 0], X_pca[:, 1], s=40, alpha=1, edgecolors='black', linewidths=0.5)
plt.title('PCA Result', fontsize=20)
plt.xlabel('Principal Component 1', fontsize=15)
plt.ylabel('Principal Component 2', fontsize=15)
plt.grid(True)
# 保存为PDF格式
plt.savefig('PCA_Result_scatter.pdf', format='pdf')
plt.show()