PCA和SVD

PCA(Principal Component Analysis)主成分分析

PCA 可以从数据中识别其主要特征,它是通过沿着数据最大方差方向旋转坐标轴来实现的。选择方差最大的方向座位第一条坐标轴,后续坐标轴则与前面的坐标轴正交。协方差矩阵上的特征值分析可以用一系列的正交坐标轴来获取。

优点:降低数据的复杂性,识别最重要的几个特征

缺点:不一定需要,且可能损失有用信息

适用数据类型:数值型数据

步骤:

  1. 去除平均值
  2. 计算协方差矩阵
  3. 计算协方差矩阵的特征值和特征向量
  4. 将特征值从大到小排序
  5. 保留最上面的N个特征向量
  6. 将数据转换到上述N个特征向量构件的的新空间中
from numpy import *
import matplotlib
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):
    meanVals = mean(dataMat, axis=0) #计算平均只
    meanRemoved = dataMat - meanVals #去除平均值
    covMat = cov(meanRemoved, rowvar=0) #计算协方差矩阵 rowvar=0代表样本为行向量
    eigVals,eigVects = linalg.eig(mat(covMat)) #计算特征值,特征向量
    eigValInd = argsort(eigVals)            #特征值从小到大排序
    eigValInd = eigValInd[:-(topNfeat+1):-1]  #提取最大的几个特征值
    redEigVects = eigVects[:,eigValInd]       #提取最大特征值所对应的特征向量
    lowDDataMat = meanRemoved * redEigVects #将原数据转换到低维空间上
    reconMat = (lowDDataMat * redEigVects.T) + meanVals #重构原数据
    return lowDDataMat, reconMat

SVD

优点: 简化数据,去除噪声,提高算法的结果

缺点: 数据的转换可能难以理解

适用数据类型: 数值型数据

SVD与推荐系统:

利用SVD实现item-based CF:

步骤:

  1. 构建物品用户数据矩阵
  2. 对数据矩阵进行SVD分解
  3. 提取最大的几个特征值
  4. 利用最大的几个特征值和特征向量构建低维空间上的物品矩阵
  5. 寻找目标用户未评分的物品
  6. 在低维空间上计算未评分物品与其它物品的相似度,再把相似度与评分值加权预测未评分物品的评分
  7. 按计算到的评分值从大到小排序,推荐前N个评分值高的给目标用户
from numpy import *
from numpy import linalg as la
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)
def svdEst(dataMat, user, simMeas, item):
    n = shape(dataMat)[1]  #计算物品数
    simTotal = 0.0; ratSimTotal = 0.0
    U,Sigma,VT = la.svd(dataMat) #进行SVD分解
    Sig4 = mat(eye(4)*Sigma[:4]) #提取前4个特征,并转换成对角矩阵
    xformedItems = dataMat.T * U[:,:4] * Sig4.I  #将原矩阵转换成低维空间的数据矩阵
    for j in range(n):
        userRating = dataMat[user,j]
        if userRating == 0 or j==item: continue
        similarity = simMeas(xformedItems[item,:].T,\
                             xformedItems[j,:].T) #计算相似度
        print 'the %d and %d similarity is: %f' % (item, j, similarity)
        simTotal += similarity  #将相似度求和
        ratSimTotal += similarity * userRating #将相似度和评分值加权求和
    if simTotal == 0: return 0
    else: return ratSimTotal/simTotal

def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=svdEst):
    unratedItems = nonzero(dataMat[user,:].A==0)[1] #寻找目标用户未被评分的物品
    if len(unratedItems) == 0: return 'you rated everything'
    itemScores = []
    for item in unratedItems: #对每一个未被评分的物品利用svd计算评分值
        estimatedScore = estMethod(dataMat, user, simMeas, item)
        itemScores.append((item, estimatedScore))
    return sorted(itemScores, key=lambda jj: jj[1], reverse=True)[:N] #按评分值排序,并且提取前N个。

SVD 是一种强大的降维工具,利用SVD来逼近矩阵,从中提取重要特征。通过保留矩阵80%-90% 的能量,就可以得到重要的特征并去除噪声。利用SVD实现,我们能够用小得多的数据集来表示原始数据集,可以节省空间。

你可能感兴趣的:(机器学习)