本文主要讲机器学习中的一种数据处理方法,主成分分析(Principal components analysis)。
记2018年的乌兰布统之游
(翻看相册配图发现2018年拍的这张张片好美,可以做壁纸了呢!)
算法简介:
主成分分析是数据挖掘中常用的一种降维算法,最早是Pearson在1901年提出,随着发展到后来Hotelling在1933年正式提出的一种多变量的统计方法。
其主要用途在于“降维”,即通过分析取主成分表现出的最大的个别差异,在机器学习中用来削减回归分析和聚类分析中变量的数目,类似于因子分析。降维就是把具有相关性的变量数目减少,用较少的变量来取代原先变量。
本文主要实现基于Python的PCA代码实现方法和流程,采用的数据集为Github上的原始数据。代码全文均有各个步骤的注释说明,特别适合于刚入机器学习的同学练习。
PCA实现主要步骤:
(1)调试数据集下载:
链接:https://github.com/zhangqingfeng0105/MachineLearn/blob/master/PCA_data_set/pca_data_set1.txt
https://github.com/zhangqingfeng0105/MachineLearn/blob/master/PCA_data_set/pca_data_set2.txt
(2)算法流程
① 对原数据集零均值化。代码:
meanRemoved = dataMat - mean(dataMat,axis=0)
② 求出均值化X的协方差矩阵:公式是:
Cov(X)=frac{1}{m-1}X^{T}X,代码:covMat = cov(meanRemoved,rowvar=0)
③ 求这个协方差矩阵的特征值,特征向量,代码:
eigVals, eigVects = linalg.eig(mat(covMat))
④ 把这些特征值按从大到小排列,返回特征值的下标,代码:
eigValInd = argsort(-eigVals)
⑤ 选出前topNfeat个特征值,返回这些选中的特征值的下标,并根据下标从特征向量矩阵eigVects中取出这些选中的特征向量组成矩阵P,这就是我们要找的变换矩阵P,代码:
redEigVects = eigVects[:,eigValInd[:topNfeat] ]
⑥ 返回降维后的数据,公式是:Y=X•P,代码:
lowDDataMat = meanRemoved * redEigVects
⑦ 原数据映射到新的空间中。公式及代码:
X^{'}=Ycdot P^{T}+mean
reconMat = (lowDDataMat * redEigVects.T) + meanValues
代码样例:
# @Author : quan# @Software : PyCharmfrom numpy import *import matplotlib.pyplot as pltdef loadDataSet(filename): dataSetList = [] fr = open(filename) for row in fr.readlines(): cur_line = row.strip().split("") #去掉数据中的空格 # print(cur_line) proce_line = list(map(float,cur_line)) #格式化 dataSetList.append(proce_line) #创建数据集 dataSetList = array(dataSetList) #数据集转换为数组 return dataSetListdef Pca(dataMat,topNfeat = 999999): meanValues = mean(dataMat,axis=0) #竖着求平均值,数据格式为mxn meanRemoved = dataMat - meanValues #0均值化 covMat = cov(meanRemoved,rowvar=0) #每一列作为一个独立变量求协方差 eigVals,eigVects = linalg.eig(mat(covMat)) #求特征值和特征向量 eigValInd = argsort(-eigVals) #特征值由大到小排列,eigvalidInd数组 eigValInd = eigValInd[:topNfeat] #选取前topfeat个特征值的序号,取第一列的序号 redEigVects = eigVects[:,eigValInd] #把符合条件的几列特征筛选出来组成p lowDDataMat = meanRemoved * redEigVects #矩阵点乘筛选的特征向量矩阵 m×r维 公式Y=X*P reconMat = (lowDDataMat * redEigVects.T) + meanValues # 转换新空间的数据 m×n维 reconMat = array(reconMat) return lowDDataMat,reconMatdef DrawPoints(dataset1,dataset2): fig = plt.figure() #添加图布 ax1 = fig.add_subplot(211) #添加子图 ax2 = fig.add_subplot(212) #添加子图 ax1.scatter(dataset1[:,0],dataset1[:,1],marker="s",s=10,color="red") ax2.scatter(dataset2[:,0],dataset2[:,1],s=10,color="blue") plt.show()if __name__ == "__main__": data = loadDataSet("/home/quan/PycharmProjects/untitled3/PCAtest/pca_data_set2.txt") process_data,reconMat = Pca(data,1) DrawPoints(data,reconMat)
以下是针对两个数据集的测试效果:
Test_date_1
Test_data_2