老饼讲解:一步一步上手学习
在上节已经讲解了PCA的求解原理,这一节我们来具体编写代码来实现PCA的求解。在这里我们先调sklearn包求解,再自行写代码求解,然后比较一下它们的结果是否一致。
在自实现PCA之前,我们先来看看sklearn的PCA结果,具体例子代码如下:
"""
本代码展示一个用sklearn求解PCA主成分分析的例子
本代码来自《老饼讲解-机器学习》www.bbblearn.com
"""
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
# 加载数据
iris = load_iris()
X = iris.data # 样本X
x_mean = X.mean(axis=0) # 样本的中心
clf = PCA(svd_solver='full') # 初始化PCA对象
clf.fit(X) # 对X进行主成分分析
# 打印结果
print('\n主成分系数矩阵A:\n A=',clf.components_.T) # 打印系数矩阵A
print('\n主成分方差var:',clf.explained_variance_) # 打印主成分方差var
print('\n主成分贡献占比(方差占比)Pr:',clf.explained_variance_ratio_) # 打印贡献占比
y = clf.transform(X) # 通过调用transform方法获取主成分数据
y2= (X-x_mean)@clf.components_.T # 通过调用公式计算主成分数据 代码运行结果如下:

好了,这就是用sklearn求解PCA所得到的结果了。
下面我们来自实现PCA的求解,只需根据之前的原理解说进行编写代码就可以了,具体如下:
"""
本代码展示一个自实现PCA主成分分析的例子
本代码来自《老饼讲解-机器学习》www.bbblearn.com
"""
import numpy as np
from sklearn.datasets import load_iris
# 加载数据
iris = load_iris() # 加载数据
X = iris.data # 变量数据
x_mean = X.mean(axis=0) # 样本的中心
# 通过SVD分解,得到A与XA每列的方差var
xp = (X-x_mean)/np.sqrt(X.shape[0]-1) # 计算X的标准化数据
U,S,VT = np.linalg.svd(xp,full_matrices=False) # 注意,numpy的SVD分解出的是US(VT)
A = VT.T # 主成分系数矩阵A
var = S*S # 方差
pr = var/var.sum() # 方差占比
#打印结果
print('\n主成分系数矩阵A:\n A=',A) # 打印主成分系数
print('\n主成分方差var:',var) # 打印方差
print('\n主成分贡献占比(方差占比)Pr:',pr) # 打印方差占比
# 获取主成分数据
y= (X-x_mean)@A # 通过调用公式计算主成分数据 代码运行结果如下:

可以看到,PCA的求解就是这么简单,仅是对进行一下SVD分解就可以了。
自行编写代码的结果与调用sklearn包基本是一致的,只是系数的符号会有一点差异,这是因为sklearn在PCA后会对系数的符号作一些改变,但符号调整对结果是没影响的,这属于sklearn的骚操作我们就不去深究了,因为在其它软件、或者旧版本的sklearn是没有这样的符号转换的。
PCA的求解,其实只是将进行SVD分解得到就可以了,就后V就是系数矩阵,S的平方就是方差了,所以PCA求解的关键是理解它的原理,在实际操作上是非常简单的。
评论