为了账号安全,请及时绑定邮箱和手机立即绑定

PCA算法的分析与实现

标签:
机器学习

PCA的执行步骤:

1、数据中心化:对X中的每一行(即一个特征属性)进行零均值化,即减去这一行的均值

2、求出数据中心化后矩阵X的协方差矩阵(即特征与特征之间的协方差构成的矩阵)

3、求解协方差矩阵的特征值和特征向量

4、将特征向量按照特征值从大到小按列进行排列称为矩阵,获取最前面的k列数据形成矩阵W。

5、利用矩阵W和样本集X进行矩阵的乘法得到降低到k维的最终数据矩阵。


1.基矩阵:
基矩阵与需要降维的N维数据相乘,
基矩阵的行数K(N>k),表示的是需要将数据降到第K维
那么如何选择最优基这个问题被形式化为:寻找一个一维基,使得所有数据变换为这个基上的坐标表示后,方差值最大。
2.协方差
对于上面二维降成一维的问题来说,找到那个使得方差最大的方向就可以了。
不过对于更高维,还有一个问题需要解决。考虑三维降到二维问题。
与之前相同,首先我们希望找到一个方向使得投影后方差最大,这样就完成了第一个方向的选择,继而我们选择第二个投影方向。
如果我们还是单纯只选择方差最大的方向,很明显,这个方向与第一个方向应该是“几乎重合在一起”,
显然这样的维度是没有用的,因此,应该有其他约束条件。
从直观上说,让两个字段尽可能表示更多的原始信息,我们是不希望它们之间存在(线性)相关性的,
因为相关性意味着两个字段不是完全独立,必然存在重复表示的信息。
3.优化目标
降维问题的优化目标:将一组N维向量降为K维(K大于0,小于N),
其目标是选择K个单位(模为1)正交基,使得原始数据变换到这组基上后,各字段两两间协方差为0,
而字段的方差则尽可能大(在正交的约束下,取最大的K个方差)。
4.协方差矩阵
5.协方差矩阵对角化(除对角线外的其它元素化为0,并且在对角线上将元素按大小从上到下排列)


图片描述

图片描述

图片描述

图片描述


算法流程
图片描述


算法实例

图片描述
要降到第K(K<N)维,就取P矩阵的前N行进行相乘
P矩阵的每一行代表一个特征向量


代码实例

#createData
import numpy as np
import matplotlib.pyplot as plt 

#1. data normalization
x = np.array([2.5,0.5,2.2,1.9,3.1,2.3,2,1,1.5,1.1])
y = np.array([2.4,0.7,2.9,2.2,3,2.7,1.6,1.1,1.6,0.9])
x1 = x
y1 = y
data = np.matrix([ [x1[i],y1[i]] for i in range(len(x1)) ])
mean_x = np.mean(x)
mean_y = np.mean(y)
x1 = x - mean_x
y1 = y - mean_y
data = np.matrix([ [x1[i],y1[i]] for i in range(len(x1)) ])

#2. 求协方差矩阵(Covariance Matrix)
#两种方式
#(1)协方差矩阵
cov1 = np.cov(x1,y1)
# (2) 散度矩阵
#normalization后均值为0,所以散度矩阵为:data * data.T
cov2 = np.dot(np.transpose(data),data)
#协方差矩阵和散度矩阵的特征值,特征向量一样
# cov2 / cov1 = matrix([[9,9],[9,9]])

#3.求协方差矩阵的特征值和特征向量
#用numpy自带的函数计算特征根和特征向量
val,vec = np.linalg.eig(cov1)
#val,vec = np.linalg.eig(cov2)

#绘制特征向量的图-->垂直的折线
plt.plot(x1,y1,'o')
xmin,xmax = x1.min(),x1.max()
ymin,ymax = y1.min(),y1.max()
dx = (xmax - xmin) * 0.2
dy = (ymax - ymin) * 0.2
plt.xlim(xmin - dx,xmax + dx)
plt.ylim(ymin - dy,ymax + dy)
plt.plot([vec[:,0][0],0],[vec[:,0][1],0],color ='red')
plt.plot([vec[:,1][0],0],[vec[:,1][1],0],color ='red')

# plt.show()  Figure_1.png

#4. 选择主要成分
main_pair = [(np.abs(val[i]) ,vec[:,i]) for i in range(len(val))]
# main_pair = [(0.049, array([-0.735,0.677])) , (1.284, array([-0.678,-0.735]))]
#从main_pair中选取前k个特征向量
#这里是二维数据,取k = 1
feature = main_pair[0][1]
#feature =  array([-0.735,0.677])

#5 原数据 X 特征向量 = 降维后的数据
new_data_reduced = np.transpose(np.dot(feature,np.transpose(data)))

#6. 可视化
new_data = np.transpose(np.dot(vec,np.transpose(data)))

plt.plot(x1,y1,'o',color = 'red')
plt.plot([vec[:,0][0],0],[vec[:,0][1],0],color = 'red')
plt.plot([vec[:,1][0],0],[vec[:,1][1],0],color = 'blue')
plt.plot(new_data[:,0],new_data[:,1],'^',color = 'blue')
plt.plot(new_data_reduced[:,0],[1.4] * 10,'*',color = 'green')
plt.show()
#Figure_2.png

Figure_1.png
图片描述
降维结果
图片描述
Figure_2.png
图片描述
参考教程1
参考教程2
参考教程3

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 1
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消