一、概述
主成分分析(Principal Component Analysis,PCA)是一种用于数据降维的方法,其核心目标是在尽可能保留原始数据信息的前提下,将高维数据映射到低维空间。该算法基于方差最大化理论,通过寻找数据的主要变化方向(即主成分),将原始数据投影到这些方向上,从而实现降维。
二、算法过程
1.数据中心化
指将数据的每个特征减去其均值,使得数据的均值为 0。这样做的目的是将数据的分布中心移到原点,便于后续计算协方差矩阵等操作,因为协方差矩阵的计算对于数据的中心位置比较敏感,中心化后可以更好地反映数据的内在结构和相关性。
值得说明的是,在某些情况下,特别是当不同特征的量纲差异较大或者数据的分布比较复杂时,除了数据中心化外,还会进行数据标准化。数据标准化是指将数据的每个特征减去对应特征列的均值再除以标准差,这样可以进一步消除不同特征在尺度上的差异,使得不同特征在后续的分析中具有相同的重要性,避免因特征尺度不同而导致的结果偏差。
2. 计算协方差矩阵
对中心化后的数据矩阵计算协方差,协方差矩阵描述了数据特征之间的相关性。
总体协方差矩阵计算公式为 Cov=1nXTcXcCov=1nXcTXc
样本协方差矩阵计算公式为 S=1n−1XTcXcS=1n−1XcTXc
其中nn是样本数量。实际计算中通常使用样本协方差,其中的1n−11n−1是总体协方差的无偏估计。
3. 计算协方差矩阵的特征值和特征向量
通过求解协方差矩阵SS的特征方程 |S−λI|=0|S−λI|=0 ,得到特征值λiλi和对应的特征向量vivi。特征值反映了数据在对应特征向量方向上的方差大小,特征值越大,说明数据在该方向上的变化程度越大,包含的信息越多。
4. 选择主成分
将特征值按照从大到小的顺序排列,对应的特征向量也随之重新排序。选择前 kk 个最大的特征值及其对应的特征向量,这些特征向量构成了新的低维空间的基向量。kk 的选择通常基于一个阈值,例如保留能够解释原始数据方差累计百分比达到一定比例(如 80%、90% 等)的主成分。
5.数据投影
将原始数据投影到由选定的 kk 个特征向量构成的低维空间中,得到降维后的数据。投影的计算公式为
Y=XcWY=XcW
其中,XcXc是中心化后的数据矩阵,WW是由前kk个特征向量组成的投影矩阵,YY 是降维后的数据矩阵。
三、示例
现有一组二维数据 X=⎡⎢ ⎢ ⎢ ⎢ ⎢ ⎢⎣1223344556⎤⎥ ⎥ ⎥ ⎥ ⎥ ⎥⎦X=[1223344556] ,下面使用PCA方法进行降维,将其从二维降至一维。
1.数据标准化
首先,计算每列的均值:
第一列均值:¯x1=1+2+3+4+55=3x¯1=1+2+3+4+55=3
第二列均值:¯x2=2+3+4+5+65=4x¯2=2+3+4+5+65=4
然后,对矩阵XX进行中心化,得到矩阵XcXc
Xc=Xc=⎡⎢ ⎢ ⎢ ⎢ ⎢ ⎢⎣1−32−42−33−43−34−44−35−45−36−4⎤⎥ ⎥ ⎥ ⎥ ⎥ ⎥⎦[1−32−42−33−43−34−44−35−45−36−4]==⎡⎢ ⎢ ⎢ ⎢ ⎢ ⎢⎣−2−2−1−1001122⎤⎥ ⎥ ⎥ ⎥ ⎥ ⎥⎦[−2−2−1−1001122]
2. 计算协方差矩阵
协方差矩阵SS的计算公式为S=1n−1XTcXcS=1n−1XcTXc,其中nn是样本数量。
XTcXc=XcTXc=[−2−1012−2−1012][−2−1012−2−1012]⎡⎢ ⎢ ⎢ ⎢ ⎢ ⎢⎣−2−2−1−1001122⎤⎥ ⎥ ⎥ ⎥ ⎥ ⎥⎦[−2−2−1−1001122]==[10101010][10101010]
则协方差矩阵 SS 为
S=15−1S=15−1[10101010][10101010]==[2.52.52.52.5][2.52.52.52.5]
3. 计算协方差矩阵的特征值和特征向量
对于矩阵 SS,其特征方程为 |S−λI|=0|S−λI|=0 ,其中 II 是单位矩阵。
∣∣∣2.5−λ2.52.52.5−λ∣∣∣|2.5−λ2.52.52.5−λ|==(2.5−λ)2−2.52(2.5−λ)2−2.52==00
展开可得 λ2−5λ=0λ2−5λ=0 ,解得特征值为 λ1=5λ1=5,λ2=0λ2=0。
求特征向量:
对于 λ1=5λ1=5 求解 (S−5I)v1=0(S−5I)v1=0
[2.5−52.52.52.5−5][2.5−52.52.52.5−5][v11v12][v11v12]==[−2.52.52.5−2.5][−2.52.52.5−2.5][v11v12][v11v12]==[00][00]
取 v11=1v11=1 ,则 v12=1v12=1 ,单位化后得到特征向量 v1=⎡⎢⎣1√21√2⎤⎥⎦v1=[1212] 。
对于 λ2=0λ2=0 ,求解 (S−0I)v2=0(S−0I)v2=0
[2.52.52.52.5][2.52.52.52.5][v21v22][v21v22]==[00][00]
取 v21=1v21=1 ,则 v22=−1v22=−1 ,单位化后得到特征向量 v2=⎡⎢⎣1√2−1√2⎤⎥⎦v2=[12−12] 。
4. 选择主成分
按照特征值从大到小排序,选择前 kk 个特征值对应的特征向量作为主成分。这里我们选择最大特征值 λ1=5λ1=5
对应的特征向量 v1=⎡⎢⎣1√21√2⎤⎥⎦v1=[1212] 作为主成分。
5. 数据投影
将中心化后的数据 XcXc 投影到主成分上,得到降维后的数据
Y=Xcv1=Y=Xcv1=⎡⎢ ⎢ ⎢ ⎢ ⎢ ⎢⎣−2−2−1−1001122⎤⎥ ⎥ ⎥ ⎥ ⎥ ⎥⎦[−2−2−1−1001122]⎡⎢⎣1√21√2⎤⎥⎦[1212]==⎡⎢ ⎢ ⎢ ⎢ ⎢ ⎢ ⎢⎣−2√2−√20√22√2⎤⎥ ⎥ ⎥ ⎥ ⎥ ⎥ ⎥⎦[−22−20222] 。
四、Python实现
scikit-learn实现:
import numpy as np
from sklearn.decomposition import PCA
# 数据
data = np.array([[1, 2],
[2, 3],
[3, 4],
[4, 5],
[5, 6]])
# 创建PCA对象,指定降维后的维度为1
pca = PCA(n_components=1)
# 使用PCA对数据进行降维
reduced_data = pca.fit_transform(data)
# 降维后的数据
print("降维后的数据:")
print(reduced_data)
编辑
函数实现:
import numpy as np
def pca(X, n_components):
# 数据中心化
X_mean = np.mean(X, axis=0)
X_centered = X - X_mean
# 计算协方差矩阵
cov_matrix = np.cov(X_centered, rowvar=False)
# 计算协方差矩阵的特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)
# 对特征值进行排序,获取排序后的索引
sorted_indices = np.argsort(eigenvalues)[::-1]
# 选择前n_components个最大特征值对应的特征向量
top_eigenvectors = eigenvectors[:, sorted_indices[:n_components]]
# 将数据投影到选定的特征向量上
X_reduced = np.dot(X_centered, top_eigenvectors)
return X_reduced
# 数据
X = np.array([[1,2],
[2,3],
[3,4],
[4,5],
[5,6]])
# 降至1维
n_components = 1
X_reduced = pca(X, n_components)
# 降维后的数据
print("降维后的数据:")
print(X_reduced)
行业拓展
分享一个面向研发人群使用的前后端分离的低代码软件——JNPF。
基于 Java Boot/.Net Core双引擎,它适配国产化,支持主流数据库和操作系统,提供五十几种高频预制组件,内置了常用的后台管理系统使用场景和实用模版,通过简单的拖拉拽操作,开发者能够高效完成软件开发,提高开发效率,减少代码编写工作。
JNPF基于SpringBoot+Vue.js,提供了一个适合所有水平用户的低代码学习平台,无论是有经验的开发者还是编程新手,都可以在这里找到适合自己的学习路径。
此外,JNPF支持全源码交付,完全支持根据公司、项目需求、业务需求进行二次改造开发或内网部署,具备多角色门户、登录认证、组织管理、角色授权、表单设计、流程设计、页面配置、报表设计、门户配置、代码生成工具等开箱即用的在线服务。