PCA (Principal Component Analysis, 主成分分析), 把数据从原来的坐标系转换到新的坐标系, 新坐标系的选择由数据本身决定. 第一个新坐标轴选择的是原始数据中方差最大的方向, 第二个新坐标轴选择和第一个坐标轴正交且具有最大方差的方向. 此过程一直重复, 重复次数为原始数据中特征的数目. 我们会发现, 大部分方差都包含在最前面的几个新坐标轴中. 因此, 我们可以忽略余下的坐标轴, 即对数据进行了降维处理.
优点 | 降低数据的复杂性, 识别最重要的多个特征 |
缺点 | 不一定需要, 且可能损失有用信息 |
适用数据类型 | 数值型 |
以下举例来自:
对于一个训练集,100个对象模板,特征是10维,那么它可以建立一个100*10的矩阵,作为样本。求这个样本的协方差矩阵,得到一个10*10的协方差矩阵,然后求出这个协方差矩阵的特征值和特征向量,应该有10个特征值和特征向量,我们根据特征值的大小,取前四个特征值所对应的特征向量,构成一个10*4的矩阵,这个矩阵就是我们要求的特征矩阵,100*10的样本矩阵乘以这个10*4的特征矩阵,就得到了一个100*4的新的降维之后的样本矩阵,每个特征的维数下降了。 当给定一个测试的特征集之后,比如1*10维的特征,乘以上面得到的10*4的特征矩阵,便可以得到一个1*4的特征,用这个特征去分类。
基础概念
1. 特征值 ()
如果说一个向量 v 是方阵 A 的特征向量, 则一定可以表示成下面的形式:这时候 λ 就被称为特征向量 v 对应的特征值, 一个矩阵的一组特征向量是一组正交向量.2. 特征值分解 ()
特征值分解可以得到特征值和特征向量, 特征值表示的是这个特征到底有多得要, 而特征向量表示的是这个特征是什么, 可以将每一个特征向量理解为一个线性的子空间. 特征值分解将一个矩阵分解成下面的形式:特征值分解的局限在于变换的矩阵必须是方阵.算法说明
1. PCA实际上是求一个投影矩阵, 用高维的特征乘以这个投影矩阵, 便可以将高维特征的维数下降到指定的维数.2. PCA 的核心思想: 由于特征值能够表示数据集的重要特征, 所以在求出所有特征值后, 按从特征值大到小进行排列, 然后按输出参数取前 N 个特征值进行矩阵变换(代码 23-29 行), 即可在最大化保持数据信息的前提下进行降维.
3. 通俗的理解, 如果把所有的点都映射到一起, 那么几乎所有的信息(如点和点之间的距离关系)都丢失了, 而如果映射后方差尽可能的大, 那么数据点则会分散开来, 以此来保留更多的信息. 可以证明, PCA是丢失原始数据信息最少的一种线性降维方式. (实际上就是最接近原始数据, 但是PCA并不试图去探索数据内在结构)
算法流程图
代码
# -*- coding: utf-8 -* from numpy import *# 载入数据, 默认以 tab 分隔数据def loadDataSet(fileName, delim='\t'): fr = open(fileName) stringArr = [line.strip().split(delim) for line in fr.readlines()] datArr = [map(float,line) for line in stringArr] # 数据转成 float return mat(datArr)# PCA 主函数# 参数 topNfeat 指应用的 N 个特征, 需降完维后还剩 topNfeat 维def pca(dataMat, topNfeat=9999999): meanVals = mean(dataMat, axis=0) meanRemoved = dataMat - meanVals # 移除平均值 # 计算协方差及特征值, 按特征值从小到大排列 covMat = cov(meanRemoved, rowvar=0) eigVals,eigVects = linalg.eig(mat(covMat)) # eig 求解特征向量和特征值 eigValInd = argsort(eigVals) # 取前 topNfeat 个最大的特征值, 并构成特征矩阵 eigValInd = eigValInd[:-(topNfeat+1):-1] redEigVects = eigVects[:,eigValInd] # 将数据转换到新空间 lowDDataMat = meanRemoved * redEigVects reconMat = (lowDDataMat * redEigVects.T) + meanVals return lowDDataMat, reconMatif __name__ == "__main__": dataMat = loadDataSet('testSet.txt') print dataMat lowDMat, reconMat = pca(dataMat, 1) # 显示 import matplotlib.pyplot as plt fig = plt.figure() ax = fig.add_subplot(111) ax.scatter(dataMat[:,0].flatten().A[0], dataMat[:,1].flatten().A[0], marker='^', s=90) ax.scatter(reconMat[:,0].flatten().A[0], reconMat[:,1].flatten().A[0], marker='o', s=50, c='red') plt.show()
运行结果
说明
本文为《Machine Leaning in Action》第十三章(Using principal component analysis to simplify data)读书笔记, 代码稍作修改及注释.好文参考
1.《》2.《》3.《》4.《》