對數據集movie ml-100kpython
有用戶,電影,評分,時間戳四個數據字段, 以用戶-電影組成的評分矩陣R,能夠用SVD方法轉化成兩個因子矩陣P,Q ,用兩個因子的乘積R'來做爲原先矩陣的近似,R因爲用戶看的電影數目及一個電影所能吸引用戶的數量,決定了R是稀疏的,然而R'是R的近似,相對於R是稠密的,於是能夠經過減少他們之間的偏差來計算獲得R',進而對於沒有看過某類電影的用戶給個預估分,這就能直觀的看出用戶對於電影的興趣,進而考慮是否推薦app
首先是最小化目標函數dom
def prediction(P,Q): return np.dot(P.T,Q) lmbda = 0.1 k = 20 m, n = R.shape # R是由用戶-電影組成的評分矩陣 訓練集 n_epochs = 100 # 迭代數 gamma=0.01 P = 3 * np.random.rand(k,m) # 對P,Q 隨機取初始值 Q = 3 * np.random.rand(k,n) # 計算RMSE def rmse(I,R,Q,P): return np.sqrt(np.sum((I * (R - prediction(P,Q)))**2)/len(R[R > 0])) #存儲偏差,可用matplotlib畫圖顯示偏差變化 train_errors = [] test_errors = [] users,items = R.nonzero() for epoch in xrange(n_epochs): for u, i in zip(users,items): e = R[u, i] - prediction(P[:,u],Q[:,i]) # 公式5 P[:,u] += gamma * ( e * Q[:,i] - lmbda * P[:,u]) # 公式4 Q[:,i] += gamma * ( e * P[:,u] - lmbda * Q[:,i]) # 公式3 train_rmse = rmse(I,R,Q,P) # I表示與R相同規模的矩陣,R的元素不爲0時相應位置爲1,爲0置爲0 test_rmse = rmse(I2,T,Q,P) # T爲R同樣,是測試集 train_errors.append(train_rmse) test_errors.append(test_rmse)