美文网首页Data structure
PCA降维算法的python实现

PCA降维算法的python实现

作者: 朱小狗儿 | 来源:发表于2016-08-20 17:09 被阅读2393次

    主成分分析(PCA)是一种无监督的学习方式,是一种常用的线性降维方法。如果遇到多因素分析,想要很多个自变量与因变量进行线性回归分析,一般都必须进行降维处理,而主成分分析是一种很好的解决方案。

    一、PCA简介
    PCA是将数据的n维特征映射到k维上(k<n),k维是全新的正交特征。这里的k维是重新构造出来的k维特征,而不是简单的从n维特征中找出k维。
    PCA求解的一般流程为:
    (1)将原始数据进行标准化;
    (2)计算标准化数据集的协方差矩阵;
    (3)计算协方差矩阵的特征值和特征向量;
    (4)保留最重要的k个特征(k<n),可以选择一个阈值,让前k个特征值之和减去后面n-k个特征值之和大于这 个阈值,找到这个k值,计算主成分变量值;
    (5)找到这k个特征值对应的特征向量;
    (6)将m乘n的数据集乘以k个n维的特征向量(n乘k),得到最终降维的数据集;
    其实PCA的本质就是对角化协方差矩阵,解释一下为什么将特征值按照从大到小排序后再选择。首先解释一下特征值和特征向量表示什么。在线性代数中,对一个n*n的对称矩阵进行分解,我们可以求出它的特征值和特征向量,就会产生n个n维的正交基,每个正交基会对应一个特征值。然后把矩阵投影到这n个正交基上,此时特征值的模就表示矩阵在该基的投影长度。特征值越大,表示矩阵在对应的特征向量上的方差越大,样本越离散,越容易区分,信息量也越多。因此,特征值最大的对应的特征向量方向上所包含的信息量就越多。如果某几个特征值很小,那么说明在该方向上的信息量非常少,我们就可以删除小特征值所对应方向的数据,只保留大特征值方向对应的数据,这样做以后数据量越小,但是有用的信息量都保留下来了。

    二、PCA的python实现
    矩阵运算需要用到numpy包以及numpy包中的genfromtxt函数,这个函数是可以读取csv文件;还需要用到matplotlib进行画图

    import numpy as np
    from numpy import genfromtxt
    import matplotlib.pyplot as plt
    

    读取csv文件程序:

    dataPath = r"D:\python\data.csv"
    dataMat = genfromtxt(dataPath, delimiter=',')
    

    设计pca函数

    def pca(dataMat, k):
        average = np.mean(dataMat, axis=0) #按列求均值
        m, n = np.shape(dataMat)
        meanRemoved = dataMat - np.tile(average, (m,1)) #减去均值
        normData = meanRemoved / np.std(dataMat) #标准差归一化
        covMat = np.cov(normData.T)  #求协方差矩阵
        eigValue, eigVec = np.linalg.eig(covMat) #求协方差矩阵的特征值和特征向量
        eigValInd = np.argsort(-eigValue) #返回特征值由大到小排序的下标
        selectVec = np.matrix(eigVec.T[:k]) #因为[:k]表示前k行,因此之前需要转置处理(选择前k个大的特征值)
        finalData = normData * selectVec.T #再转置回来
        return finalData
    

    我们可以得到最终的结果

    finalData = pca(dataMat, 2)
    plt.scatter(dataMat.T[:1],dataMat.T[1:], color='red', s=20)
    plt.scatter(finalData.T[:1],finalData.T[1:], color='blue', s=20)
    plt.show()
    plt.close()
    

    结果如下:

    如果我们不直接给出需要的前k个主成分,而是编程前k个主成分占总体90%确定k,程序如下:

    def setK(eigValue, rate):
        eigValInd = np.argsort(-eigValue) #返回特征值由大到小排序的下标值
        for i in range(1, eigValue.size+1):
            topK = eigValInd[i-1]
            eigVal = eigValue[topK]
            a = eigVal.sum()
            b = eigValue.sum()
            if a/b >= rate:
                break
        return i
    

    此时,修改两个地方:

    finalData = pca(dataMat, rata)
    k = setK(eigValInd, rata)
    

    之后就完成了主成分分析

    相关文章

      网友评论

        本文标题:PCA降维算法的python实现

        本文链接:https://www.haomeiwen.com/subject/rpobsttx.html