利用SVD-推荐未尝过的菜肴2
生活随笔
收集整理的這篇文章主要介紹了
利用SVD-推荐未尝过的菜肴2
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
推薦未嘗過(guò)的菜肴-基于SVD的評(píng)分估計(jì)
實(shí)際上數(shù)據(jù)集要比我們上一篇展示的myMat要稀疏的多。
from numpy import linalg as la from numpy import * 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]]一、計(jì)算一下到底有多少個(gè)奇異值能達(dá)到總能量的90%(下一篇我們將用一個(gè)函數(shù)實(shí)現(xiàn)該功能)
U, Sigma, VT = la.svd(mat(loadExData2())) Sigma array([15.77075346, 11.40670395, 11.03044558, 4.84639758, 3.09292055,2.58097379, 1.00413543, 0.72817072, 0.43800353, 0.22082113,0.07367823])總能量: Sig2 = Sigma ** 2
sum(Sig2) 541.9999999999995 總能量的90%: sum(Sig2) * 0.9 487.7999999999996
計(jì)算前兩個(gè)元素所包含的能量: sum(Sig2[:2]) 378.8295595113579
該值低于總能量的90%,計(jì)算前三個(gè)元素所包含的能量: sum(Sig2[:3]) 500.5002891275793
該值高于總能量的90%,我們將一個(gè)11維的矩陣轉(zhuǎn)換成一個(gè)三維的矩陣,下面對(duì)轉(zhuǎn)換后的三維空間構(gòu)造出一個(gè)相似度計(jì)算函數(shù)
二、相似度計(jì)算(歐式距離、皮爾遜相關(guān)系數(shù)、余弦相似度)
# 相似度計(jì)算 # 計(jì)算歐式距離 def ecludSim(inA, inB):return 1.0 / (1.0 + la.norm(inA - inB))# pearsim()函數(shù)會(huì)檢查是否存在3個(gè)或更多的點(diǎn) # corrcoef直接計(jì)算皮爾遜相關(guān)系數(shù),范圍[-1, 1],歸一化后[0, 1] def pearsSim(inA, inB):# 如果不存在,該函數(shù)返回1.0,此時(shí)兩個(gè)向量完全相關(guān)if len(inA) < 3:return 1.0return 0.5 + 0.5 * corrcoef(inA, inB, rowvar=0)[0][1]# 計(jì)算余弦相似度,如果夾角為90度,相似度為0;如果兩個(gè)向量的方向相同,相似度為1.0 def cosSim(inA, inB): num = float(inA.T * inB)denom = la.norm(inA) * la.norm(inB)return 0.5 + 0.5 * (num / denom)三、基于SVD的評(píng)分估計(jì)
# 基于SVD的評(píng)分估計(jì) # 在recommend()中,這個(gè)函數(shù)用于替換對(duì)standEst()的調(diào)用,該函數(shù)對(duì)給定用戶、給定物品構(gòu)建了一個(gè)評(píng)分估計(jì)值 def svdEst(dataMat, user, simMeas, item):"""svdEst()Args:dataMat 訓(xùn)練數(shù)據(jù)集user 用戶編號(hào)simMeas 相似度計(jì)算方法item 未評(píng)分的物品編號(hào)Returns:ratSimTotal / simTotal 評(píng)分(0~5之間的值)"""# 物品數(shù)目n = shape(dataMat)[1]# 對(duì)數(shù)據(jù)集進(jìn)行SVD分解simTotal = 0.0ratSimTotal = 0.0# 奇異值分解# 在SVD分解之后,我們只利用包含了90%能量值的奇異值,這些奇異值會(huì)以Numpy數(shù)組的形式得以保存U, Sigma, VT = la.svd(dataMat)# 如果要進(jìn)行矩陣運(yùn)算,就必須要用這些奇異值構(gòu)建出一個(gè)對(duì)角矩陣Sig4 = mat(eye(4) * Sigma[: 4])# 利用U矩陣將物品轉(zhuǎn)換到低維空間中,構(gòu)建轉(zhuǎn)換后的物品xformedItems = dataMat.T * U[:, :4] * Sig4.I# 對(duì)于給定的用戶,for循環(huán)在用戶對(duì)應(yīng)行的元素上進(jìn)行遍歷# 這和standEst()函數(shù)中的for循環(huán)的目的一樣,只不過(guò)這里的相似度計(jì)算是在低維空間下進(jìn)行的for j in range(n):userRating = dataMat[user, j]if userRating == 0 or j == item:continue# 相似度的計(jì)算方法也會(huì)作為一個(gè)參數(shù)傳遞給該函數(shù)similarity = simMeas(xformedItems[item, :].T, xformedItems[j, :].T)# 對(duì)相似度不斷累加求和simTotal += similarity# 對(duì)相似度及對(duì)應(yīng)評(píng)分值的乘積求和ratSimTotal += similarity * userRatingif simTotal == 0:return 0else:# 計(jì)算估計(jì)評(píng)分return ratSimTotal/simTotal四、排序獲取最后的推薦結(jié)果
# recommend()函數(shù),就是推薦引擎,它默認(rèn)調(diào)用 svdEst()函數(shù),產(chǎn)生了最高的N個(gè)推薦結(jié)果 # 如果不指定N的大小,則默認(rèn)值為3,該函數(shù)另外的參數(shù)該包括相似度計(jì)算方法和估計(jì)方法 def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=svdEst):"""recommend()Args:dataMat 訓(xùn)練數(shù)據(jù)集user 用戶編號(hào)simMeas 相似度計(jì)算方法estMethod 使用的推薦算法Returns:返回最終N個(gè)推薦結(jié)果"""# 尋找未評(píng)級(jí)的物品# 對(duì)給定用戶建立一個(gè)未評(píng)分的物品列表unratedItems = nonzero(dataMat[user, :].A == 0)[1]# 如果不存在未評(píng)分物品,那么就退出函數(shù)if len(unratedItems) == 0:return 'you rated everything'# 物品的編號(hào)和評(píng)分值itemScores = []for item in unratedItems:# 獲取 item 該物品的評(píng)分estimatedScore = estMethod(dataMat, user, simMeas, item)itemScores.append((item, estimatedScore))# 按照評(píng)分得分,進(jìn)行逆排序,獲取前N個(gè)未評(píng)級(jí)物品進(jìn)行推薦return sorted(itemScores, key=lambda jj: jj[1], reverse=True)[: N] myMat = mat(loadExData2()) recommend(myMat, 1, simMeas=pearsSim) [(4, 3.346952186702173), (9, 3.33537965732747), (6, 3.3071930278130366)] 這表明用戶1(從0開始計(jì)數(shù),對(duì)應(yīng)是矩陣第2行),對(duì)物品4的預(yù)測(cè)評(píng)分為3.34,對(duì)物品9預(yù)測(cè)評(píng)分為3.33,對(duì)物品6預(yù)測(cè)評(píng)分為3.30試試另一種相似度 recommend(myMat, 1, simMeas=cosSim) [(4, 3.344714938469228), (7, 3.3294020724526967), (9, 3.3281008763900686)]
?
轉(zhuǎn)載于:https://www.cnblogs.com/gezhuangzhuang/p/10205284.html
總結(jié)
以上是生活随笔為你收集整理的利用SVD-推荐未尝过的菜肴2的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: kernelbasedll下载_kern
- 下一篇: 15crmo焊接后多长时间探伤_3分钟g