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()
'''