python3原生实现pca降维
经过一段时间学习线性代数了解了pca降维的计算方法,下面直接上代码,大致步骤,计算矩阵A的协方差,然后计算A的特征值和对应特征值的特征向量,特征值的大小就是主成分的重要程度,然后选取前K个最大特征值的特征向量,然后再和协方差相乘 就得到了降维后的数据:
from sklearn.decomposition import PCA
from sklearn.datasets import load_iris
from sklearn import svm,datasets
import sys
from numpy.random import shuffle
import pandas as pd
from sklearn import metrics
from sklearn.linear_model import LogisticRegression as LR
from numpy import *
import numpy
class iris():
def eigValPct(self,eigVals,percentage):
sortArray=sort(eigVals) #使用numpy中的sort()对特征值按照从小到大排序
sortArray=sortArray[-1::-1] #特征值从大到小排序
arraySum=sum(sortArray) #数据全部的方差arraySum
tempSum = 0
num = 0
for i in sortArray:
tempSum+=i
num+=1
if tempSum>=arraySum*percentage:
return num
'''pca函数有两个参数,其中dataMat是已经转换成矩阵matrix形式的数据集,列表示特征;
其中的percentage表示取前多少个特征需要达到的方差占比,默认为0.9'''
def pca(self,data):
dataMat = pd.DataFrame(data.data)
meanVals = mean(dataMat,axis=0) #对每一列求平均值,因为协方差的计算中需要减去均值
meanRemoved = (dataMat - meanVals)
covMat = cov(meanRemoved,rowvar=0) #cov()计算方差
eigVals,eigVects = linalg.eig(mat(covMat)) #利用numpy中寻找特征值和特征向量的模块linalg中的eig()方法
# k = self.eigValPct(eigVals,percentage) #要达到方差的百分比percentage,需要前k个向量
#
# eigValInd = argsort(eigVals) #对特征值eigVals从小到大排序
#
# eigValInd = eigValInd[:-(k+1):-1] #从排好序的特征值,从后往前取k个,这样就实现了特征值的从大到小排列
redEigVects = pd.DataFrame(eigVects[:,0]) #这里为了对比函数降维eigVects[:,0]表示只取最大的特征值对应的特征向量
lowDDataMat = numpy.array(meanRemoved)*numpy.array(redEigVects.T) #将原始数据投影到主成分上得到新的低维数据lowDDataMat
print('自编写降维:')
print(sum(lowDDataMat,axis=1).reshape(len(lowDDataMat),1))
# reconMat = (lowDDataMat*redEigVects.T)+meanVals #得到重构数据reconMat
#
# return lowDDataMat,reconMat
#通过PCA降维选取特征
def PCA_T(self,data):
y = data.target
x = data.data
#查看每个特征的贡献率
pca = PCA()
pca.fit(x)
# print(pca.explained_variance_ratio_)
# [0.92461621 0.05301557 0.01718514 0.00518309]
# 可以看见前面两个主成分占了相当大的成分,所以我们就降成2维
pca = PCA(2)
pca.fit(x)
low_d = pca.transform(x)
print('函数降维:')
print(low_d)
# self.LMTwo(low_d,y)
if __name__=='__main__':
data = load_iris()
iris = iris()
#原生编写pca算法
iris.pca(data)
#利用pca函数
iris.PCA_T(data)