# -*- coding: utf-8 -*-
"""
Created on Thu Jan 13 15:09:14 2022
@author: he123456
"""
import matplotlib.pyplot as plt #可以用于绘图的库
from math import pow
import numpy #引用numpy库,用于对矩阵的处理
def matrix_factorization(R,P,Q,K):
result=[] #一个空列表
a=0.0002
b=0.02
for step in range(5000): #迭代次数
for i in range(len(R)):
for j in range(len(R[i])):
if R[i][j]!=0:
eij=R[i][j]-numpy.dot(P[i,:],Q[:,j]) #真实值减去预测值
for k in range(K): #对P和Q矩阵里的变量进行更新
P[i][k]=P[i][k]+a*(2*eij*Q[k][j]-b*P[i][k])
Q[k][j]=Q[k][j]+a*(2*eij*P[i][k]-b*Q[k][j])
loss=0
for i in range(len(R)):
for j in range(len(R[i])):
if R[i][j]!=0: #计算损失函数
loss=loss+pow(R[i][j]-numpy.dot(P[i,:],Q[:,j]),2)
for k in range(K): #贝塔部分
loss=loss+(b/2)*(pow(R[i][k],2)+pow(Q[k][j],2))
result.append(loss) #将损失函数值插入到列表中
if loss<0.001:
break
return P,Q,result
if __name__ == '__main__':
R=[
[5,3,0,1],
[4,0,0,1],
[1,1,0,5],
[0,1,5,4],
]
R=numpy.array(R)
N=len(R)
M=len(R[0])
K=2
P=numpy.random.rand(N,K) #得到随机分配的P和Q矩阵
Q=numpy.random.rand(K,M)
print("原始矩阵为:\n",R)
P1,Q1,LOSS= matrix_factorization(R,P,Q,K)
MR=numpy.dot(P1,Q1) #P1,Q1两个相乘
print("经过矩阵分解得到的矩阵:\n",MR)
#绘制损失函数图
n=len(LOSS)
x=range(n)
plt.plot(x,LOSS,color='r',linewidth=3)
plt.title("Convergence curve")
plt.xlabel("generation")
plt.ylabel("loss")
plt.show()
损失函数曲线