• 【机器学习】使用tensorflow 实现协同过滤算法


    系列文章目录

    第十六章 Python 机器学习 入门之 协同过滤算法


    目录

    系列文章目录

    前言

    一、均值归一化

    二、利用TensorFlow  来实现协同过滤算法

    1 构建代价函数

    2 更新参数

    三、 寻找相关特征

    总结


    前言

    本文主要讲解如何使用tensorflow 来实现协同过滤算法,以及如何使用均值归一化来优化协同过滤算法和寻找相关特征。


    一、均值归一化

    均值归一化 mean normalization 有什么用?

    协同过滤算法中加入均值归一化可以使得算法运行的更多,结果更准确。

    下面来看看均值归一化的使用

    还是以之前的评价电影的例子来说,如果我们添加了一个人Eve, 他并没有对任何电影进行评论。

    如果我们在这个数据上训练一个协调过滤算法,通过代价函数我们得到参数的值,对于第五个人Eve ,我们的到的参数可以是 w=[0,0],b(5)=0。

    因为他没有给任何电影评分,使用参数w,b 不影响代价函数中的第一项,在这个平方误差代价函数中,我们希望代价函数的值尽可能的小,所以也就是希望参数w 的值尽可能的小,最后参数w 会取到0,参数b 的值我们并没有进行规定,也可以默认它的值为0。

    如果我们使用计算出来的参数值来预测评分,那么w*x+b ,最终5部电影的评分都是0,这就是使用均值归一化的原因,使用均值归一化可以避免这种情况。

    下面,我们来看看什么是均值归一化

    为了描述什么是均值归一化,我们将数据写成矩阵的形式。

    在这里,我们计算每一行的均值,然后写成一个列向量μ,表示每部电影的平均收视率,

    然后将每个评分减去评分的平均值,随后使用均值归一化后的值进行预测,

    为了避免预测结果出现负值,我们就可以在后面加上μ_i

    有了这些铺垫,我们再来看均值归一化后的数据对第五个用户Eve,对5部电影的预测,预测结果不是0了,而是评分均值了,很明显这样的评分比0评分是要好的。

    事实证明,通过将不同电影评分的均值归一化为0,优化算法推荐的系统也会运行得更快一点。

    它对于没有评价电影和评价电影数量很少的用户表现更好,预测结果也更合理。

    这里我们使用的是对矩阵的每一行标准化为均值为0,对于不同的问题,我们也可以对矩阵的列进行标准化。

    比如对于一部没有人看过的电影,想对其进行预测评分,那么对矩阵的列进行标准化效果是比较好的。

    二、利用TensorFlow  来实现协同过滤算法

    1 构建代价函数

    代码如下:

    1. # 方法一(按公式)
    2. def cost_func(X, W, b, Y, R, lambda_):
    3. nm, nu = Y.shape
    4. J = 0
    5. for j in range(nu):
    6. w = W[j, : ]
    7. b_j = b[0, j]
    8. for i in range(nm):
    9. x = X[i, : ]
    10. y = Y[i, j]
    11. r = R[i, j]
    12. J += np.square(r * (np.dot(w,x) + b_j - y))
    13. J += lambda_*(np.sum(np.square(W)) + np.sum(np.square(X)))
    14. J = J/2
    15. return J
    16. # 方法二 (使用矢量化)
    17. def cost_func(X, W, b, Y, R, lambda_):
    18. j = (tf.linalg.matmul(X, tf.transpose(W)) + b - Y)*R
    19. J = 0.5 * tf.reduce_sum(j**2) + (lambda_/2) * (tf.reduce_sum(X**2) + tf.reduce_sum(W**2))
    20. return J

    2 更新参数

    Tensor Flow 不仅可以构建神经网络模型,也可以用它来实现协同过滤算法。

    其关键点就在于,使用tensorflow可以自动找到代价函数的导数。这是tensorflow 的一个非常强大的功能,称为AuTo Diff, 它有时也被叫做AuTo Grad ,但是专业的术语还是AuTo Diff,

    而AuTo Grad 其实是做自动微分,自动取倒数的专用软件包的名称

    下面使用AuTo Diff来实现上面协同过滤算法的简化例子。 

    代码如下:

    1. import tensorflow as tf
    2. w = tf.Variable(3.0)  # 告诉tensorflow w 是一个变量,它是我们想要优化的参数
    3. # 设置其他参数
    4. x = 1.0
    5. y = 1.0   # y是目标值
    6. alpha = 0.01
    7. iterations = 30 #迭代次数
    8. for iter in range(iterations):      
    9.     with tf.GradientTape() as tape:   # 使用GradientTape()梯度磁带功能,tensorflow会自动记录步骤顺序,
    10.         fwb = w*x                     # 计算代价J 所需的成本序列,将序列保持在 tape 磁带中
    11.         costJ = (fwb - y)**2
    12.         
    13. [dJdw] = tape.gradient(costJ, [w])   # tensorflow 自动计算w 的倒数
    14. # tensorflow 变量,层变量需要特殊处理,使用assign_add() 函数来更新参数
    15. w.assign_add(-alpha * dJdw)
    16. # 使用tensorflow 的 梯度磁带功能,我们需要做的是告诉它,如何计算代价函数J 

    正常情况下使用AuTo Diff来实现协同过滤算法

    代码如下:

    1. import tensorflow as tf
    2. # 知指定优化器Adams, 设置学习速率
    3. optimizer = keras.optimizers.Adam(learning_rate = 1e-1)
    4. # 设置其他参数
    5. iterations = 200 #迭代次数
    6. for iter in range(iterations):      
    7.     with tf.GradientTape() as tape:   # 使用GradientTape()梯度磁带功能,tensorflow会自动记录步骤顺序,
    8.                                          # 计算代价J 所需的成本序列将序列保持在 tape 磁带中
    9.         cost_value = cofiCostFuncV(X, W, b, Ynorm, R, num_users, num_movies, lambda)  # 提供代码计算代价函数
    10.         
    11. grads = tape.gradient(cost_valuw, [X, W, b])   # tensorflow 自动计算X, W, b 的倒数
    12. #将优化器与刚刚计算的梯度一起使用
    13. optimizer.apply_gradients(zip(grads, [X, W, b]))

    三、 寻找相关特征

    我们学习了每个项目I 的特征x^(i),  它很难明确的学习到各个特征,比如说x1学习到这个电影是否是动作片,x2学习到这个电影是否是美国片等,这些是很难的。

    我们将学到的特征,统称为 x1、x2…… 等 ,表示关于这部电影的某些特征

    虽然学习不到哪些准确的特征,但是找到的这些特征都是与这部电影相关的。

    给定项目i的特征x^(i),如果我们想找到其它项目,比如说与电影i相关的其他电影,那么我们可以做的就是尝试找到项目k的x^(k), 类似于x^(i)。

    计算x^(k),与 x^(i)的平方距离,如果计算出来的距离值小的话,那就是相关的特征。

    如果我们发现不只是一部电影x^(k) 与 x^(i)之间的距离最小,比如说找到了5个相关的项目,那么如果用户在找某个电影Ii时,我们就可以将这几个相似的电影k推荐给他。


    总结

    使用tensorflow 来实现协同过滤算法还是比较简单的,因为auto diff  功能可以让计算机自己计算代价函数中的导数值,在进行参数更新时,这无疑是为我们省了不少事。除了协同过滤算法,还有一个推荐算法叫基于内容过滤算法,它可以很好的解决本文所指出的协同过滤算法存在的问题,虽然可以使用均值归一化来解决,但是还是会影响精度,而基于内容过滤算法就可以很好的解决这一点,后面我们会学到。

  • 相关阅读:
    【Windows】磁盘管理无法删除卷
    三七互娱,oppo,快手25届暑期实习内推
    可验证的idea才是真的
    公钥密码和中国剩余定理
    SDN落地场景
    什么是产品思维
    【pytorch笔记】第六篇 卷积原理和卷积层
    Ubuntu20.04 中已经安装 Pytorch 但 Import 报错 - 解决记录
    【MySQL】MySQL 慢SQL如何避险
    E - Replace Digits(线段树)
  • 原文地址:https://blog.csdn.net/m0_51816252/article/details/126286199