数据降维处理:PCA之特征值分解法例子解析
请点击上面公众号,免费订阅。
《实例》阐述算法,通俗易懂,助您对算法的理解达到一个新高度。包含但不限于:经典算法,机器学习,深度学习,LeetCode 题解,Kaggle 实战。期待您的到来!
01
—
回顾
这两天推送了数据降维,提取主成分的基本概念,矩阵特征值分解法获取数据的主成分的推导过程,有需要的请参考:
今天,拿一个小例子,理解下特征值分解法求主成分的过程。
02
—
特征值分解法求主成分
在数据预处理:PCA原理推导中我们说到,求数据 X 的 k 个主成分就是求解
这个方阵的前 k 个最大特征值对应的特征向量。
我们还是拿高三101班的数学和外语的分数,要完成排名任务时,现在要对这批数据由二维降为一维,学生们的分数为了表达和书写的方便,拿出5个样本,矩阵 X的形状为:5个样本点2列特征,
数学 外语
X = [ [108, 100],
[ 82, 85],
[75, 84],
[120, 109],
[99, 91] ]
还记得我们设定的那个X吗?长这样:
X是要按照样本点按axis = 1(列轴)排序的,所以重新将 X 变为这样:
X = [ [108, 82, 75, 120, 99], #数学成绩
[100, 85, 84, 109, 91] ] #外语成绩
画出以上5个点,找出这5个点的第一主成分方向,然后以此为轴,将5个样本投影到这个轴上,就会抓取5个样本的主要特征,这个主成分提取的矩阵分解法的操作步骤如下所示:
第一步,X的shape找对了(一般矩阵运算和经常使用的Numpy等包,看一下某个矩阵和运算后的矩阵的 shape 是调试程序,寻找bug,经常用到的。),还要把每个特征去均值,最终 X变为如下才和昨天的推导中使用的 X对应上了吧,
X = [ [ 11.2, -14.8, -21.8, 23.2, 2.2],
[ 6.2, -8.8, -9.8, 15.2, -2.8] ]
第二步,就该求方阵
了,在numpy中求得方阵为:
[ [ 1362.8, 759.8],
[ 759.8, 450.8] ]
今天有的小伙伴问我,小编,我们书上学得网上看到的都还得除以每一维元素的个数,此处等于5,为什么你这里没有除呢,是不是拉下了? 其实这里除以5,还是不除以5,都对最后的求第一主成分的方向没有任何影响吧,我们关心的是它的方向,而不是向量的大小,只要方向ok,就ok。
第三步,得到了这个方阵后,下一步该求它的特征值和对应的特征向量了吧,我们直接在numpy中求出上面协方差矩阵的特征值和对应的特征向量:
特征值有2个:[ 1792.93319541, 20.66680459]
分别对应的特征向量的矩阵如下,注意,向量一般指列向量,所以特征值1792对应的特征向量为第一列,
[[ 0.87022851, -0.49264829],
[ 0.49264829, 0.87022851] ]
第四步,选取最大特征值对应的特征向量:[0.87022851, 0.49264829],可以看到numpy给出的特征向量已经标准化(模等于1)。
第五步,我们已经求出了第一主特征对应的方向向量了,这一步自然是将数据 X 投影到这个标准化后的特征向量 fpc = [0.87022851, 0.49264829] 上,还记得我们的数据在刚开始做的转置吗,一般习惯将 X 标记为 [样本个数,特征数]的二维数组吧,但是在此处,我们为了选取第一主成分向量而转置了吧,我们还是再回到熟悉的节奏上吧,投影上次说过了,不就是点乘特征向量标记的主轴吗,因此借用numpy的表示:
(X.T).dot(fpc .T)
= [ 12.80097873, -17.21468692, -23.7989348 , 27.67755548, 0.53508751]
好了,我们成功地将一个二维数据降维成1维了吧,以上就是整个的操作步骤。
展示下[0.87022851, 0.49264829] 这个向量定出的主轴方向吧,可以看到这5个点投影到这个新轴上,看着就是散的最开的方向。
03
—
总结和展望
至此,介绍完了利用矩阵分解法选取数据的主成分的背景,原理,例子解析。
还有一种方法可以用来选取数据的主成分,也是应用非常广泛,它就是奇异值分解获取数据的主成分,明天阐述下奇异值分解的相关理论和如何做数据降维。
- 赋值运算符函数__from <剑指Offer>
- 从static变量导出问题解析 __declspec(dllexport) 和 __declspec(dllimport)的作用
- php实现SESSION跨域
- 使用cJSON解析JSON字符串
- 逻辑回归 | TensorFlow深度学习笔记
- MakeSureDirectoryPathExists与CreateDirectory的区别
- 粗略的物体碰撞预测及检测
- 讨厌算法的程序员 1 | 插入排序
- FFmpeg菜鸡互啄#第6篇#音频帧格式转换(重采样)
- TF.Learn 手写文字识别
- PHP中的防御性编程
- Ray-AABB交叉检测算法
- javascript里的sleep()方法
- 编程求取直线一般式表达式,两直线交点
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- android中使用Html渲染的方式实现必填项前面的*号示例
- android视频播放简单实现示例(VideoView&MediaPlayer)
- Android中SharedPreference详解及简单实例
- Devtools 老师傅养成[5] - Network 面板
- android实现上传本地图片到网络功能
- android音乐播放简单实现的简单示例(MediaPlayer)
- Android实现桌面悬浮小火箭效果
- Android数据库中事务操作方法之银行转账示例
- Android实现QQ登录功能
- Devtools 老师傅养成[6] - Performance 面板
- RecyclerView上拉加载封装代码
- Devtools 老师傅养成[7] - Memory 内存
- Android实现简单的城市列表功能
- Android Animation之TranslateAnimation(平移动画)
- Android自定义View实现箭头沿圆转动实例代码