PCA降维,即主成分分析
主要过程为:先将数据标准化,然后求协方差矩阵,接着对协方差矩阵求特征向量和特征值,这些特征向量组成了新的特征空间。
标准化的方法一般有:
- min-max
- 均值
- o-score 通过方差和均值来进行
求协方差矩阵:调用numpy中的cov方法即可计算
求特征向量和特征值:调用numpy中线性代数模块linalg中的eig函数,可以直接求得
保留主要成分:仅保留特征值前n大得维度即可
import random
import numpy as np
test_num = 20
test_vec = 5
test_data = [[random.randint(0, 100) for i in range(test_num)] for j in range(test_vec)]
class PCA:
def __init__(self, dataset):
self.dataset = dataset
self.miu = [float(sum(i)) / len(i) for i in self.dataset]
self.cov = None
def avg_normalize(self):
for j in range(len(self.dataset)):
min_x = min(self.dataset[j])
max_x = max(self.dataset[j])
for i in range(len(self.dataset[j])):
self.dataset[j][i] = (self.dataset[j][i] - self.miu[j]) / (max_x - min_x)
def min_max_normalize(self):
for j in range(len(self.dataset)):
min_x = min(self.dataset[j])
max_x = max(self.dataset[j])
for i in range(len(self.dataset[j])):
self.dataset[j][i] = (self.dataset[j][i] - min) / (max_x - min_x)
def z_score_normalize(self):
for j in range(len(self.dataset)):
std = np.std(self.dataset[j], ddof=1)
for i in range(len(self.dataset[j])):
self.dataset[j][i] = (self.dataset[j][i] - self.miu[j]) / std
# 获取协方差矩阵
def get_cov(self):
x = np.array(self.dataset)
# 当数据存储为每个记录一个list需要转制
# x = np.array(self.dataset).T
self.cov = np.cov(x)
return self.cov
def get_svd(self):
sigma, vt = np.linalg.eig(np.mat(self.cov))
return sigma, vt
def pca(self, n):
self.get_cov()
eig_vals, eig_vects = self.get_svd() # 求特征值和特征向量,特征向量是按列放的,即一列代表一个特征向量
eig_val_indice = np.argsort(eig_vals) # 对特征值从小到大排序
n_eig_val_indice = eig_val_indice[-1:-(n + 1):-1] # 最大的n个特征值的下标
n_eig_vect = eig_vects[:, n_eig_val_indice] # 最大的n个特征值对应的特征向量
low_d_data_mat = np.mat(self.dataset).T * n_eig_vect # 低维特征空间的数据
recon_mat = (low_d_data_mat * n_eig_vect.T) # 重构数据
return low_d_data_mat, recon_mat
pca = PCA(test_data)
pca.avg_normalize()
print(pca.pca(2))