美文网首页
NLP面试-基于矩阵分解的推荐算法(转载)

NLP面试-基于矩阵分解的推荐算法(转载)

作者: 致Great | 来源:发表于2018-08-20 15:38 被阅读265次

原文:https://blog.csdn.net/google19890102/article/details/51124556

1 基本思想

在推荐系统中,我们常常遇到这样的问题:我们有很多用户和物品,以及部分用户对商品的评分,我们希望预测目标用户对其他未评分物品的评分,进而将评分高的物品推荐给用户。

下面一组基本的数据:用户-物品的评分矩阵,如下图所示:


image

矩阵分解是指将一个矩阵分解成两个或者多个矩阵的乘积。对于上述的用户-商品矩阵(评分矩阵),记为Rm×n。可以将其分解成两个或者多个矩阵的乘积,假设分解成两个矩阵Pm×k和Qk×n,我们要使得矩阵Pm×k和Qk×n的乘积能够还原原始的矩阵Rm×n:


那么接下来的问题是如何求解矩阵Pm×k和Qk×n的每一个元素,可以将这个问题转化成机器学习中的回归问题进行求解。

2 相关理论

2.1 损失函数

可以使用原始的评分矩阵Rm×n与重新构建的评分矩阵R^m×n之间的误差的平方作为损失函数,即:


损失函数

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


2.2 损失函数的求解

对于上述的平方损失函数,可以通过梯度下降法求解,梯度下降法的核心步骤是

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


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



    通过迭代,直到算法最终收敛。

2.3 加入正则项的损失函数即求解方法

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



利用梯度下降法的求解过程为:

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


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



    通过迭代,直到算法最终收敛。

3 代码实现

from numpy import *

def load_data(path):
    f = open(path)
    data = []
    for line in f.readlines():
        arr = []
        lines = line.strip().split("\t")
        for x in lines:
            if x != "-":
                arr.append(float(x))
            else:
                arr.append(float(0))
        #print arr
        data.append(arr)
    #print data
    return data

def gradAscent(data, K):
    dataMat = mat(data)
    print dataMat
    m, n = shape(dataMat)
    p = mat(random.random((m, K)))
    q = mat(random.random((K, n)))

    alpha = 0.0002
    beta = 0.02
    maxCycles = 10000

    for step in xrange(maxCycles):
        for i in xrange(m):
            for j in xrange(n):
                if dataMat[i,j] > 0:
                    #print dataMat[i,j]
                    error = dataMat[i,j]
                    for k in xrange(K):
                        error = error - p[i,k]*q[k,j]
                    for k in xrange(K):
                        p[i,k] = p[i,k] + alpha * (2 * error * q[k,j] - beta * p[i,k])
                        q[k,j] = q[k,j] + alpha * (2 * error * p[i,k] - beta * q[k,j])

        loss = 0.0
        for i in xrange(m):
            for j in xrange(n):
                if dataMat[i,j] > 0:
                    error = 0.0
                    for k in xrange(K):
                        error = error + p[i,k]*q[k,j]
                    loss = (dataMat[i,j] - error) * (dataMat[i,j] - error)
                    for k in xrange(K):
                        loss = loss + beta * (p[i,k] * p[i,k] + q[k,j] * q[k,j]) / 2

        if loss < 0.001:
            break
        #print step
        if step % 1000 == 0:
            print loss

    return p, q


if __name__ == "__main__":
    dataMatrix = load_data("./data")

    p, q = gradAscent(dataMatrix, 5)
    '''
    p = mat(ones((4,10)))
    print p
    q = mat(ones((10,5)))
    '''
    result = p * q
    #print p
    #print q

    print result

4 参考资料

相关文章

网友评论

      本文标题:NLP面试-基于矩阵分解的推荐算法(转载)

      本文链接:https://www.haomeiwen.com/subject/gnrliftx.html