使用PCA对数据集进行降维
一、实验准备
1、实验内容和目的
-
使用主成分分析(PCA)对鸢尾花数据集进行降维操作,其中要求绘制出降维后的数据分布散点图并说明降维后的维度,提取的主成分的特征值
-
其中数据集文件为iris.data.txt。数据集中的每个样本有4个特征参数,最后的标签为鸢尾花的类别
2、实验原理
-
前面学习到了KNN分类算法,然后使用KNN算法进行鸢尾花的分类。分类时,虽然将数据集中的所有特征都纳入了考虑范围,都参与了计算,但由于只有4个特征,并不会明显地加大计算的复杂程度。但如果处理别的数据集时,假如此时的样本拥有成百上千个特征,还会一样的轻松吗?
-
想象这样一种场景:我们正通过电视而非现场观看体育比赛,在电视上的纯平显示器上有一个球。显示器大概包含了100万像素,而球则可能是由较少的像素组成的,比如说一千个像素。在大部分体育比赛中,我们关注的是给定时刻球的位置。人的大脑要想了解比赛的进展,就需要了解球在运动场中的位置。对于人来说,这一切显得十分自然,甚至都不需要做任何思考。在这个场景当中,人们实时地将显示器上的百万像素转换成为了一个三维图像,该图像就给出了运动场上球的位置。在这个过程中,人们已经将数据从一百万维降至了三维
-
在上述体育比赛的例子中,人们面对的原本是百万像素的数据,但是只有球的三维位置才最重要,这就称作降维。在低维下,数据更容易进行处理。另外,其相关特征可能在数据中明确地显示出来
-
降维就是对高维度特征的一种预处理方法,它将高维度的数据保留下最重要的一些特征,去除噪声和不重要的特征,从而实现提升数据处理速度的目的。在实际的生产和应用当中,降维在一定的信息损失范围内,可以为我们节省大量的时间和成本。降维也成为了应用非常广泛的数据预处理方法
-
主成分分析(PCA)就是一种降维技术,它通过正交变换把可能线性相关的变量转换为几乎线性无关的变量,这些变量就是所谓的“主成分”
2.1 PCA的工作原理
-
在PCA中,数据从原来的坐标系转换到新的坐标系,由数据本身决定。转换坐标系时,以方差最大的方向作为坐标轴方向,因为数据的最大方差给出了数据的最重要信息。第一个新坐标轴选择的是原始数据中方差最大的方向,第二个新坐标轴选择的是与第一个新坐标轴正交且方差次大的方向。重复该过程,重复次数为原始数据的特征维数
-
通过这种方式获得的新的坐标系,大部分方差都包含在前面几个坐标轴中,后面的坐标轴所含的方差几乎为0。于是,我们可以忽略余下的坐标轴,只保留前面的几个含有绝大部份方差坐标轴。事实上,这样也就相当于只保留包含绝大部分方差的维度特征,而忽略包含方差几乎为0的特征维度,也就实现了对数据特征的降维处理
2.2 计算协方差矩阵
-
PCA的原理已经知道了,那么我们如何得到这些包含最大差异性的主成分方向呢?事实上,通过计算数据矩阵的协方差矩阵,然后得到协方差矩阵的特征值及特征向量,选择特征值最大(也即包含方差最大)的N个特征所对应的特征向量组成的矩阵,我们就可以将数据矩阵转换到新的空间当中,实现数据特征的降维
-
这里说一下方差和协方差之间的关系,首先看一下均值、方差和协方差的计算公式:
-
由上面的公式,我们可以得到以下两点:
-
方差的计算针对一维特征,即针对同一特征不同样本的曲直来进行计算得到;而协方差则必须要求至少满足二维特征
-
方差和协方差的除数是 N-1,这样是为了得到方差和协方差的无偏估计
-
二、进行实验
1、算法思路
- 在第一部分中已经详细地说明了PCA的工作原理以及具体的实现方法,即为算法思路
2、算法步骤
-
(1) 对数据集进行处理,提出每个样本的特征参数集
-
(2) 将特征参数集组织成 行 列的矩阵
-
(3) 进行零均值化
-
(4) 求出协方差矩阵
-
(5) 求出协方差矩阵的特征值以及对应的特征向量
-
(6) 将特征向量按照对应的特征值大小进行排序,然后取前k列组成矩阵
-
(7) 矩阵 是 行 列的矩阵,矩阵 是 行 列的矩阵
-
(8) 即为降维到 维后的数据矩阵
3、代码实现
-
注:由于这次实验对应的OJ题目要求提交代码进行评测,而OJ题目有一些具体的输入输出要求,所以我实现的代码就不基于使用本地的数据文件,最后实现的效果和绘制的散点图均具体进行描述
-
具体的功能实现在代码中的注释均进行了详细说明
#!/usr/bin/python
# -*- coding utf-8 -*-
# Project: PCA
# Author: jiangnan
# Mail: [email protected]
# Date: 2018/10/27
import numpy as np
def loadDataSet():
"""
函数说明:
处理数据集的输入,将其进行处理后以矩阵的形式返回
:return:
np.mat(stringArr) - 矩阵形式的数据集
"""
stringArr = []
for i in range(m):
line = input().split(',') #输入的数据以逗号分隔,以此进行分词
tempArr = []
for j in line:
tempArr.append(float(j)) #转换为float类型
stringArr.append(tempArr)
return np.mat(stringArr) #返回数据矩阵
def pca():
"""
函数说明:
对数据集进行PCA操作
"""
meanVals = np.mean(dataMat, axis=0)
meanRemoved = dataMat - meanVals #零均值化
covMat = np.cov(meanRemoved, rowvar=0) #求协方差矩阵
eigVals, eigVects = np.linalg.eig(np.mat(covMat)) #求特征值和特征向量
eigValInd = np.argsort(eigVals) #对特征值的下标进行排序操作
eigValInd_re = eigValInd[: -(k + 1): -1] #取出最大的k个特征值
for i in eigValInd_re: #根据OJ的要求,输出特征值
print(eigVals[i], end=' ')
print()
eigValInd = reversed(eigValInd)
for i in eigValInd: #根据OJ的要求,输出特征向量
for j in range(k):
print(eigVects[i, j], end=' ')
print()
redEigVects = eigVects[: ,eigValInd_re]
lowDDataMat = meanRemoved * redEigVects #计算获得降维到k维后的数据矩阵
for i in range(m): #根据OJ的要求,输出降维后的数据矩阵
for j in range(k):
print(lowDDataMat[i, j], end=' ')
print()
m, n, k = map(int, input().split()) #m和n标示输入数据的行和列,k标示降至k维
dataMat = loadDataSet()
pca()
3、实现效果
3.1 OJ测评结果
3.2 绘制散点图
- (1) 绘制一维图
- (2) 绘制二维图
- (3) 使用PCA降至3维
4、总结
-
大致总结了PCA(主成分分析)的优缺点:
-
优点:降低数据的复杂性,识别最重要的多个特征
-
缺点:可能损失有用信息
-