PCA主成分分析Python实现

简介:

Github源码:https://github.com/csuldw/MachineLearning/tree/master/PCA

PCA(principle component analysis) ,主成分分析,主要是用来降低数据集的维度,然后挑选出主要的特征。原理简单,实现也简单。关于原理公式的推导,本文不会涉及,你可以参考下面的参考文献,也可以去Wikipedia,这里主要关注实现,算是锻炼一下自己,对PCA在理论的基础上画个圆满的句号。

本来是在复习LDA的,然后就看到了PCA,就跟着下面这篇文章的步骤,把PCA用python实现了一遍,具体的思想可以参考这篇文章,讲的通俗易懂,主要是有个实例参考,值得拥有!

JerryLead之PCA主成分分析

下面自己来简单的清理下思路!

PCA思想

思想:移动坐标轴,将n维特征映射到k维上(k<n),这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的本质就是对角化协方差矩阵。有必要解释下为什么将特征值按从大到小排序后再选。首先,要明白特征值表示的是什么?在线性代数里面我们求过无数次了,那么它具体有什么意义呢?对一个nnnn的对称矩阵进行分解,我们可以求出它的特征值和特征向量,就会产生n个n维的正交基,每个正交基会对应一个特征值。然后把矩阵投影到这n个基上,此时特征值的模就表示矩阵在该基的投影长度。特征值越大,说明矩阵(样本)在对应的特征向量上投影后的方差越大,样本点越离散,越容易区分,信息量也就越多。因此,特征值最大的对应的特征向量方向上所包含的信息量就越多,如果某几个特征值很小,那么就说明在该方向的信息量非常少,我们就可以删除小特征值对应方向的数据,只保留大特征值方向对应的数据,这样做以后数据量减小,但有用的信息量都保留下来了。PCA就是这个原理。


源码实现

1.首先引入numpy,由于测试中用到了pandas和matplotlib,所以这里一并加载

1
2
3
import  numpy as np
import  pandas as pd
import  matplotlib.pyplot as plt

2.定义一个均值函数


#计算均值,要求输入数据为numpy的矩阵格式,行表示样本数,列表示特征    

1
2
def  meanX(dataX):
     return  np.mean(dataX,axis = 0 ) #axis=0表示按照列来求均值,如果输入list,则axis=1

3.编写pca方法,具体解释参考注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
"""
参数:
- 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隔开

1
2
def  loaddata(datafile):
     return  np.array(pd.read_csv(datafile,sep = "\t" ,header = - 1 )).astype(np. float )

5.可视化结果

因为我将维数k指定为2,所以可以使用下面的函数将其绘制出来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def  plotBestFit(data1, data2):  
     dataArr1  =  np.array(data1)
     dataArr2  =  np.array(data2)
     
     =  np.shape(dataArr1)[ 0 ]
     axis_x1  =  []
     axis_y1  =  []
     axis_x2  =  []
     axis_y2  =  []
     for  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

1
2
3
4
5
6
7
8
def  main():    
     datafile  =  "data.txt"
     XMat  =  loaddata(datafile)
     =  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

[4]知乎-如何理解矩阵特征值

http://www.csuldw.com/2016/02/28/2016-02-28-pca/



本文转自 stock0991 51CTO博客,原文链接:http://blog.51cto.com/qing0991/1923625

相关文章
|
8天前
|
数据采集 缓存 定位技术
网络延迟对Python爬虫速度的影响分析
网络延迟对Python爬虫速度的影响分析
|
25天前
|
数据采集 JSON 数据处理
抓取和分析JSON数据:使用Python构建数据处理管道
在大数据时代,电商网站如亚马逊、京东等成为数据采集的重要来源。本文介绍如何使用Python结合代理IP、多线程等技术,高效、隐秘地抓取并处理电商网站的JSON数据。通过爬虫代理服务,模拟真实用户行为,提升抓取效率和稳定性。示例代码展示了如何抓取亚马逊商品信息并进行解析。
抓取和分析JSON数据:使用Python构建数据处理管道
|
10天前
|
数据采集 存储 JSON
Python爬虫开发中的分析与方案制定
Python爬虫开发中的分析与方案制定
|
17天前
|
数据可视化 开发者 Python
Python GUI开发:Tkinter与PyQt的实战应用与对比分析
【10月更文挑战第26天】本文介绍了Python中两种常用的GUI工具包——Tkinter和PyQt。Tkinter内置于Python标准库,适合初学者快速上手,提供基本的GUI组件和方法。PyQt基于Qt库,功能强大且灵活,适用于创建复杂的GUI应用程序。通过实战示例和对比分析,帮助开发者选择合适的工具包以满足项目需求。
62 7
|
1月前
|
数据可视化 算法 Python
基于OpenFOAM和Python的流场动态模态分解:从数据提取到POD-DMD分析
本文介绍了如何利用Python脚本结合动态模态分解(DMD)技术,分析从OpenFOAM模拟中提取的二维切片数据,以深入理解流体动力学现象。通过PyVista库处理VTK格式的模拟数据,进行POD和DMD分析,揭示流场中的主要能量结构及动态特征。此方法为研究复杂流动系统提供了有力工具。
67 2
基于OpenFOAM和Python的流场动态模态分解:从数据提取到POD-DMD分析
|
16天前
|
存储 数据处理 Python
Python科学计算:NumPy与SciPy的高效数据处理与分析
【10月更文挑战第27天】在科学计算和数据分析领域,Python凭借简洁的语法和强大的库支持广受欢迎。NumPy和SciPy作为Python科学计算的两大基石,提供了高效的数据处理和分析工具。NumPy的核心功能是N维数组对象(ndarray),支持高效的大型数据集操作;SciPy则在此基础上提供了线性代数、信号处理、优化和统计分析等多种科学计算工具。结合使用NumPy和SciPy,可以显著提升数据处理和分析的效率,使Python成为科学计算和数据分析的首选语言。
26 3
|
17天前
|
存储 机器学习/深度学习 算法
Python科学计算:NumPy与SciPy的高效数据处理与分析
【10月更文挑战第26天】NumPy和SciPy是Python科学计算领域的两大核心库。NumPy提供高效的多维数组对象和丰富的数学函数,而SciPy则在此基础上提供了更多高级的科学计算功能,如数值积分、优化和统计等。两者结合使Python在科学计算中具有极高的效率和广泛的应用。
33 2
|
22天前
|
数据采集 机器学习/深度学习 搜索推荐
Python自动化:关键词密度分析与搜索引擎优化
Python自动化:关键词密度分析与搜索引擎优化
|
23天前
|
数据可视化 算法 JavaScript
基于图论的时间序列数据平稳性与连通性分析:利用图形、数学和 Python 揭示时间序列数据中的隐藏模式
本文探讨了如何利用图论分析时间序列数据的平稳性和连通性。通过将时间序列数据转换为图结构,计算片段间的相似性,并构建连通图,可以揭示数据中的隐藏模式。文章介绍了平稳性的概念,提出了基于图的平稳性度量,并展示了图分区在可视化平稳性中的应用。此外,还模拟了不同平稳性和非平稳性程度的信号,分析了图度量的变化,为时间序列数据分析提供了新视角。
52 0
基于图论的时间序列数据平稳性与连通性分析:利用图形、数学和 Python 揭示时间序列数据中的隐藏模式
|
1月前
|
自然语言处理 算法 数据挖掘
探讨如何利用Python中的NLP工具,从被动收集到主动分析文本数据的过程
【10月更文挑战第11天】本文介绍了自然语言处理(NLP)在文本分析中的应用,从被动收集到主动分析的过程。通过Python代码示例,详细展示了文本预处理、特征提取、情感分析和主题建模等关键技术,帮助读者理解如何有效利用NLP工具进行文本数据分析。
46 2