专栏首页Flaneur的文章分享推荐系统之矩阵分解(MF)及其python实现

推荐系统之矩阵分解(MF)及其python实现

前言

        目前推荐系统中用的最多的就是矩阵分解方法,在Netflix Prize推荐系统大赛中取得突出效果。以用户-项目评分矩阵为例,矩阵分解就是预测出评分矩阵中的缺失值,然后根据预测值以某种方式向用户推荐。今天以“用户-项目评分矩阵R(M×N)”说明矩阵分解方式的原理以及python实现。

一、矩阵分解

1.案例引入

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

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

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

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

矩阵分解的过程中,,矩阵R可以近似表示为矩阵P与矩阵Q的乘积:

矩阵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,如何求它们呢?

2.推导步骤

  1. 首先令:
  1. 对于式子1的左边项,表示的是r^ 第i行,第j列的元素值,对于如何衡量,我们分解的好坏呢,式子2,给出了衡量标准,也就是损失函数,平方项损失,最后的目标,就是每一个元素(非缺失值)的e(i,j)的总和最小值
  1. 使用梯度下降法获得修正的p和q分量:
    • 求解损失函数的负梯度
    • 根据负梯度的方向更新变量
  2. 不停迭代直到算法最终收敛(直到sum(e^2) <=阈值,即梯度下降结束条件:f(x)的真实值和预测值小于自己设定的阈值)
  3. 为了防止过拟合,增加正则化项

3.加入正则项的损失函数求解

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

对正则化不清楚的,公式可化为:

  1. 使用梯度下降法获得修正的p和q分量:
    • 求解损失函数的负梯度
    • 根据负梯度的方向更新变量

4.预测

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

二、python代码实现

以下是根据上文的评分例子做的一个矩阵分解算法,并且附有代码详解。

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

def matrix_factorization(R,P,Q,K,steps=5000,alpha=0.0002,beta=0.02): #矩阵因子分解函数,steps:梯度下降次数;alpha:步长;beta:β。
    Q=Q.T                 # .T操作表示矩阵的转置
    result=[]
    for step in range(steps): #梯度下降
        for i in range(len(R)):
            for j in range(len(R[i])):
                    eij=R[i][j]-numpy.dot(P[i,:],Q[:,j])       # .DOT表示矩阵相乘
                    for k in range(K):
                      if R[i][j]>0:        #限制评分大于零
                        P[i][k]=P[i][k]+alpha*(2*eij*Q[k][j]-beta*P[i][k])   #增加正则化,并对损失函数求导,然后更新变量P
                        Q[k][j]=Q[k][j]+alpha*(2*eij*P[i][k]-beta*Q[k][j])   #增加正则化,并对损失函数求导,然后更新变量Q
        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:           #判断是否收敛,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)    #原矩阵R的行数
    M=len(R[0]) #原矩阵R的列数
    K=3    #K值可根据需求改变
    P=numpy.random.rand(N,K) #随机生成一个 N行 K列的矩阵
    Q=numpy.random.rand(M,K) #随机生成一个 M行 K列的矩阵
    nP,nQ,result=matrix_factorization(R,P,Q,K)
    print(R)         #输出原矩阵
    R_MF=numpy.dot(nP,nQ.T)
    print(R_MF)      #输出新矩阵
    #画图
    plt.plot(range(len(result)),result)
    plt.xlabel("time")
    plt.ylabel("loss")
    plt.show()

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • python动态规划解决矩阵连乘

            动态规划算法与分治法类似,其基本思想也就是将待求解的问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解,简单概括为自顶向下...

    Flaneur
  • K-means算法及python实现

            K-means(Thek-meansalgorithm)是机器学习十大经典算法之一,同时也是最为经典的无监督聚类(Unsupervised Cl...

    Flaneur
  • 多种相似度计算的python实现

            在机器学习中有很多地方要计算相似度,比如聚类分析和协同过滤。计算相似度的有许多方法,其中有欧几里德距离(欧式距离)、曼哈顿距离、Jaccard系...

    Flaneur
  • 《Unity3D 实战核心技术详解》书中关于矩阵的错误

    最近一直在学习实时渲染,不免要接触线性代数。而渲染中,一定会用到矩阵,当我再次去复习我之前看的书时,发现《Unity3D 实战核心技术详解》关于矩阵就有几处错误...

    meteoric
  • 数据分析与数据挖掘 - 06线性代数

    导数是高等数学中非常重要的知识点,也是人工智能的算法应用中比较常用的一个知识,这一章我们的重点就是讲解一下导数和其求导法则。首先我们来看一下导数的基本概念:函数...

    马一特
  • 数学实验(预习)

    也可以用初等变换求逆矩阵,构造一个n行2n列的矩阵(A E),并进行初等变换,A编程单位矩阵的时候,E就变成了A的逆矩阵.

    云深无际
  • 吹弹牛皮之Unity 引擎基础 - 矩阵(三)

    上图中展示了p,q两个基向量(单位向量)绕原点旋转后得到的新基向量p'和q'。根据勾股定理有:

    用户7698595
  • 吹弹牛皮之Unity 引擎基础 - 矩阵(一)

    沉迷于硬笔的练习偷懒了很长时间。过去的7月份仅仅更新了一篇文章,实在是深表遗憾。接着之前的向量篇小菜继续向下探索。谢谢大家长久来的鼓励和支持。

    用户7698595
  • 一起来学matlab-matlab学习笔记10 10_1一般运算符

    本文为matlab自学笔记的一部分,之所以学习matlab是因为其真的是人工智能无论是神经网络还是智能计算中日常使用的,非常重要的软件。也许最近其带来的一...

    DrawSky
  • 吴恩达机器学习笔记18-逆矩阵、矩阵转置

    “Linear Algebra review(optional)——Inverse and transpose”

    讲编程的高老师

扫码关注云+社区

领取腾讯云代金券