手写FunkSVD分解

#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 ]])


猜你喜欢

转载自blog.csdn.net/js54100804/article/details/79669006