您的位置:首页 > 编程语言

主成分分析代码实现

2017-05-08 20:56 639 查看
主成分分析(PCA)是一种线性降维技术。在PCA中数据从原来坐转换到了新的坐标系,新坐标的选择是由数据本身决定的。(高维原空间XXT的前d’个大小的特征值(从大到小的排序)对应的特征向量决定了新坐标)。第一个坐标轴的选择是原始数据方差最大,第二新坐标轴的选择和第一个坐标轴正交且具有最大方差的方向。

PCA可以同时获得像决策树一样简单的分类,同时分类间隔SVM一样好。

通过数据集协方差矩阵以及其特征值和对应的特征向量,保留最大的N个值构成属性转化空间矩阵W,将WT]乘以原空间样本得到降维空间属性。

实现过程:Python中Numpy有寻找特征向量和特征值模块linalg,有eig()方法

伪代码:

去除平均值

计算协方差矩阵

计算协方差矩阵的特征值和特征向量

将特征值从大到小排列

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

将数据转换到上述N个特征向量构建的新空间中

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):
meanVale=mean(dataMat,axis=0)#axis=0 col
meanRemoved=dataMat-meanVale#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


map()用法: map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。

例如,对于list [1, 2, 3, 4, 5, 6, 7, 8, 9],如果希望把list的每个元素都作平方,就可以用map()函数:因此,我们只需要传入函数f(x)=x*x,就可以利用map()函数完成这个计算

def f(x):

return x*x

print map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])

结果 [1, 4, 9, 10, 25, 36, 49, 64, 81]


由于list包含的元素可以是任何类型,因此,map() 不仅仅可以处理只包含数值的 list,事实上它可以处理包含任意类型的 list,只要传入的函数f可以处理这种数据类型。

将每一行数据转换为float型
datArr=[map(float,line)for line in stringArr]
原始数据被重构后用于调试
reconMat = (lowDDataMat * redEigVects.T) + meanVals


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

观察数据集,缺失值是以NAN标识。用平均值代替缺失值,平均值根据非缺失值得到。

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]) #values that are not NaN (a number)
datMat[nonzero(isnan(datMat[:,i].A))[0],i] = meanVal  #set NaN values to mean
return datMat


npnzero()用法

nonzeros(a)返回数组a中值不为零的元素的下标,它的返回值是一个长度为a.ndim(数组a的轴数)的元组,元组的每个元素都是一个整数数组,其值为非零元素的下标在对应轴上的值。

例如对于一维布尔数组b1,nonzero(b1)所得到的是一个长度为1的元组,它表示b1[0]和b1[2]的值不为0(False)。

对于二维数组b2,nonzero(b2)所得到的是一个长度为2的元组。它的第0个元素是数组a中值不为0的元素的第0轴的下标,第

个元素则是第1轴的下标,因此从下面的结果可知b2[0,0]、b[0,2]和b2[1,0]的值不为0:

>>> b1 = np.array([True, False, True, False])
>>> np.nonzero(b1)
(array([0, 2]),)
>>> b2 = np.array([[True, False, True], [True, False, False]])
>>> np.nonzero(b2)
(array([0, 0, 1]), array([0, 2, 0]))


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