Python机器学习之PCA降维算法详解
本文详细解析Python中主成分分析(PCA)降维算法的原理、计算步骤及优缺点。涵盖从数据零均值化、协方差矩阵构建到特征值分解的全过程,并提供基于NumPy和Scikit-learn的完整代码实现示例,帮助开发者掌握高维数据降维与可视化技巧。
一、算法概述
- 主成分分析(Principal Component Analysis,简称PCA)是一种经典的统计分析技术,旨在从众多变量中提炼出核心影响因素,从而揭示数据本质并简化复杂问题。
- 作为最常用的降维手段,PCA通过线性投影将高维数据映射至低维空间。其核心目标是在投影后的维度上最大化数据方差,从而在保留尽可能多原始信息的前提下,有效减少数据维度。
- PCA算法的核心在于求解样本数据协方差矩阵的特征值与特征向量。其中,特征向量所指示的方向即为PCA投影的最佳方向,确保数据在低维投影后仍能最大程度地表征原始数据分布。
- PCA能够将具有相关性的高维变量转化为线性无关的低维变量,这些新变量被称为“主成分”。主成分能够最大程度地保留原始数据中的关键信息。
- PCA广泛应用于高维数据集的探索性分析与可视化,同时也常用于数据压缩及作为其他机器学习模型的预处理步骤。
二、算法步骤

1. 构建原始数据矩阵X,其中行代表样本,列代表特征(共m行n列)。
2. 对矩阵X的每一列(即每个属性字段)进行零均值化处理,具体操作为减去该列的均值。
3. 计算处理后的数据的协方差矩阵。
4. 求解协方差矩阵的特征值及其对应的特征向量r。
5. 将特征向量按照对应特征值的大小,从左到右按列排列成矩阵,并选取前k列组成投影矩阵P。
6. 利用投影矩阵P计算降维至k维后的最终数据。
三、相关概念
方差:用于描述单个数据的离散程度。

协方差:用于描述两个数据之间的相关性。数值接近1表示正相关,接近-1表示负相关,接近0则表示不相关。

协方差矩阵:协方差矩阵是一个对称矩阵,其对角线元素分别代表各个维度的方差。

特征值:用于筛选降维过程中保留的K个关键特征值。特征向量:用于筛选降维过程中对应的K个特征向量。
四、算法优缺点
优点
- 优点:仅以方差衡量信息量,不受数据集外部因素的干扰。
- 优点:各主成分之间相互正交,能够有效消除原始数据成分间的相互影响。
- 优点:计算方法相对简单,核心运算为特征值分解,易于工程实现。
缺点
- 缺点:主成分所代表的物理或业务含义往往具有一定模糊性,其解释性不如原始样本特征直观。
- 缺点:方差较小的非主成分可能包含对样本差异至关重要的信息,降维过程中丢弃的数据可能对后续数据处理产生负面影响。
五、算法实现
自定义实现
import numpy as np
# 对初始数据进行零均值化处理
def zeroMean(dataMat):
# 求列均值
meanVal = np.mean(dataMat, axis=0)
# 求列差值
newData = dataMat - meanVal
return newData, meanVal
# 对初始数据进行降维处理
def pca(dataMat, percent=0.19):
newData, meanVal = zeroMean(dataMat)
# 求协方差矩阵
covMat = np.cov(newData, rowvar=0)
# 求特征值和特征向量
eigVals, eigVects = np.linalg.eig(np.mat(covMat))
# 抽取前n个特征向量
n = percentage2n(eigVals, percent)
print("数据降低到:" + str(n) + '维')
# 将特征值按从小到大排序
eigValIndice = np.argsort(eigVals)
# 取最大的n个特征值的下标
n_eigValIndice = eigValIndice[-1:-(n + 1):-1]
# 取最大的n个特征值的特征向量
n_eigVect = eigVects[:, n_eigValIndice]
# 取得降低到n维的数据
lowDataMat = newData * n_eigVect
reconMat = (lowDataMat * n_eigVect.T) + meanVal
return reconMat, lowDataMat, n
# 通过方差百分比确定抽取的特征向量的个数
def percentage2n(eigVals, percentage):
# 按降序排序
sortArray = np.sort(eigVals)[-1::-1]
# 求和
arraySum = sum(sortArray)
tempSum = 0
num = 0
for i in sortArray:
tempSum += i
num += 1
if tempSum >= arraySum * percentage:
return num
if __name__ == '__main__':
# 初始化原始数据(行代表样本,列代表维度)
data = np.random.randint(1, 20, size=(6, 8))
print(data)
# 对数据降维处理
fin = pca(data, 0.9)
mat = fin[1]
print(mat)
利用Sklearn库实现
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.datasets import load_iris
# 加载数据
data = load_iris()
x = data.data
y = data.target
# 设置数据集要降低的维度
pca = PCA(n_components=2)
# 进行数据降维
reduced_x = pca.fit_transform(x)
red_x, red_y = [], []
green_x, green_y = [], []
blue_x, blue_y = [], []
# 对数据集进行分类
for i in range(len(reduced_x)):
if y[i] == 0:
red_x.append(reduced_x[i][0])
red_y.append(reduced_x[i][1])
elif y[i] == 1:
green_x.append(reduced_x[i][0])
green_y.append(reduced_x[i][1])
else:
blue_x.append(reduced_x[i][0])
blue_y.append(reduced_x[i][1])
plt.scatter(red_x, red_y, c='r', marker='x')
plt.scatter(green_x, green_y, c='g', marker='D')
plt.scatter(blue_x, blue_y, c='b', marker='.')
plt.show()
六、算法优化
PCA属于线性特征提取算法,通过计算将一组特征按重要性排序,得到一组互不相关的新特征。然而,该算法在构造子集时采用等权重方式,忽略了不同属性对分类贡献度的差异。
KPCA算法
KPCA(核主成分分析)是一种改进的非线性降维算法。它利用核函数思想对样本数据进行非线性变换,随后在变换空间中进行PCA处理,从而实现了非线性降维。
局部PCA算法
局部PCA是一种改进的局部降维算法。它在寻找主成分时引入具有局部光滑性的正则项,使得主成分能够保留更多的局部数据结构信息。
本文介绍了Python中PCA降维算法的核心原理与实现方法。如需了解更多Python PCA相关内容,欢迎查阅本站过往文章或继续浏览后续系列教程,感谢支持!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









