@@ -155,7 +155,114 @@ def loadExData2():
155155
156156> 分析数据: 暂时不需要
157157
158- > 使用算法: 通过调用 recommend() 函数进行推荐
158+ > 训练算法: 通过调用 recommend() 函数进行推荐
159+
160+ * 基于物品相似度(参考地址:http://www.codeweblog.com/svd-%E7%AC%94%E8%AE%B0/ )
161+
162+ ![ 基于物品相似度] ( /images/14.SVD/基于物品相似度.png )
163+
164+ ``` python
165+ # 基于物品相似度的推荐引擎
166+ def standEst (dataMat , user , simMeas , item ):
167+ """ standEst(计算某用户未评分物品中,以对该物品和其他物品评分的用户的物品相似度,然后进行综合评分)
168+
169+ Args:
170+ dataMat 训练数据集
171+ user 用户编号
172+ simMeas 相似度计算方法
173+ item 未评分的物品编号
174+ Returns:
175+ ratSimTotal/simTotal 评分(0~5之间的值)
176+ """
177+ # 得到数据集中的物品数目
178+ n = shape(dataMat)[1 ]
179+ # 初始化两个评分值
180+ simTotal = 0.0
181+ ratSimTotal = 0.0
182+ # 遍历行中的每个物品(对用户评过分的物品进行遍历,并将它与其他物品进行比较)
183+ for j in range (n):
184+ userRating = dataMat[user, j]
185+ # 如果某个物品的评分值为0,则跳过这个物品
186+ if userRating == 0 :
187+ continue
188+ # 寻找两个用户都评级的物品
189+ # 变量 overLap 给出的是两个物品当中已经被评分的那个元素的索引ID
190+ # logical_and 计算x1和x2元素的真值。
191+ overLap = nonzero(logical_and(dataMat[:, item].A > 0 , dataMat[:, j].A > 0 ))[0 ]
192+ # 如果相似度为0,则两着没有任何重合元素,终止本次循环
193+ if len (overLap) == 0 :
194+ similarity = 0
195+ # 如果存在重合的物品,则基于这些重合物重新计算相似度。
196+ else :
197+ similarity = simMeas(dataMat[overLap, item], dataMat[overLap, j])
198+ # print 'the %d and %d similarity is : %f'(iten,j,similarity)
199+ # 相似度会不断累加,每次计算时还考虑相似度和当前用户评分的乘积
200+ # similarity 用户相似度, userRating 用户评分
201+ simTotal += similarity
202+ ratSimTotal += similarity * userRating
203+ if simTotal == 0 :
204+ return 0
205+ # 通过除以所有的评分总和,对上述相似度评分的乘积进行归一化,使得最后评分在0~5之间,这些评分用来对预测值进行排序
206+ else :
207+ return ratSimTotal/ simTotal
208+ ```
209+
210+ * 基于SVD(参考地址:http://www.codeweblog.com/svd-%E7%AC%94%E8%AE%B0/ )
211+
212+ ![ 基于SVD.png] ( /images/14.SVD/基于SVD.png )
213+
214+ ``` python
215+ # 基于SVD的评分估计
216+ # 在recommend() 中,这个函数用于替换对standEst()的调用,该函数对给定用户给定物品构建了一个评分估计值
217+ def svdEst (dataMat , user , simMeas , item ):
218+ """ svdEst(计算某用户未评分物品中,以对该物品和其他物品评分的用户的物品相似度,然后进行综合评分)
219+
220+ Args:
221+ dataMat 训练数据集
222+ user 用户编号
223+ simMeas 相似度计算方法
224+ item 未评分的物品编号
225+ Returns:
226+ ratSimTotal/simTotal 评分(0~5之间的值)
227+ """
228+ # 物品数目
229+ n = shape(dataMat)[1 ]
230+ # 对数据集进行SVD分解
231+ simTotal = 0.0
232+ ratSimTotal = 0.0
233+ # 奇异值分解
234+ # 在SVD分解之后,我们只利用包含了90%能量值的奇异值,这些奇异值会以NumPy数组的形式得以保存
235+ U, Sigma, VT = la.svd(dataMat)
236+
237+ # # 分析 Sigma 的长度取值
238+ # analyse_data(Sigma, 20)
239+
240+ # 如果要进行矩阵运算,就必须要用这些奇异值构建出一个对角矩阵
241+ Sig4 = mat(eye(4 ) * Sigma[: 4 ])
242+ # 利用U矩阵将物品转换到低维空间中,构建转换后的物品(物品+4个主要的特征)
243+ xformedItems = dataMat.T * U[:, :4 ] * Sig4.I
244+ # 对于给定的用户,for循环在用户对应行的元素上进行遍历,
245+ # 这和standEst()函数中的for循环的目的一样,只不过这里的相似度计算时在低维空间下进行的。
246+ for j in range (n):
247+ userRating = dataMat[user, j]
248+ if userRating == 0 or j == item:
249+ continue
250+ # 相似度的计算方法也会作为一个参数传递给该函数
251+ similarity = simMeas(xformedItems[item, :].T, xformedItems[j, :].T)
252+ # for 循环中加入了一条print语句,以便了解相似度计算的进展情况。如果觉得累赘,可以去掉
253+ print ' the %d and %d similarity is: %f ' % (item, j, similarity)
254+ # 对相似度不断累加求和
255+ simTotal += similarity
256+ # 对相似度及对应评分值的乘积求和
257+ ratSimTotal += similarity * userRating
258+ if simTotal == 0 :
259+ return 0
260+ else :
261+ # 计算估计评分
262+ return ratSimTotal/ simTotal
263+ ```
264+
265+ 排序获取最后的推荐结果
159266
160267``` python
161268# recommend()函数,就是推荐引擎,它默认调用standEst()函数,产生了最高的N个推荐结果。
@@ -178,6 +285,9 @@ def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=standEst):
178285 return sorted (itemScores, key = lambda jj : jj[1 ], reverse = True )[: N]
179286```
180287
288+ > 测试 和 使用 该算法,可以自行编写
289+
290+ [ 完整代码地址] ( https://github.com/apachecn/MachineLearning/blob/master/src/python/14.SVD/svdRecommend.py ) : < https://github.com/apachecn/MachineLearning/blob/master/src/python/14.SVD/svdRecommend.py >
181291
182292#### 要点补充
183293
@@ -201,6 +311,97 @@ def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=standEst):
201311
202312### 项目案例: 基于 SVD 的图像压缩
203313
314+ > 收集 并 准备数据
315+
316+ 将文本数据转化为矩阵
317+
318+ ``` python
319+ # 加载并转换数据
320+ def imgLoadData (filename ):
321+ myl = []
322+ # 打开文本文件,并从文件以数组方式读入字符
323+ for line in open (filename).readlines():
324+ newRow = []
325+ for i in range (32 ):
326+ newRow.append(int (line[i]))
327+ myl.append(newRow)
328+ # 矩阵调入后,就可以在屏幕上输出该矩阵
329+ myMat = mat(myl)
330+ return myMat
331+ ```
332+
333+ > 分析数据: 分析 Sigma 的长度个数
334+
335+ 通常保留矩阵 80% ~ 90% 的能量,就可以得到重要的特征并取出噪声。
336+
337+ ``` python
338+ def analyse_data (Sigma , loopNum = 20 ):
339+ """ analyse_data(分析 Sigma 的长度取值)
340+
341+ Args:
342+ Sigma Sigma的值
343+ loopNum 循环次数
344+ """
345+ # 总方差的集合(总能量值)
346+ Sig2 = Sigma** 2
347+ SigmaSum = sum (Sig2)
348+ for i in range (loopNum):
349+ SigmaI = sum (Sig2[:i+ 1 ])
350+ '''
351+ 根据自己的业务情况,就行处理,设置对应的 Singma 次数
352+
353+ 通常保留矩阵 80% ~ 90% 的能量,就可以得到重要的特征并取出噪声。
354+ '''
355+ print ' 主成分:%s , 方差占比:%s%% ' % (format (i+ 1 , ' 2.0f' ), format (SigmaI/ SigmaSum* 100 , ' 4.2f' ))
356+ ```
357+
358+ > 使用算法: 对比使用 SVD 前后的数据差异对比,对于存储大家可以试着写写
359+
360+ ``` python
361+ # 打印矩阵
362+ def printMat (inMat , thresh = 0.8 ):
363+ # 由于矩阵保护了浮点数,因此定义浅色和深色,遍历所有矩阵元素,当元素大于阀值时打印1,否则打印0
364+ for i in range (32 ):
365+ for k in range (32 ):
366+ if float (inMat[i, k]) > thresh:
367+ print 1 ,
368+ else :
369+ print 0 ,
370+ print ' '
371+
372+
373+ # 实现图像压缩,允许基于任意给定的奇异值数目来重构图像
374+ def imgCompress (numSV = 3 , thresh = 0.8 ):
375+ """ imgCompress( )
376+
377+ Args:
378+ numSV Sigma长度
379+ thresh 判断的阈值
380+ """
381+ # 构建一个列表
382+ myMat = imgLoadData(' input/14.SVD/0_5.txt' )
383+
384+ print " ****original matrix****"
385+ # 对原始图像进行SVD分解并重构图像e
386+ printMat(myMat, thresh)
387+
388+ # 通过Sigma 重新构成SigRecom来实现
389+ # Sigma是一个对角矩阵,因此需要建立一个全0矩阵,然后将前面的那些奇异值填充到对角线上。
390+ U, Sigma, VT = la.svd(myMat)
391+ # SigRecon = mat(zeros((numSV, numSV)))
392+ # for k in range(numSV):
393+ # SigRecon[k, k] = Sigma[k]
394+
395+ # 分析插入的 Sigma 长度
396+ analyse_data(Sigma, 20 )
397+
398+ SigRecon = mat(eye(numSV) * Sigma[: numSV])
399+ reconMat = U[:, :numSV] * SigRecon * VT [:numSV, :]
400+ print " ****reconstructed matrix using %d singular values *****" % numSV
401+ printMat(reconMat, thresh)
402+ ```
403+
404+ [ 完整代码地址] ( https://github.com/apachecn/MachineLearning/blob/master/src/python/14.SVD/svdRecommend.py ) : < https://github.com/apachecn/MachineLearning/blob/master/src/python/14.SVD/svdRecommend.py >
204405
205406* * *
206407
0 commit comments