#coding=utf-8 import numpy as np """手写FunkSVD """ def svd(M,P,Q,K,steps = 1000,alpha = 0.1,beta = 0.02): for step in range(steps): for i in range(M.shape[0]): for j in range(M.shape[1]): #有评分 if(M[i][j] > 0): P[i] = P[i] + alpha * ((M[i][j] - np.dot(P[i],Q[j].T))*Q[j] - beta * P[i]) Q[j] = Q[j] + alpha * ((M[i][j] - np.dot(P[i],Q[j].T))*P[i] - beta * Q[j]) loss = 0 num = 0 for i in range(M.shape[0]): for j in range(M.shape[1]): #对有评分的项目,计算损失 if(M[i][j] > 0): num += 1 loss += np.power(M[i][j] - np.dot(P[i],Q[j].T),2) loss = loss / num if(loss < 0.01): print("converge") break return P,Q
import numpy as np M = [ [5,3,0,1], [4,0,3,1], [1,1,0,5], [1,0,0,4], [0,1,5,4], ] M = np.array(M) """m =5 n = 4 k = 2""" P = np.random.rand(5,2) Q = np.random.rand(4,2) pre_P,pre_Q = svd(M,P,Q,2)
np.dot(pre_P,pre_Q.T)结果:
array([[ 4.98367253, 2.91060908, 3.7128969 , 1.01288104], [ 3.87878692, 2.27160978, 3.05057831, 0.95432853], [ 1.10472351, 0.82376277, 5.39209024, 4.94044258], [ 0.99498405, 0.72275465, 4.36574992, 3.9431948 ], [ 1.80832962, 1.19447539, 4.88735256, 4.0214381 ]])