《机器学习实战》源码解析(九):PCA

本系列以书中源码为主,稍作修改并添加注释,均实际运行可行。为免后来者踩坑,特此公开!欢迎打赏!
转载请注明出处!

from numpy import *
import matplotlib
import matplotlib.pyplot as plt
#PCA算法,共两个函数
#第一个函数,用于清洗数据
#输入:原始数据集,分隔符
#输出:清洗后的数据集,一个可以计算的矩阵
def loadDataSet(fileName,delim='\t'):
    fr = open(fileName)
    stringArr = [line.strip().split(delim) for line in fr.readlines()]
    dataArr = [list(map(float,line)) for line in stringArr]
    return mat(dataArr)

#第二个函数,PCA主函数
#输入:数据集,主成分个数.注意这里的数据集矩阵中每行代表一个元素,每个元素有两个特征(书本中的数据)值
#输出:
def pca(dataMat,topNfeat=9999999):
    #求每列(即特征值)的平均值(压缩为1行),若为1则是求每行平均值(压缩为1列)
    meanVals = mean(dataMat,axis=0)
    meanRemoved = dataMat - meanVals#平移到以0为中心的地方,便于计算
    covMat =cov(meanRemoved,rowvar =0)#计算协方差矩阵
    eigVals,eigVects = linalg.eig(mat(covMat))#计算特征值,特征向量
    eigValInd = argsort(eigVals) #默认快排,从小到大进行排序
    #得到topNfeat个特征值,大的特征值排在前,若topNfeat为1,则取1个特征值
    eigValInd = eigValInd[:-(topNfeat+1):-1]
     #获得topNfeat个主成分,即坐标轴
    redEigVects = eigVects[:,eigValInd]#将对应topNfeat个特征值对应的特征向量取出来
    #利用主成分矩阵将原中心化后的矩阵转为新的矩阵
    lowDDataMat = meanRemoved * redEigVects 
    #还原降维后的矩阵。因为已经去掉了部分维数(在课本实例中去掉了一维),所以在图像上显示仍为一条直线。
    #正交阵的逆等于其转置。redEigVects为SVD分解中的右奇异正交阵
    reconMat = (lowDDataMat * redEigVects.T) + meanVals
    return lowDDataMat,reconMat  
#测试以上代码
dataMat = loadDataSet(r'选择你自己的数据集路径')
lowDMat,reconMat = 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)
ax.scatter(reconMat[:,0].flatten().A[0],reconMat[:,1].flatten().A[0],marker ='*',s=90)

#利用PCA对半导体制造数据降维
def replaceNanWithMean():
    datMat = loadDataSet('secom.data','')
    numFeat = shape(datMat)[1]
    for i in range(numFeat):
        meanVal = mean(datMat[nonzero(~isnan(datMat[:,i].A))[0],i])
        datMat[nonzero(isnan(datMat[;,i].A))[0],i] = meanVal
    return datMat

dataMat = replaceNanWithMean()
meanVals = mean(dataMat,axis=0)
meanRemoved = dataMat - meanVals
covMat = cov(meanRemoved,rowvar=0)
eigVals,eigVects = linalg.eig(mat(covMat))
eigVals
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值