机器学习实战--数据预处理

当数据量变的特别大,数据特征的维度变得很大时,若不对数据进行一定的预处理,将会使问题求解的速度变得很慢,甚至是无法求解。这里介绍两种数据预处理(降维)的方法:pca和svd
数据降维主要有这几种方法:
1、主成分分析(PCA):PCA实际上是进行坐标的转换,转换后的坐标的第一维选择数据方差最大的方向,第二维选择与第一维正交且数据方差最大的方向,依次重复上述的构造方法,得到第三维,第四维…而数据的大部分信息都隐含在较前面的维度中,所以仅选择前面N个维度就能较好的表达数据。
2、因子分析(FA):FA假设数据中含有某些隐变量,而数据就是这些引变量和噪声的线性组合,隐变量数目比特征值的数目少,通过分析这些隐变量,数据可以用这些隐变量的线性组合得到。
3、主成分分析(ICA):ICA假设数据是有多个互相独立的数据源产生的,如果数据源少于数据数目,则可以实现降维。

一、PCA

1、原理见上述:
2、pca涉及特征值和特征向量:A*V = lamda* V,相关内容可以参考线性代数的知识。
3、本质就是分析出数据最重要的特征,然后用这些特征(前N个最重要的)去表达重构数据。
4、算法实现

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)
#lowDDataMat:降维后的特征
#reconMat:用降维后的特征重构的数据
def pca(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
    #这里注意一下python中list的slice的获取方式
    #l = [1,2,3,4,5]
    #l[start:end:step]---step为负值时,应为从后往前
    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

5、我们这里采用的是将数据导入内存后进行处理,如果要进行在线的处理,可以参考(incremental eigenanalysis for classification)

二、SVD

svd是一种矩阵分解技术,即奖一个矩阵分解成多个独立的部分
1、svd数学表达: Data(mxn) = U(m x m) * Sigma(m x n) * V_T(n x n)
这里,Sigma是一个对角矩阵,除了对角线上的值非0,其它元素都为0,这些对角线上的元素即为Data的奇异值,而且,从大到小排列。
2、和pca中的特征值一样,奇异值也是数据集的重要特征,且其和特征值的关系为:奇异值是Data * Data_T矩阵的特征值的平方根
3、算法实现:

from numpy import linalg as la
U,Sigma,VT = la.svd(dataMat)
#注意这里在numpy中的实现时,为了减少储存空间,而只存储Sigma中的非0值(奇异值),进行重构时要先进行矩阵还原。

4、数据重构:Data(mxn) = U(m x r) * Sigma(r x r) * V_T(r x n)
这里r为前r个重要的奇异值数。
5、相似度的计算:

#这里,将各种方式得到的距离归一化到0-1之间
#欧式距离
def ecludSim(inA,inB):
    return 1.0/(1.0 + la.norm(inA - inB))
#皮特森距离
def pearsSim(inA,inB):
    if len(inA) < 3 : return 1.0#...
    return 0.5+0.5*corrcoef(inA, inB, rowvar = 0)[0][1]
#余弦距离
def cosSim(inA,inB):
    num = float(inA.T*inB)
    denom = la.norm(inA)*la.norm(inB)
    return 0.5+0.5*(num/denom)

5、推荐系统中选择基于用户的相似度还是基于物品的相似度取决于方便程度,数据量的大小(一般选择前者,这是由于物品<<用户)
6、关于选择多少特征值或奇异值数合适的问题:如果对所研究的问题足够熟悉,可以采用经验法,简单方便。也可采用计算的方式p = sum(Sigma[:r])/sum(Sigma)。求得用前r个奇异值时,能使重构后数据的能量值为原数据的p倍
7、基于svd的图像压缩

def imgCompress(numSV=3, thresh=0.8):
    myl = []
    for line in open('0_5.txt').readlines():
        newRow = []
        for i in range(32):
            newRow.append(int(line[i]))
        myl.append(newRow)
    myMat = mat(myl)
    print "****original matrix******"
    printMat(myMat, thresh)
    U,Sigma,VT = la.svd(myMat)
    SigRecon = mat(zeros((numSV, numSV)))
    for k in range(numSV):#construct diagonal matrix from vector
        SigRecon[k,k] = Sigma[k]
    reconMat = U[:,:numSV]*SigRecon*VT[:numSV,:]
    print "****reconstructed matrix using %d singular values******" % numSV
    printMat(reconMat, thresh)

你可能感兴趣的:(机器学习,数据预处理,pca,SVD)