在本练习中,您将实现协作过滤,以构建电影推荐系统。
软件包
我们将使用现在熟悉的NumPy和Tensorflow软件包。
import numpy as np
import tensorflow as tf
from tensorflow import keras
from recsys_utils import *
1-概念
下面这段文字描述了一些符号和符号的含义,这些符号通常在协同过滤推荐系统中使用。
- 𝑟(𝑖,𝑗): 标量,如果用户 j 对游戏 i 进行了评分,𝑟(𝑖,𝑗) = 1,否则为 0。
- 𝑦(𝑖,𝑗): 标量,表示用户 j 对游戏 i 给出的评分(仅当 r(i,j) = 1 时定义)。
- 𝐰(𝑗): 向量,表示用户 j 的参数。
- 𝑏(𝑗): 标量,表示用户 j 的参数。
- 𝐱(𝑖): 向量,表示游戏 i 的特征评分。
- 𝑛𝑢: 用户的数量。
- 𝑛𝑚: 游戏的数量。
- 𝑛: 特征的数量。
- 𝐗: 向量 𝐱(𝑖) 的矩阵,表示游戏特征。
- 𝐖: 向量 𝐰(𝑗) 的矩阵,表示用户参数。
- 𝐛: 偏置参数向量 𝑏(𝑗)。
- 𝐑: 元素为 𝑟(𝑖,𝑗) 的矩阵,表示评分矩阵。
这些符号用于描述协同过滤推荐系统中的用户、游戏、评分和参数。通过使用这些符号,可以方便地表示和操作相关的变量和矩阵。
2-推荐系统
在这个实验室中,您将实现协作过滤学习算法,并将其应用于电影评级数据集。协同过滤推荐系统的目标是生成两个向量:对于每个用户,一个体现用户电影品味的“参数向量”。对于每部电影,都有一个相同大小的特征向量,它体现了对电影的一些描述。两个向量的点积加上偏差项应该会产生用户可能对该电影的评分的估计。
下图详细说明了如何学习这些向量。
下面这段文字描述了一个协同过滤推荐系统中的训练数据和参数学习过程。
- 𝑌 是一个矩阵,包含了电影的评分。评分的范围是从0.5到5,以0.5为步长。如果电影没有被评分,则相应的值为0。
- 𝑅 是一个矩阵,其中1表示电影已被评分,0表示电影未被评分。电影在行中,用户在列中。
- 每个用户都有一个参数向量 𝑤𝑢𝑠𝑒𝑟 和一个偏置值。
- 每个电影都有一个特征向量 𝑥𝑚𝑜𝑣𝑖𝑒。
- 这些向量是通过使用现有的用户/电影评分作为训练数据同时进行学习的。上面给出了一个训练示例:𝐰(1)⋅𝐱(1)+𝑏(1)=4。
- 值得注意的是,特征向量 𝑥𝑚𝑜𝑣𝑖𝑒 必须适应所有的用户,而用户向量 𝑤𝑢𝑠𝑒𝑟 必须适应所有的电影。这是这种方法名称的来源——所有的用户共同生成评分集。
简单来说,这段文字描述了在协同过滤推荐系统中使用现有的评分数据作为训练样本,通过学习用户参数向量和电影特征向量来预测缺失的评分。用户和电影的参数向量通过协同合作进行学习,以生成整个评分集。这个过程旨在捕捉用户和电影之间的相关性和偏好,从而提供个性化的推荐。
一旦学习了特征向量和参数,它们就可以用来预测用户对未分级电影的评分。如上图所示。该等式是预测用户一对电影零的评分的示例。
在本练习中,您将实现计算协作过滤目标函数的函数cofiCostFunc
。实现目标函数后,您将使用TensorFlow自定义训练循环来学习协同过滤的参数。第一步是详细说明实验室中使用的数据集和数据结构。
3-电影评分数据集
这段文字提供了关于MovieLens数据集和在练习中使用的矩阵的信息。以下是关键点的解释:
-
MovieLens数据集:该练习使用的数据集源自MovieLens的"ml-latest-small"数据集。原始数据集包含了600个用户对9000部电影的评分。
-
数据集尺寸缩减:为了侧重于2000年以后的电影,数据集的大小进行了缩减。缩减后的数据集包含了0.5到5之间以0.5为步长的评分。
-
数据集维度:缩减后的数据集包含了443个用户(𝑛𝑢)和4778部电影(𝑛𝑚)。
-
矩阵𝑌:矩阵𝑌是一个𝑛𝑚×𝑛𝑢的矩阵,用于存储评分𝑦(𝑖,𝑗)。每个元素𝑦(𝑖,𝑗)表示用户𝑗对电影𝑖的评分。
-
矩阵𝑅:矩阵𝑅是一个二值指示矩阵,与𝑌具有相同的维度。元素𝑅(𝑖,𝑗)等于1表示用户𝑗对电影𝑖进行了评分,等于0表示没有评分。该矩阵有助于确定𝑌中哪些条目是有效的评分。
在这部分练习中,您还将使用矩阵𝐗、𝐖和𝐛:
下面这段文字解释了矩阵𝐗、𝐖和向量𝐛的含义和结构。以下是关键点的解释:
-
𝐗矩阵:𝐗矩阵的第𝑖行对应于第𝑖部电影的特征向量𝑥(𝑖)。𝑥(𝑖)是一个𝑛维向量,表示第𝑖部电影的特征。在这个练习中,𝑛的取值为10,因此𝑥(𝑖)是一个包含10个元素的向量。𝐗是一个𝑛𝑚×10的矩阵,其中𝑛𝑚是电影的数量。
-
𝐖矩阵:𝐖矩阵的第𝑗行对应于第𝑗个用户的参数向量𝐰(𝑗)。𝐰(𝑗)是一个𝑛维向量,表示第𝑗个用户的参数。与𝐗类似,𝐰(𝑗)也包含10个元素。𝐖是一个𝑛𝑢×10的矩阵,其中𝑛𝑢是用户的数量。
-
𝐛向量:𝐛是一个预先计算的值向量。在这个练习中,它将被用于开发成本模型。
在这段文字中,提到了𝑌和𝑅矩阵将与电影数据集一起加载。同时,𝐗、𝐖和𝐛也会被加载,并且这些预先计算的值将在后面的实验中进行学习。
#Load data
X, W, b, num_movies, num_features, num_users = load_precalc_params_small()
Y, R = load_ratings_small()
print("Y", Y.shape, "R", R.shape)
print("X", X.shape)
print("W", W.shape)
print("b", b.shape)
print("num_features", num_features)
print("num_movies", num_movies)
print("num_users", num_users)
Y (4778, 443) R (4778, 443)
X (4778, 10)
W (443, 10)
b (1, 443)
num_features 10
num_movies 4778
num_users 443
# From the matrix, we can compute statistics like average rating.
tsmean = np.mean(Y[0, R[0, :].astype(bool)])
print(f"Average rating for movie 1 : {
tsmean:0.3f} / 5" )
Average rating for movie 1 : 3.400 / 5
这段代码计算了电影1的平均评分。让我逐步解释代码的含义:
Y[0, R[0, :].astype(bool)]
: 这部分代码使用索引操作符[]
来获取矩阵Y中的一部分数据。Y[0, :]
表示获取Y矩阵的第1行(电影1的评分数据)。R[0, :]
表示获取R矩阵的第1行(与电影1相关的评分指示器)。.astype(bool)
将R矩阵的元素转换为布尔类型,将非零值转换为True,零值转换为False。这样做是为了过滤掉没有评分的条目。
np.mean(Y[0, R[0, :].astype(bool)])
: 这部分代码使用NumPy库的mean
函数计算指定数据的平均值。在这里,我们计算了电影1的评分数据的平均值。即对电影1所有有评分的数据进行求平均。
f"Average rating for movie 1 : {tsmean:0.3f} / 5"
: 这部分代码使用了f-string格式化字符串的功能,将计算得到的平均评分tsmean插入到字符串中。:0.3f
表示将tsmean格式化为小数点后三位的浮点数。最终的输出是一个字符串,显示电影1的平均评分。因此,这段代码的作用是计算电影1的平均评分,并将结果打印输出。
“/ 5” 是表示评分的范围。在这个上下文中,评分的范围是从0.5到5,以0.5为步长,总共有10个等级。所以"/ 5" 的含义是将评分结果显示为在5分制下的评分等级
4-协作过滤学习算法
现在,您将开始实现协作过滤学习算法。您将从实现目标函数开始。
-
参数向量:协同过滤算法考虑了一组𝑛维参数向量,包括电影的参数向量𝐱(0),…,𝐱(𝑛𝑚−1),用户的参数向量𝐰(0),…,𝐰(𝑛𝑢−1),以及偏置向量𝑏(0),…,𝑏(𝑛𝑢−1)。这些参数向量用于预测用户𝑗对电影𝑖的评分𝑦(𝑖,𝑗)。
-
预测评分:模型通过计算内积𝐰(𝑗)⋅𝐱(𝑖)加上偏置𝑏(𝑖)来预测电影𝑖由用户𝑗的评分𝑦(𝑖,𝑗)。这个预测值表示为𝑦(𝑖,𝑗)=𝐰(𝑗)⋅𝐱(𝑖)+𝑏(𝑖)。
-
目标:给定一个由一些用户对一些电影产生的评分数据集,目标是学习参数向量𝐱(0),…,𝐱(𝑛𝑚−1),𝐰(0),…,𝐰(𝑛𝑢−1)和𝑏(0),…,𝑏(𝑛𝑢−1),以使其最佳拟合(最小化平方误差)。
这段文字提到了你需要完成的cofiCostFunc
代码,用于计算协同过滤的成本函数。在该函数中,你将计算协同过滤的成本函数,用于衡量预测评分与实际评分之间的差异。
4.1协同过滤成本函数
协同过滤成本函数由下式给出
(1)中的第一个总和是“对于所有𝑖, 𝑗。𝑟(𝑖,𝑗)=1并且可以写成:
您现在应该编写cofiCostFunc(协作过滤成本函数)来返回此成本。
练习1
循环实施:
首先使用for循环实现成本函数。考虑分两步开发成本函数。首先,在没有正则化的情况下开发成本函数。下面提供了一个不包括正则化的测试用例来测试您的实现。一旦这起作用,添加正则化并运行包括正则化的测试。请注意:当计算成本函数时,只有当𝑅(𝑖,𝑗)等于1时,才应该累积用户𝑗对电影𝑖的评分差异。也就是说,只有在用户对电影进行了评分的情况下,才会考虑该评分对成本函数的贡献。
正确答案:
#wuenda
# GRADED FUNCTION: cofi_cost_func
# UNQ_C1
def cofi_cost_func(X, W, b, Y, R, lambda_):
"""
Returns the cost for the content-based filtering
Args:
X (ndarray (num_movies,num_features)): matrix of item features
W (ndarray (num_users,num_features)) : matrix of user parameters
b (ndarray (1, num_users) : vector of user parameters
Y (ndarray (num_movies,num_users) : matrix of user ratings of movies
R (ndarray (num_movies,num_users) : matrix, where R(i, j) = 1 if the i-th movies was rated by the j-th user
lambda_ (float): regularization parameter
Returns:
J (float) : Cost
"""
nm, nu = Y.shape
n=W.shape[1]
J = 0