SVD简化数据
来源:互联网 发布:反贪知乎 编辑:程序博客网 时间:2024/06/08 18:22
SVD简化数据
- SVD简化数据
- 引言
- 基础概念
- 3种相关度以及基于相似度推荐代码
- 基于SVD评分估计代码
- SVD应用代码
- 总结
- 0_5txt数据
引言
餐馆可分为很多类别,不同的专家对其分类可能有不同依据。实际中,我们可以忘掉专家,从数据着手,可对记录用户关于餐馆观点的数据进行处理,并从中提取出其背后的因素。这些因素可能会与餐馆的类别、烹饪时采用的某个特定配料,或其他任意对象一致。然后,可利用这些因素来估计人们对没有去过的餐馆的看法。
基础概念
提取信息的方法:奇异值分解Singular Value Decomposition(SVD)
在很多情况下,数据中的一小段携带了数据集中的大部分信息,而其他信息要么是噪声,要么就是毫不相关的信息。矩阵分解可将原始矩阵表示成新的易于处理的形式,新形式是两个或多个矩阵的乘积。
不同的矩阵分解技术具有不同的性质,其中有些更适合于某个应用,有些则更适合于其他应用。最常见的一种矩阵分解技术就是SVD。SVD将原始的数据集矩阵Data分解成三个矩阵U、Σ、VT。如果原始矩阵Data是m行n列,则有如下等式:
上述分解中会构建出一个矩阵Σ,该矩阵只有对角元素,其他元素均为0。另一个惯例就是,Σ的对角元素是从大到小排列的。这些对角元素称为奇异值(Singular Value),它们对应了原始数据集矩阵Data的奇异值。回想PCA章节,得到的是矩阵的特征值,它们告诉我们数据集中的重要特征。Σ中的奇异值也是如此。奇异值和特征值时有关系的。这里的奇异值就是矩阵Data∗DataT特征值的平方根。
矩阵Σ只有从大到小排列的对角元素。在科学和工程中,一致存在这样一个普遍事实:在某个奇异值的数目(r个)之后,其他的奇异值都置为0。这就意味着数据集中仅有r个重要特征,而其余特征则都是噪声或冗余特征。
3种相关度以及基于相似度推荐(+代码)
- 欧氏距离,相似度=1/(1+距离),两个物品越相似距离也就越近,当完全相似时距离就近似于0了。
- 皮尔逊相关系数,用
0.5+0.5∗(corrcoef()) 计算,用于度量两个变量X和Y之间的相关(线性相关),其值介于-1与1之间。在自然科学领域中,该系数广泛用于度量两个变量之间的相关程度,优势在于对量级不敏感。 - 余弦相似度,计算两个向量之间夹角的余弦,如果夹角为90度,余弦为0,相似度为0;如果夹角为0度,余弦为1,相似度也就为1,
cosθ=A∗B||A||∗||B|| , ||A|| 和||B||是向量A和B的2范数,numpy中用linalg.norn()。
#欧氏距离相似度 def ecludSim(inA, inB): return 1.0/(1.0 + linalg.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 = linalg.norm(inA)*linalg.norm(inB) return 0.5+0.5*(num/denom)
既然得到了相似度,就可以对一个菜单作出完整评价,如表格所示,0表示该顾客没有做出评价,首先要把0的位给预测出来,如何预测呢?
首先依次找出某以用户未评价的物品,求和其他物品的相似度,相似度累加,每次计算时还考虑相似度和当前用户评分的乘积,最后,通过除以所有的评分总和,对相似度评分的乘积进行归一化,可以使最后的评分在0-5之间。
def loadExData(): return [[4,4,0,2,2], [2,0,0,3,3], [4,0,0,1,1], [1,1,1,2,0], [2,2,2,0,0], [1,1,1,0,0], [5,5,5,0,0]] def standEst(dataMat, user, simMeans, item): n = shape(dataMat)[1] simTotal = 0.0 ratSimTotal = 0.0 # 此顾客对所有的物品的评分 for i in range(n): #此顾客对该的物品的评分 userRating = dataMat[user, i] if userRating == 0: continue #找出对此物品的评价和对待评价物品的都做评价的顾客 overLap = nonzero(logical_and(dataMat[:, item].A>0, dataMat[:, i].A>0))[0] if len(overLap) == 0: similarity = 0 else:#求出两个物品的相似度 similarity = simMeans(dataMat[overLap, item], dataMat[overLap, i]) print '%d and %d similarity = %f'%(i, item, similarity) #和所有物品的比较的相似度加和 simTotal += similarity #评分*相似度求和 ratSimTotal += similarity*userRating if simTotal == 0: return 0 return ratSimTotal/simTotal def recommend(dataMat, user, N=3, simMeas = cosSim, estMethod = standEst): #得到为零的项 unratedItems = nonzero(dataMat[user, :].A == 0)[1] if len(unratedItems) == 0: return 'None' itemScores = [] for item in unratedItems: #预测出未评分的可能评分 estimatedScore = estMethod(dataMat, user, simMeas, item) itemScores.append((item, estimatedScore)) return sorted(itemScores, key=lambda jj: jj[1], reverse=True)[:N] def main(): dataMat = mat(loadExData2()) print recommend(dataMat, 1) if name == 'main': main() '''结果''' 4 and 0 similarity = 0.000000 7 and 0 similarity = 0.990916 9 and 0 similarity = 0.000000 4 and 1 similarity = 0.000000 7 and 1 similarity = 0.978429 9 and 1 similarity = 0.000000 4 and 2 similarity = 0.000000 7 and 2 similarity = 0.977652 9 and 2 similarity = 0.000000 4 and 3 similarity = 0.000000 7 and 3 similarity = 0.000000 9 and 3 similarity = 1.000000 4 and 5 similarity = 0.000000 7 and 5 similarity = 0.000000 9 and 5 similarity = 1.000000 4 and 6 similarity = 1.000000 7 and 6 similarity = 0.000000 9 and 6 similarity = 0.692308 4 and 8 similarity = 0.000000 7 and 8 similarity = 0.995750 9 and 8 similarity = 0.000000 4 and 10 similarity = 0.000000 7 and 10 similarity = 1.000000 9 and 10 similarity = 1.000000 [(3, 4.0), (5, 4.0), (6, 4.0)]
基于SVD评分估计(+代码)
实际的数据集会比用于展示recommend()函数功能的myMat矩阵稀疏得多。
可以通过loadExData2()将该矩阵加载到程序中
接下来计算该矩阵的SVD来了解其到底需要多少维特征。
前三个元素所包含的总能量符合要求,可以将一个11维的矩阵转换成一个3维矩阵。下面对转换后的三维空间构造出一个相似度计算函数。利用SVD将所有的菜肴映射到一个低维空间中去。在低维空间下,可以利用前面相同的相似度计算方法来进行推荐。构建一个类似于standEst()的函数svdEst()。
def loadExData2(): return [[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5], [0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3], [0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0], [3, 3, 4, 0, 0, 0, 0, 2, 2, 0, 0], [5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0], [0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0], [4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1], [0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4], [0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2], [0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0], [1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]] def svdEst(dataMat, user, simMeas, item): n = shape(dataMat)[1] simTotal = 0.0 ratSimTotal = 0.0 #将原数据分解成svd U,Sigma,VT = linalg.svd(dataMat) Sig4 = mat(eye(4)*Sigma[:4]) #利用U矩阵将物品转换到低维空间中 xformedItems = dataMat.T * U[:,:4] * Sig4.I #print xformedItems 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 main(): dataMat = mat(loadExData2()) print recommend(dataMat, 1, estMethod = svdEst) if __name__ == '__main__': main() '''结果''' the 0 and 3 similarity is: 0.490950 the 0 and 5 similarity is: 0.484274 the 0 and 10 similarity is: 0.512755 the 1 and 3 similarity is: 0.491294 the 1 and 5 similarity is: 0.481516 the 1 and 10 similarity is: 0.509709 the 2 and 3 similarity is: 0.491573 the 2 and 5 similarity is: 0.482346 the 2 and 10 similarity is: 0.510584 the 4 and 3 similarity is: 0.450495 the 4 and 5 similarity is: 0.506795 the 4 and 10 similarity is: 0.512896 the 6 and 3 similarity is: 0.743699 the 6 and 5 similarity is: 0.468366 the 6 and 10 similarity is: 0.439465 the 7 and 3 similarity is: 0.482175 the 7 and 5 similarity is: 0.494716 the 7 and 10 similarity is: 0.524970 the 8 and 3 similarity is: 0.491307 the 8 and 5 similarity is: 0.491228 the 8 and 10 similarity is: 0.520290 the 9 and 3 similarity is: 0.522379 the 9 and 5 similarity is: 0.496130 the 9 and 10 similarity is: 0.493617 [(4, 3.3447149384692278), (7, 3.3294020724526976), (9, 3.328100876390069)]
SVD应用(+代码)
SVD应用于图像压缩的例子。通过可视化的方式,该例子使我们很容易就能看到SVD对数据近似的效果。在代码库中,包含了一张手写的数字图像。该图像在第二章使用过。原始图像大小是32x32=1024像素,我们能否使用更少的像素来表示这张图呢?如果能对图像进行压缩,那么就可以节省空间或带宽开销了。
可以使用SVD来对数据降维,从而实现图像的压缩。下面就会看到利用SVD的手写数字图像的压缩过程了。下面的程序包含了数字的读入和压缩代码。要了解最后的压缩效果,对压缩后的图像进行了重构。
可知,只需两个奇异值就能相当精确地对图像实现重构。那么,到底需要多少个0-1的数字来重构图像呢?U和VT都是32x2的矩阵,两个奇异值。因此,总数字数目是64+64+2=130。和原数目1024相比,获得了几乎10倍的压缩比。
# coding=utf-8 from numpy import * import numpy as np def printMat(inMat, thresh=0.8): for i in range(32): for k in range(32): if float(inMat[i,k]) > thresh: print 1, else: print 0, print '' 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 = linalg.svd(myMat) SigRecon = mat(zeros((numSV, numSV))) for k in range(numSV): SigRecon[k,k] = Sigma[k] reconMat = U[:,:numSV]*SigRecon*VT[:numSV,:] print 'U:', U[:,:numSV] print 'SigRecon:', SigRecon print 'VT:', VT[:numSV,:] print "****reconstructed matrix using %d singular values******" % numSV print shape(reconMat) printMat(reconMat, thresh) imgCompress(2)
总结
- 优点:简化数据,去除噪声,提高算法的结果。
- 缺点:数据的转换可能难以理解。
- 使用数据类型:数值型数据。
SVD是一种强大的降维工具,可以利用SVD来逼近矩阵并从中提取重要特征。通过保留80%-90%的能量,就可以得到重要的特征并去掉噪声。SVD已经运用到多种应用中,其中一个成功的应用案例就是推荐引擎。
0_5.txt数据
0000000000000011000000000000000000000000000011111100000000000000000000000001111111100000000000000000000000111111111100000000000000000000111111111111100000000000000000011111111111111100000000000000000011111111111111100000000000000000111111100001111100000000000000011111110000011111000000000000001111110000000011110000000000000011111100000000111110000000000000111111000000000111100000000000001111110000000001111000000000000001111110000000001111000000000000111111100000000011110000000000001111110000000000111100000000000001111100000000001111000000000000111111000000000011110000000000000111110000000000111100000000000001111100000000011111000000000000001111100000000011111000000000000011111000000000111110000000000000111110000000001111100000000000001111100000000111110000000000000011111000000011111100000000000000111111000001111110000000000000000111111111111111100000000000000000111111111111111000000000000000001111111111111110000000000000000001111111111110000000000000000000001111111111000000000000000000000000111111000000000000
- 利用SVD简化数据
- 利用SVD简化数据
- SVD简化数据
- SVD简化数据
- 【简化数据】奇异值分解(SVD)
- 机器学习实战-利用SVD简化数据
- chapter14 机器学习之利用SVD简化数据
- 机器学习实战笔记——利用SVD简化数据
- [完]机器学习实战 第十四章 利用SVD简化数据
- py2.7《机器学习实战》利用SVD简化数据
- 【机器学习实战-python3】利用SVD简化数据
- SVDchapter14 机器学习之利用SVD简化数据
- 机器学习笔记二十 利用SVD简化数据
- 【机器学习实战】第14章 利用SVD简化数据
- 【机器学习实战】第14章 利用 SVD 简化数据
- 利用SVD(Singular Value Decomposition)简化数据
- 机器学习实战笔记-利用SVD简化数据
- 机器学习实战——第十三/十四章:利用PCA和SVD来简化数据
- ubuntu ip 配置
- 01背包练习
- 1003.Crashing Balloon
- SQL Server数据库PIVOT函数的使用详解
- HDU
- SVD简化数据
- regiongrowing
- Java温习——基础工具之Java开发工具Eclipse
- 处理方法返回值 Object 数值型
- padding总结
- 程序员面试金典(3):确定两串乱序同构(python)
- 软件测试黑马工程师---Android app测试(01)
- mysql索引必须了解的几个重要问题
- (POJ