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

相关文章
|
18天前
|
并行计算 安全 Java
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
在Python开发中,GIL(全局解释器锁)一直备受关注。本文基于CPython解释器,探讨GIL的技术本质及其对程序性能的影响。GIL确保同一时刻只有一个线程执行代码,以保护内存管理的安全性,但也限制了多线程并行计算的效率。文章分析了GIL的必要性、局限性,并介绍了多进程、异步编程等替代方案。尽管Python 3.13计划移除GIL,但该特性至少要到2028年才会默认禁用,因此理解GIL仍至关重要。
97 16
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
|
27天前
|
缓存 Rust 算法
从混沌到秩序:Python的依赖管理工具分析
Python 的依赖管理工具一直没有标准化,主要原因包括历史发展的随意性、社区的分散性、多样化的使用场景、向后兼容性的挑战、缺乏统一治理以及生态系统的快速变化。依赖管理工具用于处理项目中的依赖关系,确保不同环境下的依赖项一致性,避免软件故障和兼容性问题。常用的 Python 依赖管理工具如 pip、venv、pip-tools、Pipenv、Poetry 等各有优缺点,选择时需根据项目需求权衡。新工具如 uv 和 Pixi 在性能和功能上有所改进,值得考虑。
84 35
|
28天前
|
数据采集 数据可视化 数据挖掘
金融波动率的多模型建模研究:GARCH族与HAR模型的Python实现与对比分析
本文探讨了金融资产波动率建模中的三种主流方法:GARCH、GJR-GARCH和HAR模型,基于SPY的实际交易数据进行实证分析。GARCH模型捕捉波动率聚类特征,GJR-GARCH引入杠杆效应,HAR整合多时间尺度波动率信息。通过Python实现模型估计与性能比较,展示了各模型在风险管理、衍生品定价等领域的应用优势。
251 66
金融波动率的多模型建模研究:GARCH族与HAR模型的Python实现与对比分析
|
1月前
|
数据采集 缓存 API
python爬取Boss直聘,分析北京招聘市场
本文介绍了如何使用Python爬虫技术从Boss直聘平台上获取深圳地区的招聘数据,并进行数据分析,以帮助求职者更好地了解市场动态和职位需求。
|
1月前
|
机器学习/深度学习 运维 数据可视化
Python时间序列分析:使用TSFresh进行自动化特征提取
TSFresh 是一个专门用于时间序列数据特征自动提取的框架,支持分类、回归和异常检测等机器学习任务。它通过自动化特征工程流程,处理数百个统计特征(如均值、方差、自相关性等),并通过假设检验筛选显著特征,提升分析效率。TSFresh 支持单变量和多变量时间序列数据,能够与 scikit-learn 等库无缝集成,适用于大规模时间序列数据的特征提取与模型训练。其工作流程包括数据格式转换、特征提取和选择,并提供可视化工具帮助理解特征分布及与目标变量的关系。
75 16
Python时间序列分析:使用TSFresh进行自动化特征提取
|
1月前
|
机器学习/深度学习 数据可视化 数据挖掘
使用Python实现基于矩阵分解的长期事件(MFLEs)时间序列分析
在现代数据分析中,高维时间序列数据的处理和预测极具挑战性。基于矩阵分解的长期事件(MFLEs)分析技术应运而生,通过降维和时间序列特性结合,有效应对大规模数据。MFLE利用矩阵分解提取潜在特征,降低计算复杂度,过滤噪声,并发现主要模式。相比传统方法如ARIMA和深度学习模型如LSTM,MFLE在多变量处理、计算效率和可解释性上更具优势。通过合理应用MFLE,可在物联网、金融等领域获得良好分析效果。
64 0
使用Python实现基于矩阵分解的长期事件(MFLEs)时间序列分析
|
1月前
|
数据可视化 算法 数据挖掘
Python时间序列分析工具Aeon使用指南
**Aeon** 是一个遵循 scikit-learn API 风格的开源 Python 库,专注于时间序列处理。它提供了分类、回归、聚类、预测建模和数据预处理等功能模块,支持多种算法和自定义距离度量。Aeon 活跃开发并持续更新至2024年,与 pandas 1.4.0 版本兼容,内置可视化工具,适合数据探索和基础分析任务。尽管在高级功能和性能优化方面有提升空间,但其简洁的 API 和完整的基础功能使其成为时间序列分析的有效工具。
80 37
Python时间序列分析工具Aeon使用指南
|
2月前
|
数据可视化 算法 数据挖掘
Python量化投资实践:基于蒙特卡洛模拟的投资组合风险建模与分析
蒙特卡洛模拟是一种利用重复随机抽样解决确定性问题的计算方法,广泛应用于金融领域的不确定性建模和风险评估。本文介绍如何使用Python和EODHD API获取历史交易数据,通过模拟生成未来价格路径,分析投资风险与收益,包括VaR和CVaR计算,以辅助投资者制定合理决策。
117 15
|
2月前
|
机器学习/深度学习 数据采集 数据挖掘
使用Python实现智能食品消费趋势分析的深度学习模型
使用Python实现智能食品消费趋势分析的深度学习模型
156 18
|
2月前
|
机器学习/深度学习 数据采集 数据挖掘
使用Python实现智能食品消费市场分析的深度学习模型
使用Python实现智能食品消费市场分析的深度学习模型
153 36

热门文章

最新文章

推荐镜像

更多