机器学习:matlab和python实现PCA降维算法
概述
降维是机器学习中十分重要的一种思想。在机器学习中,我们会经常处理一些高维数据,而高维数据情形下,会出现距离计算困难,数据样本稀疏等问题。这类问题是所有机器学习方法共同面临的问题,我们也称之为“维度灾难”。在高维特征中,也容易出现特征之间存在线性相关,也就是说有的特征是冗余的,因此降维也是必要的。
降维的优点(必要性):
- 去除噪声
- 降低算法的计算开销(改善模型的性能)
- 使得数据更容易使用
- 使得数据更容易理解(几百个维度难以理解,几个维度可视化易理解)
降维的方法有很多,主要分为两大类:
线性降维:PCA,LDA,SVD等
非线性降维:核方法(核+线性),二维化和张量化(二维+线性),流形学习(ISOMap,LLE,LPP)等
下面我们主要学习一下PCA降维算法。
1. 什么是降维?
降维,简单来说就是尽量保证数据本质的前提下将数据维数降低。降维可以理解为一种映射关系,例如函数z = f(x,y),可以二维转为一维。
2.什么是PCA?
PCA:principal component analysis,主成分分析,
是一种广泛用于数据压缩的算法(常用的降维技术)。PCA的思想是将n维特征映射到k维,这k维特征是全新的正交特征。这k维特征称为主元,是重新构造出来的特征。在PCA中,数据从原来的坐标系转换到新的坐标系下,新的坐标系的选择与数据本身决定。其中,第一个新坐标轴选择的是原始数据中方差最大的方向,第二个新坐标轴选取的是与第一个坐标轴正交且具有最大方差的方向,依次类推,我们可以取到这样的k个坐标轴,从而构造出k个特征。
3.PCA的操作步骤
(1)去平均值,即每一维特征减去各自的平均值
(2)计算协方差矩阵
(3)计算协方差矩阵的特征值与特征向量
(4)对特征值从大到小排序
(5)保留最大的k个特征向量
(6)将数据转换到k个特征向量构建的新空间中
具体实例:
(我们先用矩阵利器matlab工具做)
我们现在有二维数组:dataSet,10行2列
这个数据我们可以自己做,手动输入到txt文档里就可以了。
10行2列的数据,求每一维(每一列的数据均值):dataSetMean,1行2列
然后,原始数据每一维上的数据减去各自的均值得到dataSetAdjust,10行2列
计算dataSetAdjust的协方差矩阵(怎么计算一个矩阵的协方差矩阵?请点这里),得到dataCov,2行2列
求协方差矩阵的特征值和特征向量(怎么计算特征值和特征向量?清点这里):
特征值:D
特征向量:V
接着,对特征值进行排序,2维降1维,显然1.4214>0.1120
我们选择第二个特征值对应的特征向量:V_
转换到新的空间得到降维后的数据:FinalData,10行1列
dataSetAdjust * V_ ,
这样,我们就完成了,将10 × 2降维到10 × 1(2维降到1维)。
pca_SampleData_matlab.m
clc;clear
%% 导入数据
dataSet = load('data/SampleData.txt');% pca
k = 1; % 目标维数
[FinalData, reconData] = PCA(dataSet, k);%% 作图
hold on
plot(dataSet(:,1), dataSet(:,2), '.');
plot(reconData(:,1), reconData(:,2), '.r');
hold off
PCA.m
function [ FinalData,reconData ] = PCA( dataSet, k )[m,n] = size(dataSet);%% 去除平均值%取平均值dataSetMean = mean(dataSet);%减去平均值dataSetAdjust = zeros(m,n);for i = 1 : mdataSetAdjust(i , :) = dataSet(i , :) - dataSetMean;end%% 计算协方差矩阵dataCov = cov(dataSetAdjust);%% 计算协方差矩阵的特征值与特征向量[V, D] = eig(dataCov);% 将特征值矩阵转换成向量d = zeros(1, n);for i = 1:nd(1,i) = D(i,i);end%% 对特征值排序[maxD, index] = sort(d);%% 选取前k个最大的特征值% maxD_k = maxD(1, (n-k+1):n);index_k = index(1, (n-k+1):n);% 对应的特征向量V_k = zeros(n,k);for i = 1:kV_k(:,i) = V(:,index_k(1,i));end%% 转换到新的空间FinalData = dataSetAdjust*V_k;% 在原图中找到这些点, 数据还原reconData = FinalData * V_k';for i = 1 : mreconData(i , :) = reconData(i , :) + dataSetMean;end
end
(我们用python做)
python3代码实现:
# -*- coding: utf-8 -*-import numpy as np#计算均值,要求输入数据为numpy的矩阵格式,行表示样本数,列表示特征
def meanX(dataX):return np.mean(dataX,axis=0)#axis=0表示按照列来求均值,如果输入list,则axis=1def pca(XMat, k):average = meanX(XMat) m, n = np.shape(XMat)avgs = np.tile(average, (m, 1))data_adjust = XMat - avgscovX = np.cov(data_adjust.T) #计算协方差矩阵featValue, featVec= np.linalg.eig(covX) #求解协方差矩阵的特征值和特征向量index = np.argsort(-featValue) #按照featValue进行从大到小排序if k > n:print ("k must lower than feature number")returnelse:#注意特征向量是列向量,而numpy的二维矩阵(数组)a[m][n]中,a[1]表示第1行值selectVec = np.matrix(featVec.T[index[:k]]) #所以这里需要进行转置finalData = data_adjust * selectVec.T reconData = (finalData * selectVec) + average return finalData, reconData#根据数据集data.txt
def main(): XMat = np.loadtxt("data/SampleData.txt")k = 1 # 目标维数return pca(XMat, k)if __name__ == "__main__":finalData, reconMat = main()
我们依次查看运行过程求解得到的变量:
原始数据(待降维的数据集),XMat:
每列特征均值:average:
原始数据集每一维特征减去均值average,得到data_adjust:
计算data_adjust矩阵的协方差矩阵,得到covX矩阵:
计算协方差矩阵的特征值和特征向量:
特征值,feaValue:
特征向量,feaVec:
对特征值进行排序,从大到小,选取前k个特征值对应的特征向量,我们的例子是二维降一维,只需要选最大的特征值对应的特征向量(selectVec)即可,很显然是上述矩阵的第二列。
转换到新空间:
finalData = data_adjust * selectVec.T
python直接调用PCA模块实现:
from sklearn.decomposition import PCA
import numpy as npdatas = np.loadtxt('data/SampleData.txt') # 原始数据pca = PCA(n_components=1) # 加载PCA算法,设置降维后主成分数目为1
datas_pca = pca.fit_transform(datas) # 对样本进行降维,data_pca降维后的数据
run result:
这样太方便了,感觉走上了人生巅峰!!!(我们最好在明白原理,计算步骤的情况下使用,莫要成为一名调包侠啦,哈哈)
注:发现一个问题,matlab降维和python降维结果不相同啊!它们的结果相差一个负号
这个并不影响后面的计算。
实际上,都是对的,为什么这么说呢?
仔细阅读你会发现,matlab和python在计算特征向量的过程中出现了差异,也就是出现了正负号的问题,第二个特征向量用matlab和python计算时,正负号不同啦。
出现的原因是什么呢?如果你学过线性代数,你会知道,一个矩阵A对应的特征值是不变的,特征值对应着特征向量,这个向量是一个通解(参数取值不同,会改变),k*p + C, 其中k和C是常数,而p是特征值对应的基础解系。因此,在matlab和python中出现正负号的原因,是常数的取值不同,比如说,matlab中,k默认取+1,C取0,而python中k默认取-1,C取0。因此,最终的结果,是正负号不同。
我们也可以这样理解,n维特征映射到k维,映射的方向不同(投影的方向),则出现结果符号(正负号)的差异。
如果你不是很懂,可以看我的关于求解矩阵特征值和特征向量的文章(请点这里)。
以上,是我们的个人理解,仅做参考,新手上路,勿喷啊,有错的的地方,请指正。
总结:PCA技术的一个很大的优点是,它是完全无参数限制的。在PCA的计算过程中完全不需要人为的设定参数或是根据任何经验模型对计算进行干预,最后的结果只与数据相关,与用户是独立的。
但是,这一点同时也可以看作是缺点。如果用户对观测对象有一定的先验知识,掌握了数据的一些特征,却无法通过参数化等方法对处理过程进行干预,可能会得不到预期的效果,效率也不高。
如果后期有空,源代码放github上,供需要的人免费使用,喜欢的给我点个star,谢谢。
参考和引用:
https://www.cnblogs.com/guoyaohua/p/8855636.html
https://www.cnblogs.com/jiangxinyang/p/9291741.html
https://www.cnblogs.com/zy230530/p/7074215.html
https://blog.csdn.net/google19890102/article/details/27969459
仅用来个人学习和分享,如若侵权,留言立删。
尊重他人知识产权,不做拿来主义者!
喜欢的可以关注我哦QAQ,
你的关注和喜欢就是我write博文的动力。
机器学习:matlab和python实现PCA降维算法相关推荐
- svd降维 python案例_菜菜的机器学习sklearn实战-----sklearn中的降维算法PCA和SVD
菜菜的机器学习sklearn实战-----sklearn中的降维算法PCA和SVD 概述 从什么叫维度说开来 简单讲,shape中返回了几个数字就是几维. 一张表最多就是一维 当一个数组中存在2张3行 ...
- 机器学习:python实现LDA降维算法
这次,我们来学习一种经典的降维方法: 线性判别分析(Linear Discriminant Analysis, 以下简称LDA). 在前面博客中(点我)我们讲解了PCA降维算法. PCA追求的是在降维 ...
- 机器学习实战-65:主成因分析降维算法(Principal Component Analysis)
机器学习实战-65:主成因分析降维算法(PCA) 深度学习原理与实践(开源图书)-总目录,建议收藏,告别碎片阅读! 机器学习分为监督学习.无监督学习和半监督学习(强化学习).无监督学习最常应用的场景是 ...
- PCA降维算法原理及代码实现(python和matlab)
常见的数据降维算法有:奇异值分解(SVD).主成分分析(PCA).因子分析(FA).独立成分分析(ICA). PCA降维的基本思想:通过计算数据矩阵的协方差矩阵,然后得到协方差矩阵的特征值.特征向量. ...
- 【Python机器学习】PCA降维算法讲解及二维、高维数据可视化降维实战(附源码 超详细)
需要全部代码请点赞关注收藏后评论区留言私信~~~ 维数灾难 维数灾难是指在涉及到向量计算的问题中,当维数增加时,空间的体积增长得很快,使得可用的数据在空间中的分布变得稀疏,向量的计算量呈指数倍增长的一 ...
- 【主成分分析】PCA降维算法及Matlab代码实现
前言 机器学习中经常会遇到高维变量的大数据集,并且大数据集的很多高维变量之间并不是独立的,它们之间往往存在相关关系.这些变量一方面为机器学习提供了大量的信息,另一方面由于信息冗余也增加了数据处理的 ...
- PCA降维算法总结以及matlab实现PCA(个人的一点理解)
转载请声明出处.by watkins song 鉴于本文比较混乱, 所以写了一个新的PCA的详细介绍, 请参见: http://blog.csdn.net/watkinsong/article/det ...
- 【吴恩达】机器学习作业ex7--(k-means聚类)与(PCA降维)Python
一.前言 此次还是分为俩个部分,第一部分是利用k-means算法进行聚类,第一部分分为俩小步骤,第一步为给好的数据集进行分类(ex7data2),第二步是利用k-means算法来对图片进行压缩,然后第 ...
- pca降维算法java_PCA 降维算法详解 以及代码示例
1. 前言 PCA : principal component analysis ( 主成分分析) 最近发现我的一篇关于PCA算法总结以及个人理解的博客的访问量比较高, 刚好目前又重新学习了一下PCA ...
- 02-27 周一 图解机器学习SVM-人脸识别之PCA降维
02-27 周一 图解机器学习SVM分类 时间 版本 修改人 描述 2023年2月27日09:48:38 V0.1 宋全恒 新建文档 简介 本文主要是在试图代码分析图解机器学习这本书中5.5人脸识别 ...
最新文章
- java记事本环境变量_java环境变量配置以及用记事本写程序
- mysql数据导入python_利用python将mysql中的数据导入excel
- C内存1:从硬盘 到 内存 到 CPU
- ffmpeg库编译加文字_使用ffmpeg库编译错误及解决办法
- NLP情感分析 动手学深度学习博客
- 独家 | 数据科学入门指南:新手如何步入数据科学领域?
- CentOS yum 源的配置与使用
- 前台服务(在通知栏显示服务)
- 如何在苹果官网下载旧版本的Xcode 方法
- oracle 字段以逗号结尾的更新 数据库_Oracle数据库某个字段的值为逗号分隔的多个值组成的字符串,以一个多选的下拉框进行查询...
- 回顾Vue计算属性VS其他语法有感
- 小米潘多拉路由器添加节点_小米mesh好用吗?AX3600AX1800 混组测试
- 使用协同过滤推荐算法进行电影推荐
- Android获取外网IP地址
- Error: GPG check FAILED
- cad直线和圆弧倒角不相切_CAD中圆角(fillet)与倒角(chamfer)的技巧总结
- 群晖经典第三方套件_使用群晖第三方套件进行IPV6的DDNS
- canal同步mysql到es
- 关于学习时,如何处理专业术语的见解
- 拿下18Koffer,黑马老学长分享了4点学习建议!