PCA主成分分析python实现
Github源码:https://github.com/csuldw/MachineLearning/tree/master/PCA
PCA(principle component analysis) ,主成分分析,主要是用来降低数据集的维度,然后挑选出主要的特征。原理简单,实现也简单。关于原理公式的推导,本文不会涉及,你可以参考下面的参考文献,也可以去Wikipedia,这里主要关注实现,算是锻炼一下自己。
本来是在复习LDA的,然后就看到了PCA,就跟着下面这篇文章的步骤,把PCA用Python实现了一遍,具体的思想可以参考这篇文章,讲的通俗易懂,主要是有个实例参考,值得拥有!
下面引用的是http://www.cnblogs.com/jerrylead/archive/2011/04/18/2020209.html中关于主成分分析的讲解
主成分分析(Principal components analysis)-最大方差解释
1、 比如拿到一个汽车的样本,里面既有以“千米/每小时”度量的最大速度特征,也有“英里/小时”的最大速度特征,显然这两个特征有一个多余。
5、 在信号传输过程中,由于信道不是理想的,信道另一端收到的信号会有噪音扰动,那么怎么滤去这些噪音呢?
回顾我们之前介绍的《模型选择和规则化》,里面谈到的特征选择的问题。但在那篇中要剔除的特征主要是和类标签无关的特征。比如“学生的名字”就和他的“成绩”无关,使用的是互信息的方法。
而这里的特征很多是和类标签有关的,但里面存在噪声或者冗余。在这种情况下,需要一种特征降维的方法来减少特征数,减少噪音和冗余,减少过度拟合的可能性。
第一步分别求x和y的平均值,然后对于所有的样例,都减去对应的均值。这里x的均值是1.81,y的均值是1.91,那么一个样例减去均值后即为(0.69,0.49),得到
对角线上分别是x和y的方差,非对角线上是协方差。协方差大于0表示x和y若有一个增,另一个也增;小于0表示一个增,一个减;协方差为0时,两者独立。协方差绝对值越大,两者对彼此的影响越大,反之越小。
上面是两个特征值,下面是对应的特征向量,特征值0.0490833989对应特征向量为,这里的特征向量都归一化为单位向量。
第四步,将特征值按照从大到小的顺序排序,选择其中最大的k个,然后将其对应的k个特征向量分别作为列向量组成特征向量矩阵。
这里特征值只有两个,我们选择其中最大的那个,这里是1.28402771,对应的特征向量是。
FinalData(10*1) = DataAdjust(10*2矩阵)×特征向量
这样,就将原始样例的n维特征变成了k维,这k维就是原始特征在k维上的投影。
上面的数据可以认为是learn和study特征融合为一个新的特征叫做LS特征,该特征基本上代表了这两个特征。
正号表示预处理后的样本点,斜着的两条线就分别是正交的特征向量(由于协方差矩阵是对称的,因此其特征向量正交),最后一步的矩阵乘法就是将原始样本点分别往特征向量对应的轴上做投影。
归纳一下,使用我们之前熟悉的表示方法,在求协方差之前的步骤是:
其中是样例,共m个,每个样例n个特征,也就是说是n维向量。是第i个样例的第j个特征。是样例均值。是第j个特征的标准差。
整个PCA过程貌似及其简单,就是求协方差的特征值和特征向量,然后做数据转换。但是有没有觉得很神奇,为什么求协方差的特征向量就是最理想的k维向量?其背后隐藏的意义是什么?整个PCA的意义是什么?
要解释为什么协方差矩阵的特征向量就是k维理想特征,我看到的有三个理论:分别是最大方差理论、最小错误理论和坐标轴相关度理论。这里简单探讨前两种,最后一种在讨论PCA意义时简单概述。
在信号处理中认为信号具有较大的方差,噪声有较小的方差,信噪比就是信号与噪声的方差比,越大越好。如前面的图,样本在横轴上的投影方差较大,在纵轴上的投影方差较小,那么认为纵轴上的投影是由噪声引起的。
因此我们认为,最好的k维特征是将n维样本点转换为k维后,每一维上的样本方差都很大。
比如下图有5个样本点:(已经做过预处理,均值为0,特征方差归一)
下面将样本投影到某一维上,这里用一条过原点的直线表示(前处理的过程实质是将原点移到样本点的中心点)。
假设我们选择两条不同的直线做投影,那么左右两条中哪个好呢?根据我们之前的方差最大化理论,左边的好,因为投影后的样本点之间方差最大。
回到上面左右图中的左图,我们要求的是最佳的u,使得投影后的样本点方差最大。
中间那部分很熟悉啊,不就是样本特征的协方差矩阵么(的均值为0,一般协方差矩阵都除以m-1,这里用m)。
We got it!就是的特征值,u是特征向量。最佳的投影直线是特征值最大时对应的特征向量,其次是第二大对应的特征向量,依次类推。
因此,我们只需要对协方差矩阵进行特征值分解,得到的前k大特征值对应的特征向量就是最佳的k维新特征,而且这k维新特征是正交的。得到前k个u以后,样例通过以下变换可以得到新的样本。
这是其中一种对PCA的解释,第二种是错误最小化,放在下一篇介绍。
PCA思想
主要思想:移动坐标轴,将n维特征映射到k维上(kn),这k维是全新的正交特征。这k维特征称为主元,是重新构造出来的k维特征,而不是简单地从n维特征中去除其余n-k维特征。
说到PCA难免会提到LDA(linear discriminate analysis,线性判别分析),以及FA(factor analysis,因子分析)。关于LDA,打算有时间也用代码实现一遍,下面给出它的主要思想。
LDA思想:最大类间距离,最小类内距离。简而言之,第一,为了实现投影后的两个类别的距离较远,用映射后两个类别的均值差的绝对值来度量。第二,为了实现投影后,每个类内部数据点比较聚集,用投影后每个类别的方差来度量。
三者的描述如下
以下内容引自 Wikipedia- Linear discriminant analysis
LDA is also closely related to principal component analysis (PCA) and factor analysis in that they both look for linear combinations of variables which best explain the data.[4] LDA explicitly attempts to model the difference between the classes of data. PCA on the other hand does not take into account any difference in class, and factor analysis builds the feature combinations based on differences rather than similarities. Discriminant analysis is also different from factor analysis in that it is not an interdependence technique: a distinction between independent variables and dependent variables (also called criterion variables) must be made.
区别:PCA选择样本点投影具有最大方差的方向,LDA选择分类性能最好的方向。
好了,下面来看下实现源码!
基本步骤
基本步骤:
- 对数据进行归一化处理(代码中并非这么做的,而是直接减去均值)
- 计算归一化后的数据集的协方差矩阵
- 计算协方差矩阵的特征值和特征向量
- 保留最重要的k个特征(通常k要小于n),也可以自己制定,也可以选择一个阈值,然后通过前k个特征值之和减去后面n-k个特征值之和大于这个阈值,则选择这个k
- 找出k个特征值对应的特征向量
- 将m * n的数据集乘以k个n维的特征向量的特征向量(n * k),得到最后降维的数据。
其实PCA的本质就是对角化协方差矩阵。有必要解释下为什么将特征值按从大到小排序后再选。首先,要明白特征值表示的是什么?在线性代数里面我们求过无数次了,那么它具体有什么意义呢?对一个n*n的对称矩阵进行分解,我们可以求出它的特征值和特征向量,就会产生n个n维的正交基,每个正交基会对应一个特征值。然后把矩阵投影到这N个基上,此时特征值的模就表示矩阵在该基的投影长度。特征值越大,说明矩阵在对应的特征向量上的方差越大,样本点越离散,越容易区分,信息量也就越多。因此,特征值最大的对应的特征向量方向上所包含的信息量就越多,如果某几个特征值很小,那么就说明在该方向的信息量非常少,我们就可以删除小特征值对应方向的数据,只保留大特征值方向对应的数据,这样做以后数据量减小,但有用的信息量都保留下来了。PCA就是这个原理。
源码实现
1.首先引入numpy,由于测试中用到了pandas和matplotlib,所以这里一并加载
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
2.定义一个均值函数
#计算均值,要求输入数据为numpy的矩阵格式,行表示样本数,列表示特征
def meanX(dataX):
return np.mean(dataX,axis=0)#axis=0表示按照列来求均值,如果输入list,则axis=1
3.编写pca方法,具体解释参考注释
"""
参数:
- XMat:传入的是一个numpy的矩阵格式,行表示样本数,列表示特征
- k:表示取前k个特征值对应的特征向量
返回值:
- finalData:参数一指的是返回的低维矩阵,对应于输入参数二
- reconData:参数二对应的是移动坐标轴后的矩阵
"""
def pca(XMat, k):
average = meanX(XMat)
m, n = np.shape(XMat)
data_adjust = []
avgs = np.tile(average, (m, 1))
data_adjust = XMat - avgs
covX = np.cov(data_adjust.T) #计算协方差矩阵
featValue, featVec= np.linalg.eig(covX) #求解协方差矩阵的特征值和特征向量
index = np.argsort(-featValue) #按照featValue进行从大到小排序
finalData = []
if k > n:
print "k must lower than feature number"
return
else:
#注意特征向量时列向量,而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
4.编写一个加载数据集的函数
#输入文件的每行数据都以\t隔开
def loaddata(datafile):
return np.array(pd.read_csv(datafile,sep="\t",header=-1)).astype(np.float)
5.可视化结果
因为我将维数k指定为2,所以可以使用下面的函数将其绘制出来:
def plotBestFit(data1, data2):
dataArr1 = np.array(data1)
dataArr2 = np.array(data2)
m = np.shape(dataArr1)[0]
axis_x1 = []
axis_y1 = []
axis_x2 = []
axis_y2 = []
for i in range(m):
axis_x1.append(dataArr1[i,0])
axis_y1.append(dataArr1[i,1])
axis_x2.append(dataArr2[i,0])
axis_y2.append(dataArr2[i,1])
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(axis_x1, axis_y1, s=50, c='red', marker='s')
ax.scatter(axis_x2, axis_y2, s=50, c='blue')
plt.xlabel('x1'); plt.ylabel('x2');
plt.savefig("outfile.png")
plt.show()
6.测试方法
测试方法写入main函数中,然后直接执行main方法即可:
data.txt可到github中下载:data.txt
#根据数据集data.txt
def main():
datafile = "data.txt"
XMat = loaddata(datafile)
k = 2
return pca(XMat, k)
if __name__ == "__main__":
finalData, reconMat = main()
plotBestFit(finalData, reconMat)
结果展示
最后的结果图如下:
蓝色部分为重构后的原始数据,红色则是提取后的二维特征!
参考文献
[1] http://www.cnblogs.com/jerrylead/archive/2011/04/18/2020209.html
[2] Wikipedia- Linear discriminant analysis
[3] Wikipedia- Principal_component_analysis
PCA主成分分析python实现相关推荐
- PCA主成分分析-Python特征值分解
PCA主成分分析 目的:找出向量W,得到线性可分的边界ZZ=W.T*X 步骤: w有两种求法 一个是特征值分解 一个是奇异值分解 代码部分最开始简单的计算结果有有这种小数,就查了一下,原因是二进制的问 ...
- 谱定理、瑞利熵、PCA(主成分分析)、clustering algorihtm
目录 一.谱定理(Spectral theorem) 二.瑞利熵(Rayleigh Quotients) 三.什么是PCA? 一.谱定理(Spectral theorem) 参考资料: 知乎文章:ht ...
- python 图像压缩pca_在Python中使用K-Means聚类和PCA主成分分析进行图像压缩
AI 人工智能 在Python中使用K-Means聚类和PCA主成分分析进行图像压缩 各位读者好,在这片文章中我们尝试使用sklearn库比较k-means聚类算法和主成分分析(PCA)在图像压缩上的 ...
- PCA主成分分析算法专题【Python机器学习系列(十五)】
PCA主成分分析算法专题[Python机器学习系列(十五)] 文章目录 1. PCA简介 2. python 实现 鸢尾花数据集PCA降维 3. sklearn库实现 鸢尾花数据集PCA降维案例 ...
- 通俗解释如何理解主成分分析PCA,Python实现PCA主成分分析2维降到1维
知道IEEE这个世界最大电子电气学术组织禁止华为资助和中国某些一流大学教授参与审稿这个消息我是愤怒的.我也是无奈的,学校考核必须发论文到这儿,不得不发.IEEE上面的论文中国人几乎占了三成(美国人搞学 ...
- 吴恩达机器学习作业7 - K-means和PCA主成分分析(Python实现)
吴恩达机器学习作业7 - K-means和PCA主成分分析(Python实现) Introduction 在本实验中,将实现K-means聚类算法,并将其应用于图像压缩.在第二部分实验中,将使用主成分 ...
- pca降维python实例_主成分分析(Principal component analysis, PCA)例子–Python | 文艺数学君...
摘要这一篇是关于PCA的实战, 我们会举一个例子, 看一下PCA具体在实战中是如何来进行的. 同时我们会比较同一个数据下, 使用PCA(主成分分析)和FA(因子分析)得到结果的不同. 简介 这一篇文章 ...
- 数据分析实战:python热门音乐分析 附代码+数据 +论文(PCA 主成分分析,sklearn 机器学习,pytorch 神经网络,k-means 聚类,Librosa 音频处理,midi 音序)
项目概述: 本选取了抖音当下最热门的 400 首音乐,通过一系列方法提取每首歌的波形特征,再经过降维以及机器学习等手段,进行无监督学习对音乐数据进行聚类的同时训练并使用监督学习分类器进行音乐流派分类, ...
- 【python数据分析】数据建模之 PCA主成分分析
PCA主成分分析:最广泛无监督算法 + 基础的降维算法. 通过线性变换将原始数据变换为一组各维度线性无关的表示,用于提取数据的主要特征分量 → 高维数据的降维 PCA主成分分析: 二维数据降维 / 多 ...
- Python——PCA主成分分析
PCA主成分分析 输入X,降低后的维度k def PCA_Batch_Feat(X, k, center=True):"""param X: BxCxHxWparam k ...
最新文章
- Dockerfile 最佳实践
- openssl qt linux 安装,在Ubuntu 16.04.1上使用OpenSSL构建Qt失败
- 【LeetCode】0136. 只出现一次的数字
- 股权分配中的三种定时炸弹
- Java程序员谈一谈-----java程序员成长之路
- Appium+Python移动端 实战——教你如何xpath定位自动化测试
- 1259:【例9.3】求最长不下降序列
- Accept-Encoding
- 尼尔森十大可用性原则
- 基于STM32简易计算器
- Basler相机全部型号详细参数
- Android 使用 Android Studio 把图片转为WebP格式来减小图片的大小
- hdu5294Tricks Device 最大流之最小割
- SD卡、记忆棒等内存卡的数据恢复方法
- java 带t日期格式转换_自我整理:java 日期转换
- 什么是机器学习,为什么它如此重要?
- 离散数学——用c/c++求命题公式的主范式
- 滚动条自动显示和隐藏
- BS4爬取电影天堂的下载地址并保存至csv文件
- 一堆密密麻麻的字,word怎么看字数?