PCA 可以从数据中识别其主要特征,它是通过沿着数据最大方差方向旋转坐标轴来实现的。选择方差最大的方向座位第一条坐标轴,后续坐标轴则与前面的坐标轴正交。协方差矩阵上的特征值分析可以用一系列的正交坐标轴来获取。
优点:降低数据的复杂性,识别最重要的几个特征
缺点:不一定需要,且可能损失有用信息
适用数据类型:数值型数据
步骤:
去除平均值计算协方差矩阵计算协方差矩阵的特征值和特征向量将特征值从大到小排序保留最上面的N个特征向量将数据转换到上述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实现item-based CF:
步骤:
构建物品用户数据矩阵对数据矩阵进行SVD分解提取最大的几个特征值利用最大的几个特征值和特征向量构建低维空间上的物品矩阵寻找目标用户未评分的物品在低维空间上计算未评分物品与其它物品的相似度,再把相似度与评分值加权预测未评分物品的评分按计算到的评分值从大到小排序,推荐前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实现,我们能够用小得多的数据集来表示原始数据集,可以节省空间。