简介:
高纬度的数据不容易计算,往往需要投影到低纬空间,进行降维处理。
本章介绍一种降维方法: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*2的0矩阵
dataset=read_data(X) #读取表格中的数据,放到矩阵中
#2维变成1维
K = np.shape(X)[1] - 1 #降低一维,k为得到结果的维度
pca = PCA(X,K) #调用PCA主函数
输入数据是一个包含两列数据的表格,读取后得到的是50 * 2的矩阵
得到结果:
可见新得到的矩阵已经变成了50*1的一阶矩阵,实现了降维。
代码实现2:sklearn调用
# -*- coding: utf-8 -*-
import numpy as np
import xlrd
import tensorflow as tf
import numpy as np
from sklearn.decomposition import PCA
#读取表格数据,填充到矩阵作为数据集
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列数据
# # 1.手动输入数据
# X = np.array([[10, 15],
# [15, 46],
# [23, 21],
# [11, 9],
# [42, 45],
# [9, 48],
# [11, 21],
# [8, 5],
# [11, 12],
# [21, 20]])
#2.读取xlsx的数据
X=np.zeros([50,2]) #创建一个50*2的0矩阵
dataset=read_data(X) #读取表格中的数据,放到矩阵中
pca = PCA(n_components='mle') #'mle':将自动选取特征个数n; 或者自己选择1、2、3...
newX = pca.fit_transform(X) #等价于pca.fit(X)-训练 + pca.transform(X)-将数据X转换成降维后的数据
# invX = pca.inverse_transform(X) #将降维后的数据转换成原始数据
# print(X)
print(newX,newX.shape)
print(pca.explained_variance_ratio_)
# 1.components_:返回具有最大方差的成分。
# 2.explained_variance_ratio_:返回 所保留的n个成分各自的方差百分比。
# 3.n_components_:返回所保留的成分个数n。
# # 4.pca对象的n_components值为2,即保留2个特征,第一个特征占所有特征的方差百分比为0.99244289,
# # 意味着几乎保留了所有的信息。即第一个特征可以99.24%表达整个数据集,因此我们可以降到1维