这些在前面文章都已经详细讲解,看了会很容易理解,详见前面文章:【机器学习】【PCA-1】PCA基本原理和原理推导 + PCA计算步骤讲解 + PCA实例展示数学求解过程
其实PCA计算过程很简单,核心的是理解PCA的原理推理,主要涉及协方差矩阵式C是一个实对角矩阵,实对角矩阵的不同特征值对应的特征向量是正交的!PCA降维后的降维矩阵的协方差矩阵要求是对角矩阵,每个维度特征互相的协方差cov(x,y)=0。然后用这俩思路联合起来推导出来的PCA降维公式Z=XU。
详细的推理过程还是看前面文章为妙。
完全人肉出品,代码如下所示:
# -*- coding: utf-8 -*-
"""
@author: 蔚蓝的天空Tom
Talk is cheap, show me the code
Aim:使用PCA求样本矩阵X的K阶降维矩阵Z
"""
import numpy as np
class CPCA(object):
'''用PCA求样本矩阵X的K阶降维矩阵Z
Note:请保证输入的样本矩阵X shape=(m, n),m行样例,n个特征
'''
def __init__(self, X, K):
'''
:param X,训练样本矩阵X
:param K,X的降维矩阵的阶数,即X要特征降维成k阶
'''
self.X = X #样本矩阵X
self.K = K #K阶降维矩阵的K值
self.centrX = [] #矩阵X的中心化
self.C = [] #样本集的协方差矩阵C
self.U = [] #样本矩阵X的降维转换矩阵
self.Z = [] #样本矩阵X的降维矩阵Z
self.centrX = self._centralized()
self.C = self._cov()
self.U = self._U()
self.Z = self._Z() #Z=XU求得
def _centralized(self):
'''矩阵X的中心化'''
print('样本矩阵X:\n', self.X)
centrX = []
mean = np.array([np.mean(attr) for attr in self.X.T]) #样本集的特征均值
print('样本集的特征均值:\n',mean)
centrX = self.X - mean ##样本集的中心化
print('样本矩阵X的中心化centrX:\n', centrX)
return centrX
def _cov(self):
'''求样本矩阵X的协方差矩阵C'''
#样本集的样例总数
ns = np.shape(self.centrX)[0]
#样本矩阵的协方差矩阵C
C = np.dot(self.centrX.T, self.centrX)/(ns - 1)
print('样本矩阵X的协方差矩阵C:\n', C)
return C
def _U(self):
'''求X得降维转换矩阵U, shape=(n,k), n是X的特征维度总数,k是降维矩阵的特征维度'''
#先求X的协方差矩阵C的特征值和特征向量
a,b = np.linalg.eig(self.C) #特征值赋值给a,对应特征向量赋值给b
print('样本集的协方差矩阵C的特征值:\n', a)
print('样本集的协方差矩阵C的特征向量:\n', b)
#给出特征值降序的topK的索引序列
ind = np.argsort(-1*a)
#构建K阶降维的降维转换矩阵U
UT = [b[:,ind[i]] for i in range(self.K)]
U = np.transpose(UT)
print('%d阶降维转换矩阵U:\n'%self.K, U)
return U
def _Z(self):
'''按照Z=XU求降维矩阵Z, shape=(m,k), n是样本总数,k是降维矩阵中特征维度总数'''
Z = np.dot(self.X, self.U)
print('X shape:', np.shape(self.X))
print('U shape:', np.shape(self.U))
print('Z shape:', np.shape(Z))
print('样本矩阵X的降维矩阵Z:\n', Z)
return Z
if __name__=='__main__':
'10样本3特征的样本集, 行为样例,列为特征维度'
X = np.array([[10, 15, 29],
[15, 46, 13],
[23, 21, 30],
[11, 9, 35],
[42, 45, 11],
[9, 48, 5],
[11, 21, 14],
[8, 5, 15],
[11, 12, 21],
[21, 20, 25]])
K = np.shape(X)[1] - 1
print('样本集(10行3列,10个样例,每个样例3个特征):\n', X)
pca = CPCA(X,K)
runfile('C:/Users/tom/PCA.py', wdir='C:/Users/tom')
样本集(10行3列,10个样例,每个样例3个特征):
[[10 15 29]
[15 46 13]
[23 21 30]
[11 9 35]
[42 45 11]
[ 9 48 5]
[11 21 14]
[ 8 5 15]
[11 12 21]
[21 20 25]]
样本矩阵X:
[[10 15 29]
[15 46 13]
[23 21 30]
[11 9 35]
[42 45 11]
[ 9 48 5]
[11 21 14]
[ 8 5 15]
[11 12 21]
[21 20 25]]
样本集的特征均值:
[ 16.1 24.2 19.8]
样本矩阵X的中心化centrX:
[[ -6.1 -9.2 9.2]
[ -1.1 21.8 -6.8]
[ 6.9 -3.2 10.2]
[ -5.1 -15.2 15.2]
[ 25.9 20.8 -8.8]
[ -7.1 23.8 -14.8]
[ -5.1 -3.2 -5.8]
[ -8.1 -19.2 -4.8]
[ -5.1 -12.2 1.2]
[ 4.9 -4.2 5.2]]
样本矩阵X的协方差矩阵C:
[[ 108.32222222 74.53333333 -10.08888889]
[ 74.53333333 260.62222222 -106.4 ]
[ -10.08888889 -106.4 94.17777778]]
样本集的协方差矩阵C的特征值:
[ 335.15738485 95.32771231 32.63712506]
样本集的协方差矩阵C的特征向量:
[[-0.30253213 -0.87499307 -0.37797014]
[-0.86718533 0.08811216 0.49012839]
[ 0.39555518 -0.47604975 0.78543792]]
2阶降维转换矩阵U:
[[-0.30253213 -0.87499307]
[-0.86718533 0.08811216]
[ 0.39555518 -0.47604975]]
X shape: (10, 3)
U shape: (3, 2)
Z shape: (10, 2)
样本矩阵X的降维矩阵Z:
[[ -4.56200104 -21.2336912 ]
[-39.28629002 -15.26038349]
[-13.30247561 -32.55597794]
[ 2.71190993 -25.49365577]
[-47.37858268 -38.02120912]
[-42.36990935 -6.0258027 ]
[-16.00097294 -14.43926499]
[ -0.822856 -13.7001301 ]
[ -5.42741864 -18.56462272]
[-13.80800193 -28.51385518]]
其实PCA计算过程很简单,核心的是理解PCA的原理推理。
(end)