二、矩阵分解、正则化

 有如下R(5,4)的打分矩阵:(“-”表示用户没有打分)

其中打分矩阵R(n,m)是n行和m列,n表示user个数,m行表示item个数

那么,如何根据目前的矩阵R(5,4)如何对未打分的商品进行评分的预测(如何得到分值为0的用户的打分值)?

——矩阵分解的思想可以解决这个问题,其实这种思想可以看作是有监督的机器学习问题(回归问题)。

矩阵R可以近似表示为P与Q的乘积:R(n,m)≈ P(n,K)*Q(K,m)

矩阵分解的过程中,将原始的评分矩阵分解成两个矩阵的乘积: 

 

矩阵P(n,K)表示n个user和K个特征之间的关系矩阵,这K个特征是一个中间变量,矩阵Q(K,m)的转置是矩阵Q(m,K),矩阵Q(m,K)表示m个item和K个特征之间的关系矩阵,这里的K值是自己控制的,可以使用交叉验证的方法获得最佳的K值。为了得到近似的R(n,m),必须求出矩阵P和Q,如何求它们呢?

 

 【方法】

 1. 首先令

 2. 损失函数:使用原始的评分矩阵与重新构建的评分矩阵之间的误差的平方作为损失函数,即:

      如果R(i,j)已知,则R(i,j)的误差平方和为:

  最终,需要求解所有的非“-”项的损失之和的最小值:

 

 3. 使用梯度下降法获得修正的p和q分量:

  •   求解损失函数的负梯度:

     

 

  •        根据负梯度的方向更新变量:

     

 

 4. 不停迭代直到算法最终收敛(直到sum(e^2) <=阈值)

 

 

(Plus:为了防止过拟合,增加正则化项

正则化是在非正则的基础上进行的,所以代码中的运算是先求出初始损失函数值然后将求出来的值直接运用到下面的正则化中

【加入正则项的损失函数求解】

 1.  首先令

 2.  通常在求解的过程中,为了能够有较好的泛化能力,会在损失函数中加入正则项,以对参数进行约束,加入正则的损失函数为:

   

 

也即:

       

 

 3.  使用梯度下降法获得修正的p和q分量:

  •   求解损失函数的负梯度:

        

 

  •   根据负梯度的方向更新变量:

       

 

 4. 不停迭代直到算法最终收敛(直到sum(e^2) <=阈值)

 

【预测】利用上述的过程,我们可以得到矩阵这样便可以为用户 i 对商品  j 进行打分:

                 

 

 

 【Python代码实现如下】(基于Python 3.X ;使用正则项)

import matplotlib.pyplot as plt
from math import pow
import numpy

def matrix_factorzation(R,P,Q,K,steps=5000,alpha=0.0002,beta=0.02):
    Q=Q.T
    result=[]
    for step in range(steps):
        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[i][k]=P[i][k]+alpha*(2*eij*Q[k][j]-beta*P[i][k])
                        Q[k][j]=Q[k][j]+alpha*(2*eij*P[i][k]-beta*Q[k][j])
        eR=numpy.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]-numpy.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
    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=numpy.array(R)
       
    N=len(R)
    M=len(R[0])
    K=2
    P=numpy.random.rand(N,K)
    Q=numpy.random.rand(M,K)
        
    nP,nQ,result=matrix_factorzation(R,P,Q,K)
    print("原始的评分矩阵R为:\n",R)
    R_MF=numpy.dot(nP,nQ.T)
    print("经过MF算法评分后的矩阵是:\n",R_MF)
    #损失函数收敛曲线图
    n=len(result)
    x=range(n)
    plt.plot(x,result,color='r',linewidth=3)
    plt.title("Con")
    plt.xlabel("generation")
    plt.ylabel("loss")
    plt.show()

运行结果如下:

 

损失函数的收敛曲线图:

 

自己理解整理的:
在这里插入图片描述
在这里插入图片描述

  • 13
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值