PCA实验记要
PCA主要用于简化数据,去掉冗余部分(线性相关)。前提条件是数据中没有太多异类数据,否则会严重影响效果,因为异类数据会导致不相关的变量相关系数变高。使用之前,一般会剔除或限制异类数据。并且,原始数据中,需要有线性相关的部分,如果每个变量都是线性无关的,那么PCA基本上也没有什么作用。PCA简化后,可以用于数据可视化,方便数据解读。下面的试验,演示PCA的一些特性,便于理解,后面的试验全部基于R语言。
原始数据
随机生成1000个记录,每个记录有三个变量,都是基于正太分布随机生成,它们线性独立
生成的散点图中,可以发现都是水平的椭圆,并且关联系数基本为0,说明变量之间是线性无关的。这三个变量也是数据的“主成份”。相关系数如下:
衍生数据
衍生数据基于主成份的线性组合,然后添加一些随机误差,避免完全的线性组合。可以发现,无论如何添加线性组合,只要进行适当处理,最后出来的结果都是前三个主成份可以表达99%+。
相关系数上可以看到一定的关系,
实验1:直接PCA
PCA计算方法是将协方差矩阵对角化,原理是找到一个线性转换矩阵,将原始数据转换到一个新的线性空间,使得其方差最大。因为方差越大,信息越大。但是由于异类数据也会生成非常大的方差,所以一般需要剔除掉异类数据(比如异类值全部设置为最大/小限制)。
根据图像,可以发现主成份是前三个。PCA模型信息如下:
试验2:先将变量均值变化为0,然后PCA
根据之前的协方差矩阵推导,发现协方差矩阵其实是使用等幂矩阵将数据矩阵X转换到一个均值为0的空间中,然后相乘得到。所以,我们的原始数据在PCA之前处理均值为0,得到的结果和直接使用PCA一致。PCA模型信息如下:
实验3:先正规化,然后PCA
由于不同变量的单位不同,导致一些单位较大的变量会主导整个主成份分布,数值较小的独立变量会被掩盖,所以需要将每个变量处理成相同的单位,然后PCA,下面将所有变量转成标准正在分布的Z值,
上面的PCA分布,可以发现第一主城分比之前低很多。
试验4:基于相关系数PCA
将数据处理成Z值后再PCA有个等价的简化处理,即直接对角化关联矩阵R,而不是协方差矩阵S,R与S的关系参考这里。因为R是由方差为1的变量计算协方差矩阵得到,而z值的处理过程正是式每个变量的方差为1(减均值对PCA结果没有影响),所以两者效果等价,但是关联矩阵计算效率明显高于z值预处理。
可以发现,两者的效果完全一致。
实现5:先01正规化,然后PCA
有时候,用正规化z值处理不太适合,那么使用01正规化,也是一个不错的选择,或者log正规化也可以,这里演示01正规化
得到的分布与z值正规化略有不同,但是前三个成分仍然是主成份。
总结
PCA用于剔除线性依赖数据,但是计算之前,需要处理有异类数据和归一化变量单位。归一化方法有很多,比如01归一化,log,z-值。z-值归一化的等价方法是关联矩阵对角化,可以极大提高计算效率。
实验脚本
直接将下面数据放到R中即可执行,推荐使用RStudio。
原文地址:https://www.cnblogs.com/petewell/p/11607348.html
- Spring Cloud(一)服务的注册与发现(Eureka)
- Shard 分片集群
- 面试官最爱的volatile关键字
- 玩转 WebView ,突破系统限制,让缓存更简单,更灵活
- Mycat 读写分离 数据库分库分表 中间件 安装部署,及简单使用
- 50道Java线程题
- Jrebel6.3.3破解,配置图文教程
- Spring Cloud(十一)高可用的分布式配置中心 Spring Cloud Bus 消息总线集成(RabbitMQ)
- Keras中带LSTM的多变量时间序列预测
- Spring Cloud(十)高可用的分布式配置中心 Spring Cloud Config 中使用 Refresh
- Hibernate 的性能优化的时候碰到了"抓取策略",有四种
- 基于 Spring Cloud 完整的微服务架构实战
- maven build时报错Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
- Spring Cloud(九)高可用的分布式配置中心 Spring Cloud Config 集成 Eureka 服务
- 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 数组属性和方法
- Ubuntu 安装cuda10.1驱动的实现步骤
- Android单例模式的几种方法总结
- android长截屏原理及实现代码
- Android 删除指定包名的App实例代码
- 在Ubuntu20.04 LTS中配置Java开发环境
- Android 加载GIF图最佳实践方案
- Android编程之方向传感器用法示例
- Ubuntu20.04安装cuda10.1的步骤(图文教程)
- Android的WebView与H5前端JS代码交互的实例代码
- Android 图片缓存机制的深入理解
- Ubuntu18.04安装Nvidia显卡驱动教程(图文)
- Android控件Spinner的使用方法(1)
- 学习使用Material Design控件(四)Android实现标题栏自动缩放、放大效果
- Ubuntu 20.04 CUDA&cuDNN安装方法(图文教程)
- Android开发之基于DialogFragment创建对话框的方法示例