接着上篇完成之后,已经过了2天时间了,终于,在今天将代码全部写完,并通过测试。太不容易了,主要是遇到一个坑,浪费好多时间。废话不多说,直接进入正题吧。

特征提取一般的都是使用主成分分析法,即PCA。

PCA的一般处理步骤分为:

  1. 中心化
  2. 求协方差矩阵
  3. 对协方差矩阵求特征值和特征向量,从而得到降维矩阵
  4. 通过中心化后的矩阵和降维矩阵的乘积即可得到最终的结果。

这里的话,就不介绍协方差矩阵相关的一些东西了,不懂的同学可以自行百度。

首先,我们来了解一下第三方库sklearn中的PCA的使用方法,一看你会觉得so easy的。

# sklearn PCA 调用
import numpy as np
import sklearn.decomposition as dp
from matplotlib import pyplot as plt
from sklearn.datasets import load_iris
#'''
x,y=load_iris(return_X_y=True)
print(x.shape) # 4维(150,4)
pca=dp.PCA(n_components=2)# pca.fit(x)
# a=pca.transform(x)
# print(a.shape)# fit和transform一块计算
reduced_x=pca.fit_transform(x)
print(len(reduced_x))
print(reduced_x[:10])
print('特征值:')
print(pca.n_features_)
print(pca.n_samples_)
print('特征向量:')
print(pca.components_)
print(type(reduced_x))
print(reduced_x.shape)
print(pca.explained_variance_ratio_)

可以直接忽略print相关代码,核心代码其实就是fit_transform函数,可以直接得到降维后的数据。


为了熟悉以上所说的步骤,我们通过numpy库来自实现一下这个步骤,

这里说明一下numpy.lianlg.eig方法可用于计算协方差矩阵的特征值和特征向量,返回值即为特征值和特征向量,另外,需要知道协方差矩阵的一个性质。

如此以来,可以对照着看一下如下代码:

'''使用Numpy来实现CPA,只具体到相应步骤'''
import numpy as np
from sklearn.datasets import load_iris
from sklearn.utils.extmath import svd_flipclass PCA:def __init__(self,n_components):self.n_components=n_componentsdef fit_transform(self,x):self.feature_count=x.shape[1]#中心化x=x-x.mean(axis=0)#协方差矩阵self.convariance=np.dot(x.T,x)/x.shape[0]# #求特征值和特征向量#  eig_vals,eig_vectors=np.linalg.eig(self.convariance)# # 排序获得前n个特征# idx=np.argsort(-eig_vals)# # 得到由特征向量组成的降维矩阵# self.components_=eig_vectors[:,idx[:self.n_components]]# print('特征值:')# print(eig_vals)# print('特征向量:')# print(self.components_)# # 对x进行降维处理# return np.dot(x,self.components_)U,S,V=np.linalg.svd(x,full_matrices=False)U,V=svd_flip(U,V)print(V)# 得到由特征向量组成的降维矩阵self.components_=V.T[:,:self.n_components]# print('特征值:')# print(eig_vals)print('特征向量:')print(self.components_)# 对x进行降维处理return np.dot(x,self.components_)pca=PCA(n_components=2)
x,y=load_iris(True)
x_components=pca.fit_transform(x)
print(x_components[:10])

相信眼尖的同学已经看到了,我处理函数中有一部分注释代码,是使用的eig方法,而再用的是svd函数,其实这里即是我要说的坑。

我一开始使用eig函数实现后,将对应的特征值打印出来后发现,第二维的数据与sklearn得到的数据刚好为相反数,这就很奇怪了,按道理的话,要么一致要么都相反才对,然后我怀疑我代码写的有问题,各种分析最后打开百度,一瞬间我就明了了,因为好多人都提了类似的问题,那区别究竟为何呢?查看sklearn的PCA方法可以看到起定义中使用的正是svd方法(奇异值分解法),这个方法只需要将中心化后的矩阵做为参数传入即可,但需要在处理结束后进行svd_flip操作,其实这才是第二维数据互为相反数的原因。其实就是使用的操作方法不一致,而导致的结果。

这里也警醒我,不是万不得已,不要放着现成的库不用,而使用自己写的方法,用自己的方法也并没有那么炫酷,而且容易掉坑里。

方法的详细实现,贵在了解其步骤,熟悉其内在原理,并不是要写出一个可以投入使用的方法。

那么到这里是不是就结束了呢?


其实我觉得,到上一步结束后,大部分都能了解PCA的处理流程了,但是,其实还可以再进一步的加深巩固一下,这部分留给有精力的同学喽,其实就是将中心化等能自己实现的都用np自己实现以下,这里也不多说什么,直接是那个代码就是了

'''PCA算法细节自实现'''
import numpy as np
from sklearn.datasets import load_irisclass PCA:def __init__(self,n_components):self.n_components=n_componentsdef fit_transform(self,X):self.X=Xself._centralizaed()self._conv()self._eig()# 这里一定要注意,是使用中心化后的矩阵和降维矩阵做乘result=np.dot(self.centerX,self.components)return result# 中心化def _centralizaed(self):mean=np.array([np.mean(col) for col in self.X.T]) #等同于 X.mean(axis=0)self.centerX=self.X-mean# 求协方差矩阵def _conv(self):self.convariance=np.dot(self.centerX.T,self.centerX)/self.X.shape[0]def _eig(self):eig_values,eig_vectors= np.linalg.eig(self.convariance)idx=np.argsort(-eig_values)self.components=eig_vectors[:,idx[:self.n_components]]print('特征值:')print(eig_values)print('特征向量:')print(self.components[:10])pca=PCA(n_components=2)
x,y=load_iris(return_X_y=True)
x_components=pca.fit_transform(x)
# print(pca.components.shape)
# print(pca.components[:10])
print(x_components.shape)
print(x_components[:10])

其实我认为,对于原理的掌握并不一定非要完全理解了,再去敲代码加深理解,在掌握原理的基础上,可以试着先跟着代码的思路其实现以下,运行了解一下相关的步骤结果,这样更有利于对原理的掌握。


对于python小白的我来说,今天这里还学到了,np.ndarray对矩阵的操作方法,其实都是numpy的一些用法,相对于list的基础操作来说,numpy可以支持更多简便的操作,因此我们在ML的过程中,一般都已numpy为运算库,因此需要多多学习numpy的用法了。


b=[[1,2,3],[4,5,6]]
b[:,a[:2]]
Traceback (most recent call last):File "<input>", line 1, in <module>
TypeError: list indices must be integers or slices, not tuple
type(b)
<class 'list'>import numpy as np
c=np.array([[1,2,3],[4,5,6]])
type(c)
<class 'numpy.ndarray'>
c[:,a[:2]]
array([[2, 3],[5, 6]])
c[:,[1,2]]
array([[2, 3],[5, 6]])
c[:,[0,2]]
array([[1, 3],[4, 6]])
b
[[1, 2, 3], [4, 5, 6]]
b.mean(axis=0)
Traceback (most recent call last):File "<input>", line 1, in <module>
AttributeError: 'list' object has no attribute 'mean'c.mean(axis=0)
array([2.5, 3.5, 4.5])
c.mean(axis=1)
array([2., 5.])
c.T
array([[1, 4],[2, 5],[3, 6]])
c.T[0]
array([1, 4])
cnp.transpose(c)
array([[1, 4],[2, 5],[3, 6]])

特征提取PCA实现及避坑指南相关推荐

  1. 2022年Matlab毕设避坑指南及选题推荐

    大家好,我是你的matlab大师. 2021学年,给众多的matlab方向童鞋们做了许多的课题,其中很多人加我,发现有大部分的同学因为是第一次没经验,由于自己基础不太行,在做大四的课题设计时,往往会找 ...

  2. 2023年Matlab毕设避坑指南及选题推荐

    大家好! 2021-2022学年,接了很多matlab数字图像处理/语音信号处理的单子,其中碰到了很多同学们的遭遇,给大家分享下.可以说因为都是第一次,没经验,往往会贪图便宜而踩坑被骗.基础不好不会做 ...

  3. 17条避坑指南:一份来自谷歌的数据库经验贴

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | https://medium.com/@rak ...

  4. 怎么把原来的墙拆掉_电视墙避坑指南要收好!拆掉重装太心累...

    电视墙是家里装修最为重要的一个地方. 相信很多人都想要把电视墙装修得简单又大气,而且还是容易搞卫生的整洁类型~但是,电视墙贴砖过程中,有很多坑需要注意,一不小心就要像下面的业主一样,拆掉重装. 业主反 ...

  5. VMProtect SDK完全避坑指南

    文章目录 前言 编译VMProtect Demo 生成机器码 替换密钥对 生成序列号 总结 前言 在编写软件的时候,通常会有这样一个需求,需要对自己写的软件实现一机一码加密保护,并且最好能够限制使用时 ...

  6. Serverless 时代前端避坑指南

    作者 | 张挺 每个时代,从来不缺机会. 云原生的浪潮席卷而来,从 14 年到现在,上云的声音就没有停歇过,而如今到了 2020,云厂商都已经准备好了,而前端,是否也准备好踏入这纷争的领域,去拥抱时代 ...

  7. 工业级光纤收发器使用“避坑”指南

    工业级光纤收发器在使用中有很多的注意事项,往往这些注意事项经常被忽略.下面飞畅科技就整理了一些工业级光纤收发器使用"避坑"指南,大家可以仔细看看,引起重视. 使用工业级光纤收发器连 ...

  8. 项目从0到1避坑指南

    背景: 物流行业,老板信息化意识弱,不是现有的TMS而是一个新的方向,目前市场上竞品较少 前言: 一个项目从0到1,有相关的固定的考虑事项.然而,由于公司环境.项目涉及的行业等一些实际条件的约束,会在 ...

  9. python避坑指南_Linux下Python3.6的安装及避坑指南

    Python3的安装 1.安装依赖环境 Python3在安装的过程中可能会用到各种依赖库,所以在正式安装 Python 3之前,需要将这些依赖库先行安装好. yum -y install zlib-d ...

最新文章

  1. Intent跳转到系统应用中的拨号界面、联系人界面、短信界面及其他
  2. java学习路线_java学习路线_我的入坑路
  3. Python基础(一)简介与安装
  4. python编译后的pyd爆破
  5. python学习: 如何循序渐进学习Python语言
  6. 虚拟路由器冗余协议-VRRP
  7. delphi7 安装delphi 5 delphi 6控件
  8. 处理接口超时_架构设计 | 接口幂等性原则,防重复提交Token管理
  9. 独家:为了永不停机的计算服务 - 四月月刊 | 凌云时刻
  10. html文件调整表格边框的属性,css怎么设置表格边框?
  11. MTK TouchPanel 驱动框架
  12. BP神经网络及其学习算法
  13. 谷歌浏览器 Cookie 设置
  14. 「Remmina」- 远程桌面客户端(SSH、SFTP、VNC、Windows Remote Desktop、...) @20210402
  15. Transform 3.1:SPSS 的通用数据转换程序
  16. caffe学习笔记31-理解全连接层
  17. 已知四边形四条边求四边形最大面积
  18. java雷霆战机小游戏(git 素材+代码)
  19. python凤凰新闻数据分析(一)python爬虫数据爬取
  20. socket网络编程封装错误处理函数

热门文章

  1. SQL刷题——查找最晚入职员工的所有信息
  2. C语言中的FILE结构体
  3. 实用APP分享:这3款“三无”浏览器,你竟然还不知道?
  4. 安装Proxmox VE系统报错
  5. 深度好文:最详细的卷积神经网络入门教程
  6. 【项目三、车牌检测+识别项目】二、使用YOLOV5进行车牌检测
  7. vue-pdf 跳坑
  8. IBM ThinkPad-如何激活和关闭数字小键盘
  9. linux驱动通过地址配置按键,linux输入子系统之多个按键
  10. 论文阅读 L2M-GAN:《L2M-GAN: Learning to Manipulate Latent Space Semantics for Facial Attribute Editing》