PCA主成分分析实现降维

简介:

高纬度的数据不容易计算,往往需要投影到低纬空间,进行降维处理。
本章介绍一种降维方法:PCA(主成分分析)
参考链接:https://blog.csdn.net/u012421852/article/details/80458350

实现步骤

PCA降维步骤:
1.对所有样本进行中心化处理
2.计算协方差矩阵
3.求协方差的特征值和特征向量
4.将特征值按照从大到小的顺序排序,选择其中最大的k个,然后将其对应的k个特征向量分别作为列向量组成转换矩阵
5.通过低阶转换矩阵,把原矩阵转换成低维矩阵。

代码实现:

# -*- coding: utf-8 -*- 
import numpy as np
import xlrd
import tensorflow as tf

#读取表格数据,填充到矩阵作为数据集
def read_data(X):
    worksheet = xlrd.open_workbook(u'img/data.xlsx')
    sheet_names= worksheet.sheet_names()

    for sheet_name in sheet_names:
        sheet = worksheet.sheet_by_name(sheet_name)
        rows = sheet.nrows # 获取行数
        cols = sheet.ncols # 获取列数,尽管没用到
        all_content = []

        for i in range(1,rows) :
            X[i-1][0] = sheet.cell_value(i, 1) # 取第2列数据
            X[i-1][1] = sheet.cell_value(i, 2) # 取第3列数据

class PCA(object):
    def __init__(self, X, K):

        self.X = X       #样本矩阵X
        self.K = K       #K阶降维矩阵的K值
        self.centrX = [] #矩阵X的中心化
        self.C = []      #样本集的协方差矩阵C
        self.U = []      #样本矩阵X的降维转换矩阵
        self.Z = []      #样本矩阵X的降维矩阵Z
        
        self.centrX = self._centralized()
        self.C = self._cov()
        self.U = self._U()
        self.Z = self._Z()   #Z=XU求得
    
    # 1.矩阵X的中心化
    def _centralized(self):
        centrX = []
        mean = np.array([np.mean(attr) for attr in self.X.T])   #样本集的特征均值
        centrX = self.X - mean ##样本集的中心化
        print('样本集的特征均值:\n',mean)

        return centrX

    #2.求样本矩阵X的协方差矩阵C
    def _cov(self):
        #样本集的样例总数
        ns = np.shape(self.centrX)[0]
        #样本矩阵的协方差矩阵C
        C = np.dot(self.centrX.T, self.centrX)/(ns - 1)
        print('样本矩阵X的协方差矩阵C:\n', C)
        return C
      
    #3.求协方差矩阵C的特征值、特征向量
    def _U(self):
        #先求X的协方差矩阵C的特征值和特征向量
        a,b = np.linalg.eig(self.C) #特征值赋值给a,对应特征向量赋值给b 
        print('样本集的协方差矩阵C的特征值:\n', a)
        print('样本集的协方差矩阵C的特征向量:\n', b)

        #给出特征值降序的topK的索引序列
        ind = np.argsort(-1*a)

        #4.构建K阶降维的降维转换矩阵U
        UT = [b[:,ind[i]] for i in range(self.K)]   #获取最大的k个值的
        U = np.transpose(UT)    #构成一维转换矩阵
        print('%d阶降维转换矩阵U:\n'%self.K, U)
        return U
    
    #5.通过低阶转换矩阵,把原矩阵转换成低维矩阵
    def _Z(self):
        Z = np.dot(self.X, self.U)    #计算X和转换矩阵的乘积,得到降维后的矩阵
        print('样本矩阵X的降维矩阵Z:\n', Z)
        print('原矩阵的维度:', np.shape(X))
        print('降维后的维度:', np.shape(Z))
        return Z
              
if __name__=='__main__':
    #读取xlsx的数据
    X=np.zeros([50,2])     #创建一个50*20矩阵
    dataset=read_data(X)   #读取表格中的数据,放到矩阵中 

    #2维变成1K = np.shape(X)[1] - 1   #降低一维,k为得到结果的维度
    pca = PCA(X,K)     #调用PCA主函数

输入数据是一个包含两列数据的表格,读取后得到的是50 * 2的矩阵
在这里插入图片描述

得到结果:
在这里插入图片描述
可见新得到的矩阵已经变成了50*1的一阶矩阵,实现了降维。

猜你喜欢

转载自blog.csdn.net/gm_Ergou/article/details/90948368