推荐系统之矩阵分解(MF)及其python实现
完整代码如下
from math import *
import numpy as np
import matplotlib.pyplot as plt
def MF(R,P,Q,K,aplha,beta,steps):
'''
:param R: 用户-物品评分矩阵 m*n
:param P: 用户的分解矩阵 m*k
:param Q: 物品的分接矩阵 m*k
:param K: 隐向量的维度
:param aplha: 学习率
:param beta: 正则化参数
:param steps:
:return:
'''
print('开始分解原矩阵')
Q=Q.T
result=[]
print('开始训练')
for step in range(steps):
''''''
for i in range(len(R)):
for j in range(len(R[i])):
eij=R[i][j]-np.dot(P[i,:],Q[:,j])
for k in range(K):
if R[i][j]>0:
P[i][k]=P[i][k]+aplha*(2*eij*Q[k][j]-beta*P[i][k])
Q[k][j]=Q[k][j]+aplha*(2*eij*P[i][k]-beta*Q[k][j])
eR=np.dot(P,Q)
e=0
for i in range(len(R)):
for j in range(len(R[i])):
if R[i][j] > 0:
e = e + pow(R[i][j] - np.dot(P[i, :], Q[:, j]), 2)
for k in range(K):
e = e + (beta / 2) * (pow(P[i][k], 2) + pow(Q[k][j], 2))
result.append(e)
if e < 0.001:
break
print('training Finshed 。。。。')
return P, Q.T, result
if __name__ == '__main__':
R=[
[5,3,0,1],
[4,0,0,1],
[1,1,0,5],
[1,0,0,4],
[0,1,5,4]
]
R=np.array(R)
N=len(R)
M=len(R[0])
K=3
P=np.random.rand(N,K)
Q=np.random.rand(M,K)
nP,nQ,result=MF(R,P,Q,K,aplha=0.0002,beta=0.02,steps=5000)
print(result)
print('原矩阵',R)
R_MF=np.dot(nP,nQ.T)
print('计算出的矩阵',R_MF)
plt.plot(range(len(result)),result)
plt.xlabel("time")
plt.ylabel("loss")
plt.show()