本文包括两部分,使用python实现PCA代码使用sklearn库实现PCA降维,不涉及原理。

总的来说,对n维的数据进行PCA降维达到k维就是:

  1. 对原始数据减均值进行归一化处理;
  2. 求协方差矩阵;
  3. 求协方差矩阵的特征值和对应的特征向量;
  4. 选取特征值最大的k个值对应的特征向量;
  5. 经过预处理后的数据乘以选择的特征向量,获得降维结果。

实验数据

数据data.txt使用[2]中编写的数据,以下是部分数据截图:

shape为(31, 4),即31条特征数为4的数据。

使用python实现PCA

完整代码参考[2],这里逐步做详细介绍。

1. 导入数据

import numpy as np
import pandas as pddatafile = "data.txt"
XMat = np.array(pd.read_csv(datafile,sep=" ",header=None)).astype(np.float)
XMat.shape
(31, 4)

2. 去除平均值

求得XMat每列的平均值:

average = np.mean(XMat, axis=0)
average
array([5.01935484, 3.43870968, 1.47741935, 0.24516129])

扩展均值shape由(1, 4)到(31, 4):

# avgs为average的前m=31行,因为average只有1行,因此这31行是一样的
# np.tile(average, (m, 1))表示是二维的,m行4列
m, n = np.shape(XMat)
avgs = np.tile(average, (m, 1))
print(avgs.shape)# np.tile(average, m)是一维的,有m*4个值
print(np.tile(average, m))
print(np.tile(average, m).shape)
(31, 4)
avgs

XMat减去其每列均值:

data_adjust = XMat - avgs
data_adjust

3. 求XMat协方差矩阵的特征值和特征向量

因为是4列的数据即4维特征,因此协方差是4x4的:

covX = np.cov(data_adjust.T)
covX
array([[0.1356129 , 0.10022581, 0.01645161, 0.01576344],[0.10022581, 0.12245161, 0.00023656, 0.01919355],[0.01645161, 0.00023656, 0.03380645, 0.0053871 ],[0.01576344, 0.01919355, 0.0053871 , 0.00989247]])

特征值 0.23301081 对应特征向量为第一条列向量 [-0.72506043,-0.67669491,-0.06368499,-0.11097564],这里的特征向量都归一化为单位向量:

featValue, featVec=  np.linalg.eig(covX)
featValue
featVec
array([0.23301081, 0.04211748, 0.02128637, 0.00534878])array([[-0.72506043, -0.39050501,  0.5585571 ,  0.09903116],[-0.67669491,  0.49557031, -0.48975083, -0.23798779],[-0.06368499, -0.77541379, -0.58351247, -0.23278934],[-0.11097564, -0.02548266, -0.32813302,  0.93774397]])

4. 选择最大的k个特征值对应的k个特征向量

按照特征值从大到小排序,index显示位置:

index = np.argsort(-featValue)
index# 下面是从小到大
np.argsort(featValue)
array([0, 1, 2, 3], dtype=int64)array([3, 2, 1, 0], dtype=int64)

因为特征向量是列向量,这里转化成横向量:

k = 2
selectVec = np.matrix(featVec.T[index[:k]])
selectVec
matrix([[-0.72506043, -0.67669491, -0.06368499, -0.11097564],[-0.39050501,  0.49557031, -0.77541379, -0.02548266]])

5. 将样本点投影到选取的特征向量上

即数据集*特征向量的转置:

finalData = data_adjust * selectVec.T # (31, 4) * (4, 2) = (31, 2)
finalData.shape
finalData

6. 计算重构误差[3]

还原对应投影后的数据:

reconData = (finalData * selectVec) + average
print(reconData.shape)
reconData

根据[4]中的:

其中,m是样本个数,即数据的行数31。x是经过去均值处理的原始数据,这里是data_adjust。x(approx)是经过重构后还原的数据,这里是reconData。

求误差平方和,计算err1:

errMat = XMat - reconData
err1 = np.sum(np.array(errMat)**2) / n
err1
0.19976362846119633

计算err2:

err2 = np.sum(data_adjust**2) / n
err2
2.2632258064516138

计算η:

eta = err1/err2
eta
0.0882650011729915

根据[4],1-η=91%左右,说明该数据取k=2进行PCA降维时,能保留91%以上的信息。

使用sklearn库实现PCA降维

PCA的api详见[5],下面说明一些常用的属性和方法。

from sklearn.decomposition import PCApca = PCA(n_components=k)
pca.fit(XMat)

1. n_components参数:

  • 默认值为保留所有特征值,即不进行降维:
pca = PCA()
pca.fit(XMat)
pca.explained_variance_
array([0.23301081, 0.04211748, 0.02128637, 0.00534878])

explained_variance_ 即协方差矩阵的k个最大特征值,这里n_components是默认值,因此k=4。

  • n_components == 'mle' 时, 会自动确认降维维度,但是好像结果就是n-1(n是原始数据的列数,即特征个数):
pca.explained_variance_
array([0.23301081, 0.04211748, 0.02128637])

k=3的结果。

  • 0 < n_components < 1 时,即指定降维后的 方差和 占比,比例越大,降维后保留的信息越多,会自动确认降维的维度。

当n_components=0.9时是k=2的效果,n_components=0.95时是k=3的效果。

可以通过[6]中的画图来获取想要保留的信息和维度的关系:

import matplotlib.pyplot as pltdef pcaImg(XMat):pca=PCA( )pca.fit(XMat)ratio=pca.explained_variance_ratio_k = pca.n_components_print("pca.n_components_", k)# 绘制图形x = [i+1 for i in range(k)]y = [np.sum(ratio[:i+1]) for i in range(k)]print(y)plt.plot(x, y)plt.xticks(1+np.arange(k,step=1))plt.yticks(np.arange(0,1.01,0.05))plt.grid()plt.show()pcaImg(XMat)

横坐标表示k,纵坐标表示降维后可保留的信息。

可以看到,当k=1时能保留大概77%的信息;k=2时为91%,k=3时为98%,k=4时即没有降维,没有损失信息。

取 n_components = 0.9 时,打印结果:

确实是k=2。

2. components_ 属性

输出k个特征向量,每一行代表一个特征向量:

3. explained_variance_ 属性

输出所选择的k个最大特征值:

4. explained_variance_ratio_ 属性

保留的维度的方差百分比,就是每个特征值占其所有特征值总值的占比:

即k=1时,降维后可保留的信息为77%,k=2时为77%+24%等。

一般来说,占比过小的可以舍弃,即这里取k=2或3较好,具体情况具体分析。

5. n_components_ 属性

即设置的降维维度k:

6. fit_transform(X[, y]) 方法

获得降维后的结果,和 transform(X) 方法差不多:

7. get_covariance() 方法

获得协方差矩阵:

8. inverse_transform(X) 方法

由降维结果返回原始结果:

这里因为k=n,所有还原后就是原始值,实际上当k<n时就跟上面一样是有误差的。

总结

当数据维度过高时可使用降维手段如PCA,来使得维度变低,避免维度灾难,同时加快运算速度。

PCA降维本质上就是一种信息压缩,如把shape为(31, 4)的数据压缩为(31, 2)。

关于降维维度k的确定,可以使用sklearn中的PCA模块来获取数据的方差百分比,根据以上绘图的方法来确定最佳k值。

有些研究工作表明,所选的主轴总长度占所有主轴长度之和的大约85% 即可。即保留的维度的方差总百分比到达85%以上,但实际效果还是依靠训练之后产生的预测结果的评估来决定。

确定好了k值后,即可快速根据API获取降维后的数据,来进行后续的实验。

参考文档

[1] 降维算法一 : PCA (Principal Component Analysis)

[2] 机器学习降维之PCA(python代码+数据)

[3] PCA降维以及维数的确定

[4] PCA主成分数量(降维维度)选择

[5] sklearn.decomposition.PCA

[6] 通过PCA选择合适降维维度

python实现PCA降维相关推荐

  1. python实现PCA降维及可视化

    实现功能: python对数据清洗以及数据编码(具体实现方式可查看前两篇文章)后的变量进行PCA降维,并进行可视化展示. 实现代码: # 导入需要的库 import numpy as np impor ...

  2. python实现pca降维_python实现PCA(主成分分析)降维

    PCA复杂的原理在这就不说了,可以去网上看看相关资料,说的都很好,在这我主要说一下实现的过程. PCA计算过程: 第一步:求均值.求平均值,然后对于所有的样例,都减去对应的均值 第二步:求特征协方差矩 ...

  3. 用python实现PCA降维

    主成分分析(Principal Component Analysis) Step 1:去相关(Decorrelation) Step 2: 降维(Reduce Dimension) 数据是文本时 St ...

  4. python实现pca降维_Python实现PCA降维

    PCA算法 主成分分析(Principal Component Analysis,PCA)是最常用的一种降维方法,通常用于高维数据集的探索与可视化,还可以用作数据压缩和预处理等.PCA可以把具有相关性 ...

  5. PCA降维的来龙去脉及Python实现

    目录 1 PCA降维 2 在讲PCA降维的原理前需要知道的一些东西 2.1 方差 2.2 协方差及协方差矩阵 2.3 向量在不同基下的坐标 2.4 矩阵乘法 2.5 矩阵的特征值和特征向量 2.6 实 ...

  6. svd降维 python案例_PCA降维的原理、方法、以及python实现。

    PCA(主成分分析法) 1. PCA(最大化方差定义或者最小化投影误差定义)是一种无监督算法,也就是我们不需要标签也能对数据做降维,这就使得其应用范围更加广泛了.那么PCA的核心思想是什么呢? 例如D ...

  7. 三种方法实现PCA降维

    主成分分析,即Principal Component Analysis(PCA),是多元统计中的重要内容,也广泛应用于机器学习和其它领域.它的主要作用是对高维数据进行降维.PCA把原先的n个特征用数目 ...

  8. 数学推导+纯Python实现机器学习算法26:PCA降维

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 作为一种常见的多元统计分析方法,主成分分析法(Principal ...

  9. PCA降维算法原理及代码实现(python和matlab)

    常见的数据降维算法有:奇异值分解(SVD).主成分分析(PCA).因子分析(FA).独立成分分析(ICA). PCA降维的基本思想:通过计算数据矩阵的协方差矩阵,然后得到协方差矩阵的特征值.特征向量. ...

最新文章

  1. python3 time模块_python3 time模块
  2. 【leetcode 简单】第三十一题 买卖股票的最佳时机
  3. 科大讯飞cordova语音插件填坑及api介绍
  4. VS调试时怎么跳过for循环?
  5. C语言中的数据类型在VB中的申明
  6. 阻碍物联网腾飞几大难题盘点 看能想出什么对策
  7. [ZJOI2007]时态同步 树形DP
  8. jar bat dos窗口 隐藏
  9. ExtJs radiogroup form.loadRecord方法无法赋值正确解决办法
  10. Spring Security ACL使用Oracle数据库的配置与数据库脚本
  11. ueditor去掉本地保存功能
  12. Oracle实现数据不存在则插入,数据存在则更新(insert or update)
  13. ABAQUS装配节点建模教程
  14. 我从零开始学黑莓开发的过程
  15. Win10运行PS很卡,分享几种解决Win10用PS卡顿提速设置方法
  16. 神奇的BUG——MATLAB之1
  17. 国际赛事证书,220G数据集开放下载|ACCV2022国际细粒度图像分析挑战赛开赛
  18. Redisson(2-2)分布式锁实现对比 VS Java的ReentrantLock之带超时时间的tryLock
  19. 01赵玉荣-03安海莹-04郝玥-实训一
  20. python计算bmi的编程_Python学习-计算BMI的小程序

热门文章

  1. 利用transform:rotate( )制作折扇
  2. JAVA和SQL中时间的格式化知识
  3. python wasm_wasm和javascript
  4. Word骨灰级操作大全,赶紧留一份。
  5. http请求头中的content-type 属性
  6. Centos7.5运行iotop报错
  7. 计算机网络(自顶向下学习笔记)---网络层之控制平面
  8. 算法1.2.冒泡排序
  9. 万顿思电商:开网店运费怎样才能便宜点?
  10. 使用p5.js画一幅创意自画像