Python使用三种方法实现PCA算法


Posted in Python onDecember 12, 2017

主成分分析,即Principal Component Analysis(PCA),是多元统计中的重要内容,也广泛应用于机器学习和其它领域。它的主要作用是对高维数据进行降维。PCA把原先的n个特征用数目更少的k个特征取代,新特征是旧特征的线性组合,这些线性组合最大化样本方差,尽量使新的k个特征互不相关。关于PCA的更多介绍,请参考:https://en.wikipedia.org/wiki/Principal_component_analysis.

主成分分析(PCA) vs 多元判别式分析(MDA)

PCA和MDA都是线性变换的方法,二者关系密切。在PCA中,我们寻找数据集中最大化方差的成分,在MDA中,我们对类间最大散布的方向更感兴趣。

一句话,通过PCA,我们将整个数据集(不带类别标签)映射到一个子空间中,在MDA中,我们致力于找到一个能够最好区分各类的最佳子集。粗略来讲,PCA是通过寻找方差最大的轴(在一类中,因为PCA把整个数据集当做一类),在MDA中,我们还需要最大化类间散布。

在通常的模式识别问题中,MDA往往在PCA后面。

PCA的主要算法如下:

  1. 组织数据形式,以便于模型使用;
  2. 计算样本每个特征的平均值;
  3. 每个样本数据减去该特征的平均值(归一化处理);
  4. 求协方差矩阵;
  5. 找到协方差矩阵的特征值和特征向量;
  6. 对特征值和特征向量重新排列(特征值从大到小排列);
  7. 对特征值求取累计贡献率;
  8. 对累计贡献率按照某个特定比例,选取特征向量集的字迹合;
  9. 对原始数据(第三步后)。

其中协方差矩阵的分解可以通过按对称矩阵的特征向量来,也可以通过分解矩阵的SVD来实现,而在Scikit-learn中,也是采用SVD来实现PCA算法的。

本文将用三种方法来实现PCA算法,一种是原始算法,即上面所描述的算法过程,具体的计算方法和过程,可以参考:A tutorial on Principal Components Analysis, Lindsay I Smith. 一种是带SVD的原始算法,在Python的Numpy模块中已经实现了SVD算法,并且将特征值从大从小排列,省去了对特征值和特征向量重新排列这一步。最后一种方法是用Python的Scikit-learn模块实现的PCA类直接进行计算,来验证前面两种方法的正确性。

用以上三种方法来实现PCA的完整的Python如下:

import numpy as np
from sklearn.decomposition import PCA
import sys
#returns choosing how many main factors
def index_lst(lst, component=0, rate=0):
  #component: numbers of main factors
  #rate: rate of sum(main factors)/sum(all factors)
  #rate range suggest: (0.8,1)
  #if you choose rate parameter, return index = 0 or less than len(lst)
  if component and rate:
    print('Component and rate must choose only one!')
    sys.exit(0)
  if not component and not rate:
    print('Invalid parameter for numbers of components!')
    sys.exit(0)
  elif component:
    print('Choosing by component, components are %s......'%component)
    return component
  else:
    print('Choosing by rate, rate is %s ......'%rate)
    for i in range(1, len(lst)):
      if sum(lst[:i])/sum(lst) >= rate:
        return i
    return 0

def main():
  # test data
  mat = [[-1,-1,0,2,1],[2,0,0,-1,-1],[2,0,1,1,0]]
  
  # simple transform of test data
  Mat = np.array(mat, dtype='float64')
  print('Before PCA transforMation, data is:\n', Mat)
  print('\nMethod 1: PCA by original algorithm:')
  p,n = np.shape(Mat) # shape of Mat 
  t = np.mean(Mat, 0) # mean of each column
  
  # substract the mean of each column
  for i in range(p):
    for j in range(n):
      Mat[i,j] = float(Mat[i,j]-t[j])
      
  # covariance Matrix
  cov_Mat = np.dot(Mat.T, Mat)/(p-1)
  
  # PCA by original algorithm
  # eigvalues and eigenvectors of covariance Matrix with eigvalues descending
  U,V = np.linalg.eigh(cov_Mat) 
  # Rearrange the eigenvectors and eigenvalues
  U = U[::-1]
  for i in range(n):
    V[i,:] = V[i,:][::-1]
  # choose eigenvalue by component or rate, not both of them euqal to 0
  Index = index_lst(U, component=2) # choose how many main factors
  if Index:
    v = V[:,:Index] # subset of Unitary matrix
  else: # improper rate choice may return Index=0
    print('Invalid rate choice.\nPlease adjust the rate.')
    print('Rate distribute follows:')
    print([sum(U[:i])/sum(U) for i in range(1, len(U)+1)])
    sys.exit(0)
  # data transformation
  T1 = np.dot(Mat, v)
  # print the transformed data
  print('We choose %d main factors.'%Index)
  print('After PCA transformation, data becomes:\n',T1)
  
  # PCA by original algorithm using SVD
  print('\nMethod 2: PCA by original algorithm using SVD:')
  # u: Unitary matrix, eigenvectors in columns 
  # d: list of the singular values, sorted in descending order
  u,d,v = np.linalg.svd(cov_Mat)
  Index = index_lst(d, rate=0.95) # choose how many main factors
  T2 = np.dot(Mat, u[:,:Index]) # transformed data
  print('We choose %d main factors.'%Index)
  print('After PCA transformation, data becomes:\n',T2)
  
  # PCA by Scikit-learn
  pca = PCA(n_components=2) # n_components can be integer or float in (0,1)
  pca.fit(mat) # fit the model
  print('\nMethod 3: PCA by Scikit-learn:')
  print('After PCA transformation, data becomes:')
  print(pca.fit_transform(mat)) # transformed data      
main()

运行以上代码,输出结果为:

Python使用三种方法实现PCA算法

这说明用以上三种方法来实现PCA都是可行的。这样我们就能理解PCA的具体实现过程啦~~有兴趣的读者可以用其它语言实现一下哈

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python Mysql数据库操作 Perl操作Mysql数据库
Jan 12 Python
python实现文件名批量替换和内容替换
Mar 20 Python
最基础的Python的socket编程入门教程
Apr 23 Python
详细解读Python的web.py框架下的application.py模块
May 02 Python
在Python中操作文件之truncate()方法的使用教程
May 25 Python
Python文件右键找不到IDLE打开项解决办法
Jun 08 Python
python爬虫获取多页天涯帖子
Feb 23 Python
pandas groupby 分组取每组的前几行记录方法
Apr 20 Python
Python 解决中文写入Excel时抛异常的问题
May 03 Python
Python底层封装实现方法详解
Jan 22 Python
Tensorflow 定义变量,函数,数值计算等名字的更新方式
Feb 10 Python
Keras 在fit_generator训练方式中加入图像random_crop操作
Jul 03 Python
Java分治归并排序算法实例详解
Dec 12 #Python
Python数据结构与算法之二叉树结构定义与遍历方法详解
Dec 12 #Python
Python数据结构与算法之图的基本实现及迭代器实例详解
Dec 12 #Python
Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
Dec 12 #Python
你真的了解Python的random模块吗?
Dec 12 #Python
Python判断两个对象相等的原理
Dec 12 #Python
浅谈Django REST Framework限速
Dec 12 #Python
You might like
Apache中php.ini的设置方法
2013/02/28 PHP
ThinkPHP3.1新特性之G方法的使用
2014/06/19 PHP
ThinkPHP发送邮件示例代码
2016/10/08 PHP
用JavaScript实现类似于ListBox功能示例代码
2014/03/09 Javascript
jQuery CSS()方法改变现有的CSS样式表
2014/09/09 Javascript
用C/C++来实现 Node.js 的模块(一)
2014/09/24 Javascript
JavaScript函数参数使用带参数名的方式赋值传入的方法
2015/03/19 Javascript
jQuery实现提交按钮点击后变成正在处理字样并禁止点击的方法
2015/03/24 Javascript
整理Javascript数组学习笔记
2015/11/29 Javascript
jquery遍历函数siblings()用法实例
2015/12/24 Javascript
实例讲解JavaScript中call、apply、bind方法的异同
2016/09/13 Javascript
JS判断两个对象内容是否相等的方法示例
2017/04/10 Javascript
详解基于vue的移动web app页面缓存解决方案
2017/08/03 Javascript
jQuery创建及操作xml格式数据示例
2018/05/26 jQuery
js数据类型检测总结
2018/08/05 Javascript
在vue中利用v-html按分号将文本换行的例子
2019/11/14 Javascript
JSONP 的原理、理解 与 实例分析
2020/05/16 Javascript
Element DateTimePicker日期时间选择器的使用示例
2020/07/27 Javascript
vue 使用localstorage实现面包屑的操作
2020/11/16 Javascript
[02:03]《现实生活中的DOTA2》—林书豪&DOTA2职业选手出演短片
2015/08/18 DOTA
在IIS服务器上以CGI方式运行Python脚本的教程
2015/04/25 Python
Python中最大递归深度值的探讨
2019/03/05 Python
解决python中用matplotlib画多幅图时出现图形部分重叠的问题
2019/07/07 Python
tensorflow之自定义神经网络层实例
2020/02/07 Python
小学运动会广播稿200字(十二篇)
2014/01/14 职场文书
医药个人求职信范文
2014/01/29 职场文书
敬老院院长事迹材料
2014/05/21 职场文书
优秀毕业生的求职信
2014/07/21 职场文书
学雷锋团日活动总结
2015/05/06 职场文书
自信主题班会
2015/08/14 职场文书
初中生物教学反思
2016/02/20 职场文书
Python爬虫之爬取最新更新的小说网站
2021/05/06 Python
教你如何使用Python Tkinter库制作记事本
2021/06/10 Python
利用Python判断整数是否是回文数的3种方法总结
2021/07/07 Python
CSS Transition通过改变Height实现展开收起元素
2021/08/07 HTML / CSS
 python中的元类metaclass详情
2022/05/30 Python