(一般是多用户回归的例子)
预测电影评价,根据用户对一些电影的评价去给他推荐电影(这里的评分是0~5星)
然后我们要预测用户对某部电影的评价分数会是多少
电影名 | 中文翻译 | 用户1 评分 | 用户2 评分 | 用户3 评分 | 用户4 评分 |
---|
Love at last | 真心男儿 | 5 | 5 | 0 | 0 |
Romance forever | 罗曼史 | 5 | ? | ? | 0 |
Cute puppies of love | 可爱小狗 | ? | 4 | 0 | ? |
Nonstop car chases | 汽车追逐 | 0 | 0 | 5 | 4 |
Swrods vs. karate | 剑客vs空手道 | 0 | 0 | 5 | ? |
电影的特征是什么?比如用 浪漫程度、动作程度 作为特征
电影名 | 中文翻译 | 用户1 评分 | 用户2 评分 | 用户3 评分 | 用户4 评分 | x1(浪漫程度) | x2(动作程度) |
---|
Love at last | 真心男儿 | 5 | 5 | 0 | 0 | 0.9 | 0 |
Romance forever | 罗曼史 | 5 | ? | ? | 0 | 1.0 | 0.01 |
Cute puppies of love | 可爱小狗 | ? | 4 | 0 | ? | 0.99 | 0 |
Nonstop car chases | 汽车追逐 | 0 | 0 | 5 | 4 | 0.1 | 1.0 |
Swrods vs. karate | 剑客vs空手道 | 0 | 0 | 5 | ? | 0 | 0.9 |
一些参数符号:
一些参数:nu=nm=n=i j k x(i)=w(j)=b(j)=y^(i,j)=452xm(i)=vm(i)wu(j)=vu(j)bu(j)w(j)⋅x(i)+b(j)用户数(User)电影数(Movie)特征数电影序用户序特征序?第i部电影的特征第j个用户的特征_1第j个用户的特征_2拟合模型
可以用电影特征+用户喜好预测用户评价:
尝试用电影3的特征+用户1的喜好,来预测用户1对电影3的评价: w(1)=b(1)=x(3)=y^(3,1)==[50]0[0.990]w(1)⋅x(3)+b(1)4.95第1个用户 模型参数第1个用户 模型参数第3部电影的特征第1个用户对第3部电影的评价
Loss函数依然是平方误差公式,成本函数为:
w(j),b(j)minJ(w(j),b(j))=2m(j)1i:r(i,j)=1∑(w(j)⋅x(i)+b(j)−y(i,j))2+2m(j)λk=1∑n(wk(j))2
前面的x1和x2是已经给出的,这期会学习如何自动得出
电影名 | 中文翻译 | 用户1 评分 | 用户2 评分 | 用户3 评分 | 用户4 评分 | x1(浪漫程度) | x2(动作程度) |
---|
Love at last | 真心男儿 | 5 | 5 | 0 | 0 | ? | ? |
Romance forever | 罗曼史 | 5 | ? | ? | 0 | ? | ? |
Cute puppies of love | 可爱小狗 | ? | 4 | 0 | ? | ? | ? |
Nonstop car chases | 汽车追逐 | 0 | 0 | 5 | 4 | ? | ? |
Swrods vs. karate | 剑客vs空手道 | 0 | 0 | 5 | ? | ? | ? |
既可以用电影特征+用户喜好预测用户评价:
尝试用电影3的特征+用户1的喜好,来预测用户1对电影3的评价: w(1)=b(1)=x(3)=y^(3,1)==[50]0[0.990]w(1)⋅x(3)+b(1)4.95第1个用户 模型参数第1个用户 模型参数第3部电影的特征第1个用户对第3部电影的评价
也可以用用户评价计算电影特征:
尝试用4个用户的评分,来绩电影1的特征: w(1)=[50]b(1)=0w(2)=[50]b(2)=0w(3)=[05]b(3)=0w(4)=[05]b(4)=0 因为 y^(i,j)=w(j)⋅x(i)+b(j),w(1)⋅x(1)≈5w(2)⋅x(1)≈5w(3)⋅x(1)≈0w(4)⋅x(1)≈0⎭⎬⎫ x(1)=[10]
那么将两者结合,协同过滤算法:
用代价函数去学习:w(1),b(1),⋯,w(nu),b(nu):minJ(w(1),b(1),⋯,w(nu),b(nu))=21j=1∑nui:r(i,j)=1∑(w(j)⋅x(i)+b(j)−y(i,j))2+2λj=1∑nuk=1∑n(wk(j))2 用代价函数去学习:x(1),⋯,x(nm):minJ(x(1),x(2),⋯,x(nm))=21i=1∑nmj:r(i,j)=1∑(w(j)⋅x(i)+b(j)−y(i,j))2+2λi=1∑nmk=1∑n(xk(i))2 将他们组合起来:minJ(w,b,x)=21(i,j):r(i,j)=1∑(w(j)⋅x(i)+b(j)−y(i,j))2+2λj=1∑nuk=1∑n(wk(j))2+2λi=1∑nmk=1∑n(xk(i))2
梯度下降,最优化
wi(j):=wi(j)−α∂wi(j)∂J(w,b,x)b(j):=b(j)−α∂b(j)∂J(w,b,x)xk(i):=xk(i)−α∂xk(i)∂J(w,b,x)
二进制标签,例如:喜欢、赞、点击过
(Binary labels:favs, likes and clicks)
实例应用举例:
- 用户J在被展示后购买了商品吗?
- 用户J是否喜欢某件物品?
- 用户J是否在该项上花费了至少30秒的时间?
- 用户J是否点击了一个项目?
电影名 | 中文翻译 | 用户1 点赞 | 用户2 点赞 | 用户3 点赞 | 用户4 点赞 |
---|
Love at last | 真心男儿 | 1 | 1 | 0 | 0 |
Romance forever | 罗曼史 | 1 | ? | ? | 0 |
Cute puppies of love | 可爱小狗 | ? | 1 | 0 | ? |
Nonstop car chases | 汽车追逐 | 0 | 0 | 1 | 1 |
Swrods vs. karate | 剑客vs空手道 | 0 | 0 | 1 | ? |
接下来的做法就是将上一个例子中的线性回归变成逻辑回归:
通用成本函数:f(w,b,x)(x)=g(w(j)⋅x(i)+b(j)) 预测的成本函数:minJ(w,b,x)=21(i,j):r(i,j)=1∑(w(j)⋅x(i)+b(j)−y(i,j))2+2λj=1∑nuk=1∑n(wk(j))2+2λi=1∑nmk=1∑n(xk(i))2 二元分类的成本函数:Loss:L(f(w,b,x)(x),y(i,j))=−y(i,j)log(f(w,b,x)(x))−(1−y(i,j))log(1−f(w,b,x)(x))minJ(w,b,x)=21(i,j):r(i,j)=1∑L(f(w,b,x)(x),y(i,j))
手动实现(使用梯度下降)
w = tf.Variable(3.0)
x = 1.0
y = 1.0 # 目标值
alpha = 0.01
iterations = 30
for iter in range(iterations):
# 使用TensorFlow的渐变磁带来记录步骤
# 用来计算成本J,以实现自动微分
with tf.GradientTape() as tape:
fwb = w*x
costJ = (fwb-y)**2
# 使用梯度带计算成本相对于参数w的梯度
[dJdw] = tape.gradient(costJ, [w])
# 通过更新w的值来运行一步梯度下降以降低成本
w.assign_add(-alpha * dJdw)
TensorFlow包实现
# 实例化一个优化器
optimizer = keras.optimizers.Adam (learnina rate=1e-1)
iterations = 200
for iter in range (iterations):
# 使用TensorFlow的GradientTape来记录用于计算成本的操作
with tf.GradientTape() as tape:
# 计算成本 (前向传递包含在成本中)
cost_value = cofiCostruncV(X, W, b, Ynorm, R,
num_users, num_movies, lambda)
# 使用梯度带自动检索可训练变量相对于损失的梯度
grads = tape.gradient( cost_value, [X,W,b] )
# 通过更新变量的值来运行一步梯度下降,以最小化Loss
optimizer.apply_gradients ( zip(grads, [X,W,b]) )

话说矩阵的归一化,挺常见的。之前学unity shared时,好像也有过类似的操作
均值归一化作用:能使算法运行得更快一点
假如有一个新用户,他没有对任何一部电影评分,我们要去预测他的行为,那么要先将原来的数据进行 均值归一化
这样可以规范那一列,好处是如果有一大群新用户,那么会有数列都是0。进行矩阵运算时,能十分好地去简化运算,使运算更快


假如有一部新电影,也需要去均值归一化吗?去规范那一行吗?
好像说是不如新用户需求高,可以不均值归一化
另外,对于推荐算法,一开始就不要将这部没有评分的电影展示给太多用户
项目i的特征x(i)很难解释,要找到与之相关的其他项。
找到与x(i)相似的x(k),从而找到与项i相似的项k(比如找到与某电影相关的其他电影)
也就是,找最小的距离的项:
l=1∑n(xl(k)−xl(i))2
Q:Cold Start(?冷启动?)问题,如何去:
- 新项:对那些几乎没有用户评价过的新项进行排名?
- 新用户:向评分数很少的新用户展示一些合适的东西?
A:可以使用项或用户的侧面信息:
- 项:类型、电影明星、工作室
- 用户:人口统计 (年龄,性别,地址),表现的喜好,……
原理
- 协同过滤:
- 基于内容过滤:
- 根据用户和项目的特点向您推荐项目,以找到合适的匹配项
工作方式
- 用户特征:xu(j)对应
user[j]
- 电影特征:xm(i)对应
movie[i]
比如
w(j)⋅x(i)→vu(j)⋅vm(j) 用户特征:xuj=vu(j)=4.90.1⋮3.0likeslikes⋮ likes 电影特征:xmi=vm(i)=4.50.2⋮3.5浪漫程度动作程度⋮
将用户网络和电影网络回执成两个独立的神经网络,然后再将他们合并成一个单一的神经网络


成本函数:
minJ(vu,vm)=21(i,j):r(i,j)=1∑(vu(j)⋅vm(i)−y(i,j))2+2λj=1∑nuk=1∑n(vu,k(j))2+2λi=1∑nmk=1∑n(vm,k(i))2
Q:目的:去寻找与电影i相似的其他电影
A:实现:即求尽量小的∣∣vm(k)−vm(i)∣∣2
# 用户的神经网络
user_NN = tf.keras.models.sequential([
tf.keras.layers.Dense (256, activation='relu'),
tf.keras.layers.Dense (128, activation='relu'),
tf.keras.layers.Dense (32)
])
# 项目的神经网络
item_NN = tf.keras.models.sequential([
tf.keras.layers.Dense (256, activation='relu'),
tf.keras.layers.Dense (128, activation='relu'),
tf.keras.layers.Dense (32)
])
# 创建用户输入并指向基本网络
input_user = tf.keras.layers.Input(shape=(num_user_features)) # 用户输入
vu = user_NN(input_user) # 用户神经网络的输出vu
vu = tf.linalg.l2_normalize (vu, axis=1) # 正则化
# 创建项目输入并指向基本网络
input_item = tf.keras.layers.Input(shape=(num_item_features)) # 项目输入
vm = item_NN(input_item) # 项目神经网络的输出vm
vm = tf.linalg.l2_normalize (vm, axis=1) # 正则化
# 测量两个矢量输出的相似度
output = tf.keras.layers.Dot(axes=1)([vu,vm]) # 点乘两个神经网络输出
# 指定模型的输入和输出
model = Model([input_user, input_item], output)
# 指定成本函数
cost_fn = tf.keras.losses.MeanSquaredError() # 平方误差成本函数
比如:
- 电影,可能有上千部可供推荐
- 广告,可能有上百万的广告可推荐
- 歌曲,可能有上千万首歌可以推荐
- 商品,可能有上千种商品可以推荐
两个步骤:检索和排名
检索:
排名:
- 使用学习模型获取检索到的列表和排序
- 将排序项显示给用户
检索步骤
- 检索更多的条目可以获得更好的性能,但推荐速度更慢
- 为了分析/优化交易,进行离线实验,看看检索额外的项目是否会获得更多的相关奖励
(即,向用户显示的p(y(i,j))=1的项目更多)
推荐制度的目标是什么?
推荐:
- 最有可能被用户评为五星级的电影
- 最有可能购买的产品
- 最有可能被点击的广告
- 产生最大利润的产品
- 导致最大观看时间的视频
这里面可能会有一些伦理问题
例如:
贷款业,推荐系统可能会帮助从用户那里进行剥削
改进:不接受剥削性企业的广告。但这往往是比较难定义的问题
用户参与最大化(如观看时间)已导致大型社交媒体/视频分享网站 放大阴谋论和仇恨/毒性
改进:过滤掉有问题的内容,如仇恨言论、欺诈、诈骗和暴力内容。
一个排名系统能以透明的方式来实现你的利润最大化而不是用户的福利吗?
改进:对用户透明