在生活中,咱們常常給朋友推薦一些本身喜歡的東西,也時常接受別人的推薦。怎麼能保證推薦的電影或者美食就是朋友喜歡的呢?通常來講,大家兩我的常常對同一個電影或者美食感興趣,那麼你喜歡的東西就很大程度上朋友也會比較感興趣。在大數據的背景下,算法會幫我尋找興趣類似的那些人,並關注他們喜歡的東西,以此來給咱們推薦可能喜歡的事物。python
某外賣店鋪收集了一些用戶對本店鋪美食的評價和推薦分,並計劃爲一些新老客戶推薦他們不曾嘗試的美食。算法
數據分析服務器
A B C D E F G H I J K 0[0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 5], 1[0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 3], 2[0, 0, 0, 0, 4, 0, 0, 1, 0, 4, 0], 3[5, 4, 5, 0, 0, 0, 0, 5, 5, 0, 0], 4[0, 0, 0, 0, 5, 0, 1, 0, 0, 5, 0], 5[4, 3, 4, 0, 0, 0, 0, 5, 5, 0, 1], 6[0, 0, 0, 4, 0, 4, 0, 0, 0, 0, 4], 7[0, 0, 0, 2, 0, 2, 5, 0, 0, 1, 2], 8[0, 0, 0, 0, 5, 0, 0, 0, 0, 4, 0], 9[1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0]
橫軸爲美食品種,分爲A--K 11中,豎軸爲用戶序號,有0-9 10我的。表內值爲某個用戶對某種美食的推薦分,0表示其不曾吃過,5分爲最高的推薦分。以上數據爲實驗虛構數據。app
給定一個用戶i,咱們根據上面的數據爲其推薦N個推薦分最高的美食。機器學習
協同過濾簡單來講是利用某興趣相投、擁有共同經驗之羣體的喜愛來推薦用戶感興趣的信息,我的經過合做的機制給予信息至關程度的迴應(如評分)並記錄下來以達到過濾的目的進而幫助別人篩選信息,迴應不必定侷限於特別感興趣的,特別不感興趣信息的紀錄也至關重要。函數
咱們也將採用協同過濾來實現商品推薦,並在下面的章節一步步實現基於協同過濾的商品推薦系統。學習
以上數據,不存在缺失和無心義推薦分,即不超出範圍,格式正確。大數據
如今基礎環境以及搞定了,咱們能夠用terminal安裝本身須要的包環境。同時能夠選擇python2或者python3的開發環境。並且左側的文件系統,支持本地文件的上傳下載等。spa
在推薦系統中,咱們須要計算兩我的或商品的類似度,咱們能夠採用餘弦類似度,皮爾遜相關係數等。3d
餘弦類似性經過測量兩個向量的夾角的餘弦值來度量它們之間的類似性。0度角的餘弦值是1,表示徹底同樣,而其餘任何角度的餘弦值都不大於1;而且其最小值是-1,類似度爲0。
皮爾遜相關係數( Pearson correlation coefficient),是用於度量兩個變量X和Y之間的相關(線性相關),其值介於-1與1之間。
新建文件recom.py,實現類似度計算函數
def cosSim(inA,inB): num = float(inA.T*inB) denom = la.norm(inA)*la.norm(inB) return 0.5+0.5*(num/denom)
在文件recom.py,實現推薦分計算
#dataMat 用戶與美食的矩陣 #user 用戶序號 #simMeas 類似度算法 #item 美食商品 def standEst(dataMat, user, simMeas, item): n = shape(dataMat)[1]#商品數 simTotal = 0.0; ratSimTotal = 0.0 for j in range(n):#全部商品,遍歷 userRating = dataMat[user,j]#user對該商品的推薦分 if userRating == 0: continue#若是user 未推薦該商品則過濾 #logical_and邏輯與,nonzero非零判斷,overLap爲均爲商品item,j推薦的用戶 overLap = nonzero(logical_and(dataMat[:,item].A>0, \ dataMat[:,j].A>0))[0] if len(overLap) == 0: similarity = 0 #以此overLap,計算兩商品的類似度。 else: similarity = simMeas(dataMat[overLap,item], \ dataMat[overLap,j]) 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 svdEst(dataMat, user, simMeas, item): n = shape(dataMat)[1] simTotal = 0.0; ratSimTotal = 0.0 U,Sigma,VT = la.svd(dataMat) #奇異值分解 Sig4 = mat(eye(4)*Sigma[: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
經過計算待推薦商品與已推薦商品的類似度,並乘以該用戶對已推薦商品的推薦分,來計算待推薦商品的推薦分。
在文件recom.py,加入recommend函數
#dataMat 用戶與美食的矩陣 #user 用戶序號 #N 推薦前N個商品 #simMeas 類似度計算算法 #estMethod 推薦分計算算法 def recommend(dataMat, user, N=3, simMeas=cosSim, estMethod=standEst): #找出user未評分的商品 unratedItems = nonzero(dataMat[user,:].A==0)[1]#find unrated items if len(unratedItems) == 0: return 'you rated everything' itemScores = [] #依次計算這些商品的推薦分 for item in unratedItems: estimatedScore = estMethod(dataMat, user, simMeas, item) itemScores.append((item, estimatedScore)) #返回前N個較好分的結果 return sorted(itemScores, key=lambda jj: jj[1], reverse=True)[:N]
若是是本地編輯的文件,能夠經過文件上傳方式上傳到服務器。
一般在計算類似度以前,咱們須要肯定是計算基於商品的類似度(上面的方式),仍是計算基於用戶的類似度。在現實狀況下,咱們要根據用戶和商品的數據決定選擇哪一種計算方式。同時,在數據量變大時,咱們一般須要先降維,在作商品推薦。部分代碼參考《機器學習實戰》,本篇文章主要介紹如何使用PAI-DSW實現算法實驗。
本文做者:伊逍
本文爲雲棲社區原創內容,未經容許不得轉載。