您的位置:首页 > 其它

py2.7《机器学习实战》利用PCA来简化数据

2017-03-24 17:57 357 查看
最近看了PCA降维,很多地方还是不理解,还是线代学的太差了,但是书上总结的还是挺精简的

一、在Numpy中实现PCA

1、伪代码:

(1)去除平均值(均值归0方便计算方差)

(2)计算协方差矩阵

(3)计算协方差矩阵的特征值和特征向量(利用Numpy中的linalg方法)

(4)将特征值从大到小排序

(5)保留最上面的N个特征向量

(6)将数据转换到上述N个特征构建的新空间中

2.PCA算法

源代码:

#-*- coding:utf-8 -*-
from numpy import *

def loadDataSet(fileName , delim = '\t'):
fr = open(fileName)
stringArr = [line.strip().split(delim) for line in fr.readlines()] #这姿势真是太高大上了
datArr = [map(float,line) for line in stringArr] #类型转换
return mat(datArr)

def pca(dataMat , topNfeat = 9999999):
meanVals = mean(dataMat,axis=0) #求矩阵的平均值
meanRemoved = dataMat - meanVals
covMat = cov(meanRemoved,rowvar=0) #求协方差矩阵
eigVals , eigVects  = linalg.eig(mat(covMat)) #计算特征值和特征向量
eigValInd = argsort(eigVals) #从小到大排序
eigValInd = eigValInd[:-(topNfeat+1):-1] #选取最大的前topNfeat个,默认9999999,这里是反向选取
redEigVect = eigVects[:,eigValInd]
lowDDataMat = meanRemoved*redEigVect #转换空间
reconMat = (lowDDataMat *redEigVect.T ) + meanVals
return lowDDataMat , reconMat  #返回重构后的原始数据和降维后的数据
执行代码:

#-*- coding:utf-8 -*-
import pca
import matplotlib.pyplot as plt
dataMat = pca.loadDataSet('testSet.txt')
lowDMat , reconMat = pca.pca(dataMat,1)
fig = plt.figure()
ax = fig.add_subplot(111) #构造图形
ax.scatter(dataMat[:,0].flatten().A[0] , dataMat[:,1].flatten().A[0],marker='^',s=90,c='red')
ax.scatter(reconMat[:,0].flatten().A[0] , reconMat[:,1].flatten().A[0],marker='o',s=50,c='red')
plt.show()


效果:



二、利用PCA对半导体制造数据降维

源代码:

def replaceNanWithMean(): #处理NaN值,这里采取平均值法
dataMat = loadDataSet('secom.data' , ' ')
numFeat = shape(dataMat)[1] #计算出特征数目
for i in range(numFeat): #对每个特征计算非NaN的均值
meanVal = mean(dataMat[nonzero(~isnan(dataMat[:,i].A))[0],i]) #不是NAN的所有值的平均值
dataMat[nonzero(isnan(dataMat[:,i].A))[0],i] = meanVal
return dataMat


执行代码
#-*- coding:utf-8 -*-
from numpy import *
import pca
import matplotlib.pyplot as plt
dataMat = pca.replaceNanWithMean()
meanVal = mean(dataMat,axis=0) #均值
meanRemoved = dataMat - meanVal #尽力归零化
covMat = cov(meanRemoved,rowvar=0) #协方差矩阵
eigVals , eigVects = linalg.eig(mat(covMat)) #特征值分析
print eigVals #检查特征值:发现大部分都是0,还有四舍五入造成的负数,只有前15个是大于10^5信息量很大

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: