PCA简化数据

1.前言

之前做了不少的机器学习模型和算法,但我们用来训练模型的数据维数都是很小的,所以模型的预测结果也能差强人意。但之前做决策树的时候,曾经带入过十几维的数据得到的决策树是过拟合的,说明数据维数还是影响着模型。

使数据降维的主要原因如下:

a.在训练数据集中,也许并不是所有的数据都能对预测或者是分类起作用,我们只需要找到其中起绝对性因素的数据特征即可。

b.训练数据的维数过多会导致模型的训练时间延长

2.主成分分析(PCA)

主成分分析是设法将原来众多具有一定相关性(比如P个指标),重新组合成一组新的互相无关的综合指标来代替原来的指标。

主成分分析,是考察多个变量间相关性一种多元统计方法,研究如何通过少数几个主成分来揭示多个变量间的内部结构,即从原始变量中导出少数几个主成分,使它们尽可能多地保留原始变量的信息,且彼此间互不相关.通常数学上的处理就是将原来P个指标作线性组合,作为新的综合指标。(摘自百度百科)

博主的理解就是,就对于数据集里面的特征,我们计算一个能衡量该特征是否为主要特征的指标,该指标越大,则在预测或分类里占的要素也越大。假如我们要选取N个主成分,那就选取前N个大的指标对应的特征。

3.PCA具体实现流程

假设数据X有N个特征:X={$X_1$,$X_2$,...,$X_N$}

(1)计算每一个特征对应的平均值

(2)计算协方差矩阵:


其中$c_i_j$的计算公式如下:


(3)根据协方差矩阵求解出特征值和特征向量

(4)根据特征值进行排序,选出前K个最大特征值对应的特征向量

(5)将数据转换到K个特征向量的空间之中

4.PCA实战

-----来自《机器学习实战》

对testSet处理:


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




5.代码

书上给的代码好像不能直接运行(我的版本是python3),我这里给出直接修改过且能运行的代码:

(会显示"error"但不影响结果)

from numpy import *
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
def loadDataSet(fileName, delim='\t'):
    fr = open(fileName)
    stringArr = [line.strip().split(delim) for line in fr.readlines()]
    for line in stringArr:
        for i in range(len(line)):
            line[i]=float(line[i])
    datArr = [line for line in stringArr]
    return mat(datArr)

def pc_a(dataMat, topNfeat=9999999):
    meanVals = mean(dataMat, axis=0)
    meanRemoved = dataMat - meanVals #remove mean
    covMat = cov(meanRemoved, rowvar=0)
    eigVals,eigVects = linalg.eig(mat(covMat))
    eigValInd = argsort(eigVals)            #sort, sort goes smallest to largest
    eigValInd = eigValInd[:-(topNfeat+1):-1]  #cut off unwanted dimensions
    redEigVects = eigVects[:,eigValInd]       #reorganize eig vects largest to smallest
    lowDDataMat = meanRemoved * redEigVects#transform data into new dimensions
    reconMat = (lowDDataMat * redEigVects.T) + meanVals
    return lowDDataMat, reconMat

def replaceNanWithMean(): 
    datMat = loadDataSet('secom.data', ' ')
    #print(datMat)
    numFeat = shape(datMat)[1]
    for i in range(numFeat):
        try:
            meanVal = mean(datMat[nonzero(~np.isnan(datMat[:,i].A))[0],i]) #values that are not NaN (a number)
            datMat[nonzero(np.isnan(datMat[:,i].A))[0],i] = meanVal  #set NaN values to mean
        finally:
            print('error')
    return datMat

def start():
    dataMat=replaceNanWithMean()
    meanVals=mean(dataMat,axis=0)
    meanRemoved=dataMat-meanVals
    covMat=cov(meanRemoved,rowvar=0)
    eigVals,eigVects=linalg.eig(mat(covMat))
    eigValInd=argsort(eigVals)
    eigValInd=eigValInd[::-1]
    sortedEigVals=eigVals[eigValInd]
    total=sum(sortedEigVals)
    varPercentage=sortedEigVals/total*100
    print(eigVals)
    fig=plt.figure()
    ax=fig.add_subplot(111)
    ax.plot(range(1,21),varPercentage[:20],marker='^')
    plt.xlabel("Principal Component Number")
    plt.ylabel("Percentage of Variance")
    plt.show()
'''
import pca
dataMat=pca.loadDataSet('testSet.txt')
lowDMat,reconMat=pca.pc_a(dataMat,1)
shape(lowDMat)
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="o", s=50, c="red")  
plt.show()  
'''

 


  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值