在进行数据处理时,有可能会遇到数据属性的数量要比每种数据的数据量还要多,甚至相当,而且对于这些不同属的数据所描述的信息有重合的时候,这时候需要对数据进行降维处理,来减少数据处理的维度。一句话来说就是当我们对一个对象进行数据分析时,所获得的数据的属性很多,为了减少数据处理的维度,我们可以通过计算出几个主要因素来代表这些数据,主成分分析可以做到这点。
比如说衡量一个人的智商,我们要综合其个方面因素来评价,数学成绩,语文成绩,英语成绩,各种成绩,但是我们可以选出数学成绩,理科成绩来衡量他的智商,虽然不能代表全部,但是可以代表大部分。
概述
主要参考《机器学习实战》,书中的介绍十分详细清楚,这里只记录代码实现以及分析数据的过程。
主成分分析实现要解决两个问题,降维度降到多少可以很好的表达原始数据,如何获得降维后的数据。
将多少维度
在确定降多少维度之前我们需要对数据进行标准化:
加载数据,同时进行数据预处理:
import numpy as np
from matplotlib import pyplot as plt
import os
from sklearn import preprocessing
from pprint import pprint
def load_data():
data = []
with open('./test_pca.txt') as f:
data = [list(map(float, item.strip().split())) for item in f.readlines()]
# data = map(int, data)
return np.mat(data)
def pca_analysis(dataMat):
# 数据标准化
meanMat = np.mean(dataMat, axis=0)
removMat = dataMat - meanMat
stdMat = np.std(dataMat, axis=0)
scaleMat = removMat / stdMat
# print(preprocessing.scale(dataMat))
数据集:
1798.96 27982 123.25 600.71 736.88 865.606 223.77 41.492 115.92 421.61
605.27 16526 75.53 270.64 107.53 208.494 55.08 20140 34.85 105.04
422.08 15455 60.66 165.81 75.23 130.658 135.41 13559 25.85 75.51
672.07 10057 158.10 246.71 132.58 231.085 252.47 34419 39.85 128.67
409.51 6106 118.34 103.97 69.29 135.992 81.30 24865 32.25 84.87
733.40 14331 134.42 318.38 82.51 245.837 134.30 17382 37.28 117.74
723.84 13338 177.51 265.44 69.09 235.943 131.45 19926 39.30 91.73
127.54 8627 20.92 21.94 11.54 42.1407 83.94 5766 11.85 33.42
336.21 8082 89.19 87.70 37.48 131.507 56.06 12128 25.57 82.19
546.23 12517 86.49 248.15 32.23 204.36 102.16 40937 34.87 114.22
414.55 8103 119.50 93.30 29.81 117.264 106.71 17649 24.79 67.43
359.12 9330 63.23 157.85 37.52 110.387 40.80 18405 22.85 66.01
可以使用numpy手动标准化,也可以调用sklearn的函数
在获得标准化数据之后,通过求改矩阵的协方差矩阵的特征值来确定降维度的维数。通过计算特征值所占全部特征值的百分比(贡献率)来确定降维度的维数,以及那组数据为轴进行正交,一般选取的数据属性所占贡献率总和超过80%即可。
# 求协方差矩阵
covMat = np.cov(scaleMat, rowvar=False)
# print(covMat)
# 求特征值和特征向量
eigVals, eigVects = np.linalg.eig(covMat)
# pprint((eigVals, eigVects))
# 计算特征贡献率
conRate = 100 * eigVals / eigVals.sum()
# print(conRate)
plt.figure()
plt.plot(np.arange(1, 11), conRate)
plt.show()
通过图像可以观察出我们选取两个主成分即可,我们选取贡献率最大的两个特征向量作为两个主成分线性表示的系数。
获取降维的数据
上一部分我们已经通过计算特征值来确定要降的维数,同时我们还获得了相应的两种主成分由十个原数据的线性表出的系数,也就是两个特征值对应的特征向量,我们只需要将数据线性表出便可以获得降维的数据。
# 降维到2维
eigInd = np.argsort(eigVals)
eigInd = eigInd[:-3:-1]
redEigVects = eigVects[:, eigInd]
lowDDate = scaleMat * redEigVects
pprint((redEigVects, lowDDate))
来源:CSDN
作者:很重的水
链接:https://blog.csdn.net/weight_water/article/details/104110042