PCA(主成分分析)python实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PCA(主成分分析)python实现相关的知识,希望对你有一定的参考价值。

参考技术A

回顾了下PCA的步骤,并用python实现。深刻的发现当年学的特征值、特征向量好强大。

PCA是一种无监督的学习方式,是一种很常用的降维方法。在数据信息损失最小的情况下,将数据的特征数量由n,通过映射到另一个空间的方式,变为k(k<n)。

这里用一个2维的数据来说明PCA,选择2维的数据是因为2维的比较容易画图。
这是数据:

画个图看看分布情况:

协方差的定义为:

假设n为数据的特征数,那么协方差矩阵M, 为一个n n的矩阵,其中Mij为第i和第j个特征的协方差,对角线是各个特征的方差。
在我们的数据中,n=2,所以协方差矩阵是2
2的,
通过numpy我们可以很方便的得到:

得到cov的结果为:
array([[ 0.61655556, 0.61544444],
[ 0.61544444, 0.71655556]])

由于我们之前已经做过normalization,因此对于我们来说,
这个矩阵就是 data*data的转置矩阵。

得到结果:
matrix([[ 5.549, 5.539],
[ 5.539, 6.449]])

我们发现,其实协方差矩阵和散度矩阵关系密切,散度矩阵 就是协方差矩阵乘以(总数据量-1)。因此他们的 特征根 特征向量 是一样的。这里值得注意的一点就是,散度矩阵是 SVD奇异值分解 的一步,因此PCA和SVD是有很大联系的,他们的关系这里就不详细谈了,以后有机会再写下。

用numpy计算特征根和特征向量很简单,

但是他们代表的意义非常有意思,让我们将特征向量加到我们原来的图里:

其中红线就是特征向量。有几点值得注意:

蓝色的三角形就是经过坐标变换后得到的新点,其实他就是红色原点投影到红线、蓝线形成的。

得到特征值和特征向量之后,我们可以根据 特征值 的大小,从大到小的选择K个特征值对应的特征向量。
这个用python的实现也很简单:

从eig_pairs选取前k个特征向量就行。这里,我们只有两个特征向量,选一个最大的。

主要将原来的数据乘以经过筛选的特征向量组成的特征矩阵之后,就可以得到新的数据了。

output:

数据果然变成了一维的数据。
最后我们通过画图来理解下数据经过PCA到底发生了什么。

绿色的五角星是PCA处理过后得到的一维数据,为了能跟以前的图对比,将他们的高度定位1.2,其实就是红色圆点投影到蓝色线之后形成的点。这就是PCA,通过选择特征根向量,形成新的坐标系,然后数据投影到这个新的坐标系,在尽可能少的丢失信息的基础上实现降维。

通过上述几步的处理,我们简单的实现了PCA第一个2维数据的处理,但是原理就是这样,我们可以很轻易的就依此实现多维的。

用sklearn的PCA与我们的pca做个比较:

得到结果:

用我们的pca试试

得到结果:

完全一致,完美~
值得一提的是,sklearn中PCA的实现,用了部分SVD的结果,果然他们因缘匪浅。

PCA主成分分析Python实现

作者:拾毅者
出处:http://blog.csdn.net/Dream_angel_Z/article/details/50760130
Github源代码:https://github.com/csuldw/MachineLearning/tree/master/PCA

PCA(principle component analysis) 。主成分分析,主要是用来减少数据集的维度,然后挑选出基本的特征。原理简单,实现也简单。关于原理公式的推导,本文不会涉及,你能够參考以下的參考文献,也能够去Wikipedia,这里主要关注实现,算是锻炼一下自己。

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

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

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的本质就是对角化协方差矩阵。有必要解释下为什么将特征值按从大到小排序后再选。

首先,要明确特征值表示的是什么?在线性代数里面我们求过无数次了。那么它详细有什么意义呢?对一个n*n的对称矩阵进行分解。我们能够求出它的特征值和特征向量,就会产生n个n维的正交基,每一个正交基会相应一个特征值。

然后把矩阵投影到这N个基上,此时特征值的模就表示矩阵在该基的投影长度。

特征值越大。说明矩阵在相应的特征向量上的方差越大。样本点越离散。越easy区分,信息量也就越多。因此。特征值最大的相应的特征向量方向上所包括的信息量就越多,假设某几个特征值非常小。那么就说明在该方向的信息量非常少,我们就能够删除小特征值相应方向的数据,仅仅保留大特征值方向相应的数据,这样做以后数据量减小。但实用的信息量都保留下来了。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实现的主要内容,如果未能解决你的问题,请参考以下文章

5.7 tensorflow2实现主成分分析(PCA) ——python实战(下篇)

PCA主成分分析Python实现

[python机器学习及实践]Sklearn实现主成分分析(PCA)

PCA主成分分析 原理讲解 python代码实现

深入学习主成分分析(PCA)算法原理及其Python实现

机器学习算法-python实现PCA 主成分分析降维