机器学习(ML)(十一) — 推荐系统探析
介绍
推荐系统(Recommendation system
)的商业影响和实际使用案例数量甚至远远超过学术界的关注程度。每次你访问京东app
、淘宝app
、美团app
等或腾讯视频等电影流媒体网站,或者访问提供短视频(抖音、快手)应用时,这类应用都会向你推荐他们认为你可能想买的东西、他们认为你可能想看的电影或他们认为你可能想尝试的餐馆。对于许多公司来说,很大一部分销售额是由他们的推荐系统(Recommendation system
)推动的。因此,对于许多公司来说,推荐系统(Recommendation system
)带来的经济效益或价值非常大。因此,我们很有必要深入了解一下什么是推荐系统(Recommendation system
)。
我将使用预测电影评分的应用作为示例。假设您经营一家大型电影流媒体网站,您的用户使用一到五颗星对电影进行评分。因此,在典型的推荐系统(Recommendation system
)中,您有一组用户,这里有四个用户Alice、Bob Carol
和Dave
。用户编号为1、2、3、4
。以及一组电影《爱在最后》、《浪漫永恒》、《可爱的小狗》、《不停歇的汽车追逐》和《剑与空手道》。用户所做的就是将这些电影评为一到五颗星。假设Alice
给《爱在最后》评了五颗星,给《浪漫永恒》评了五颗星。也许她还没有看过《可爱的小狗》,所以没有对这部电影进行评分。则通过问号来表示,她认为《不停歇的汽车追逐》和《剑与空手道》应该得零颗星等。在推荐系统(Recommendation system
)中,你有一定数量的用户和一定数量的项目。在这种情况下,项目是您想要推荐给用户的电影。尽管在这个例子中使用的是电影,但同样的逻辑或同样的东西也适用于任何东西,从产品或网站到餐馆,甚至推荐哪些媒体的文章、要展示的社交媒体文章,对用户感到更有趣的东西。这里使用的符号是Dallas Alice
对电影1
进行了评分,但尚未对电影3
进行评分,因此1
进行了评分,但3
进行评分。最后使用2
对电影3
的评分等于Recommendation system
)框架,解决问题的一种方法是查看用户尚未评分的电影。并尝试预测用户对这些电影的评分,因为这样我们就可以尝试向用户推荐他们更有可能评为五星的电影。
如果我们有每件商品的特征或每部电影的特征,我们该如何开发一个推荐系统?这里四个用户对五部电影中的部分电影进行了评分。在这里添加了两个特征0.9
,并且它不是一部动作电影。所以这个特征取0
。《不停歇的汽车追逐》中只有一点点浪漫。所以它的值为0.1
,但它有大量的动作。所以这个特征取值为1.0
。这时的用户数量表示为:Alice
的电影评分。假设预测电影0.99
,第二个特征为0
。我们的预测将是Alice
对《爱在最后》和《永远的浪漫》这两部非常浪漫的电影给出了高评分,但对动作片《不停歇的汽车追逐》和《剑与空手道》给出了低评分。所以对于《可爱的小狗的爱》预测给出4.95
分似乎很合理。因此,参数Alice
来说似乎是很合理的模型。对于多个用户来说,只需添加一些符号。在这里添加上标1
,表示用户1
的参数4
个用户中的每一个设置不同的参数。将用户4
个用户中的每一个拟合不同的线性回归模型。让我们看看如何为该算法制定成本函数。这里注意,如果用户4
部电影,则3
部电影,则1
。这类似于用于线性回归的成本函数。这就是Recommendation system
)来说,
协同过滤
如果每部电影都有特征,例如特征1
的参数4
,
为了简化这个例子,我们将设置Alice
给第一部电影的评分是5
,则Bob
给它评分也是5
,所以1、0
,在这种情况下,
推荐系统(Recommendation system
)或协同过滤算法都涉及到了二元标签,如何从线性回归到逻辑回归,再到预测数字,再到预测二元标签,这是一个带有元标签的协同过滤数据集的示例。标签1
指出用户喜欢某部电影。意味着Alice
从头到尾看完了电影《爱在最后》和《浪漫永恒》。问号通常表示用户尚未看该商品,因此无法决定是否对该特定商品点赞或收藏。如何将协同过滤算法应用于此数据集。在具有二元标签的协同过滤中,有很多方法可以定义标签1
和标签0
。在一个在线购物网站中,标签可以表示用户1
表示购买了商品,标签0
表示没有购买商品。问号表示没有看到商品。或者在社交媒体环境中,标签1
或0
可以表示用户在看到某项商品后是否喜欢或不喜欢该商品。问号表示用户尚未看到该商品,或者许多网站不要求用户明确评分,而是使用用户行为来猜测用户是否喜欢该商品。例如,您可以测量用户是否在某项商品上花费了至少30
秒。如果是,则将其标记为1
;如果用户看到了某项商品但没有花费至少30
秒,则将其标记为0
。如果用户尚未看到该商品,则将其标记为问号。另一种根据用户行为隐式生成评分的方法是查看用户是否点击了某项商品。这通常在在线广告中完成,如果用户看到了广告,如果他们点击了该广告,则将其标记为1
,如果他们没有点击,则将其标记为0
;如果用户甚至没有看到该广告,则标记为问号。这些二元标签通常具有以下粗略含义。1
表示用户在看到某件商品后参与其中,而参与可能意味着他们点击或花费30
秒或明确喜欢或想购买该商品。0
表示用户在看到该商品后没有参与,问号表示该商品尚未显示给用户。给定这些二元标签,该算法与线性回归非常相似,可以预测这些二元输出。之前,我们预测标签
在构建推荐系统(Recommendation system
)时。如果先进行均值归一化,则性能会更好一些。也就是说,如果将电影评分归一化为具有一致的平均值,又有什么结果?为了解释均值归一化,需要添加第五个用户Eve
,她还没有对任何电影进行评分。添加均值归一化将有助于算法对用户Eve
做出更好的预测。如果要在这个数据集上训练协同过滤算法,会得到第五个用户的参数Eve
,Eve
还没有对任何电影进行评分,所以参数Eve
的电影评分在这个平方误差成本函数中不起作用。Eve
对所有电影的评分将是Eve
的所有问号)放入二维矩阵中。只是为了以更持久、更紧凑的方式写出所有评分(包括问号)。要进行均值归一化,我们要做的就是获取所有这些评分,并计算每部电影的平均评分。因此,电影一有两个 5 分和两个 0 分,因此平均评分为 2.5。电影二有一个 5 分和一个 0 分,因此平均评分为 2.5。第三部电影的评分为4
和0
,平均得分为2
。第四部电影的平均评分为2.25
。第五部电影不太受欢迎,平均评分为1.25
。将这五个数字全部收集到一个向量中,我将这个向量称为5
。减去平均评分2.5
,得到2.5
。这部电影的评分是0
星。减去2.25
,得到-2.25
的评分,依此类推,现在包括新用户 Eve
在内的五个用户以及所有五部电影都是如此。然后,右边的这些新值将成为1
对电影一给出了2.5
分,对电影四给出了-2.25
分。然后利用此方法,您可以像之前一样为电影Eve
还没有给任何电影打过分,那么可能会学习参数1
的预测评分,将预测Eve
的评分Eve
可能会给这部电影打2.5
分似乎更合理,而不是认为Eve
会给所有电影打零分,因为她还没有给任何电影打分。事实上,这种算法的效果是,它将导致新用户Eve
的初始猜测恰好等于其他用户对这五部电影的评分的平均值。取电影的平均评分似乎比猜测Eve
的所有评分都是零更合理。事实证明,将不同电影评分的平均值归一化为0
,推荐系统(Recommendation system
)也会运行得更快一些。但这确实使算法对没有评分过任何电影或评分过很少电影的用户表现更好。预测也会变得更加合理。这就是均值归一化。它使算法运行得更快。当有用户对很少的电影甚至根本没有电影进行过评分时,算法能够给出更好、更合理的预测。均值归一化将使推荐系统(Recommendation system
)工作得更好。
我们接下来了解如何使用TensorFlow
实现协同过滤算法。TensorFlow
对于构建其他类型的机器学习算法也非常有用。例如协同过滤算法。为了实现梯度下降,您需要找到成本函数的导数,但TensorFlow
可以自动找出成本函数的导数。需要做的就是实现成本函数,无需了解任何微积分,无需自己求导,您只需几行代码即可获得TensorFlow
来计算该导数项,该导数可用于优化成本函数。接下来看看这一切是如何工作的。在第一个线性回归示例中。设置了TensorFlow
可以解决这个问题。使用一个非常简单的成本函数为:TensorFlow
可以自动计算此导数项。下面的代码实现:
1 | w = tf.Varibale(3.0) |
w=tf.variable(3.0)
,参数3.0
。设置x=1.0、y=1.0
并将学习率(alpha
)设置为0.01
。运行梯度下降30
次,即30
次迭代。这是让TensorFlow
自动为您计算导数的语法。TensorFlow
有一个被称为梯度带(Gradient Tape
)的工具。计算TensorFlow
将自动记录步骤序列。这是启用自动微分所必需的。接下来,TensorFlow
将在梯度带中保存操作序列。TensorFlow
自动计算此导数项,将其称为dJdw
。这是TensorFlow
的一个非常强大的功能,称为Auto Diff
。其他一些机器学习包,如Pytorch
,也支持Auto Diff
。如何使用Auto Diff
实现协同过滤算法。一旦可以自动计算导数,不仅限于梯度下降。还可以用于adam
优化算法。
如果您访问在线购物网站(如淘宝或京东),正在查看特定商品(例如某本书),网站可能会向您显示“这里有一些与本书类似的其他书籍”之类的信息。网站是如何做到这一点的?当您查看某件商品时,它会向您显示其他类似或相关的商品供您考虑。协同过滤算法提供了一种查找相关商品的好方法。学习了每个商品的特征5
个或10
个电影,那么您最终会找到与项目5
个或10
个项目。
如果你正在构建一个网站,希望帮助用户找到与他们正在查看的特定产品相关的产品,那么这将是一个不错的方法,因为特征IP
地址,这可以告诉您很多有关用户位置的信息,了解用户的位置也可能有助于您猜测用户可能对什么感兴趣,或者是否知道用户是通过移动设备还是桌面设备访问您的网站,或者是否知道他们正在使用哪种Web
浏览器。所有这些都是可以获得的线索。它们可以与用户的偏好惊人地相关。尽管协同过滤(多个用户对多个项目进行评分)是一组非常强大的算法,但它也有一些局限性。
内容过滤
接下来讲解第二种推荐系统(Recommendation system
),即基于内容的过滤算法。首先,将协同过滤方法与基于内容的过滤方法进行对比。对于协同过滤,一般会根据给出相似评分的用户的评分推荐商品。一些用户对某些商品给出了评分,算法会利用这些评分推荐新商品。相比之下,基于内容的过滤方法将根据用户的特征和商品的特征来推荐商品。换句话说,它需要每个用户的一些特征以及每个商品的一些特征,并使用这些特征来尝试确定哪些商品和用户可能彼此匹配。使用基于内容的过滤算法。基于内容的过滤将继续使用200
个国家/地区,那么也可以有一个具有大约200
个可能值的独热特征。你还可以查看用户过去的行为来构建此特征向量。例如,如果查看目录中的前1000
部电影,您可能会构建1000
个特征。如果有一组电影,并且知道每部电影属于哪种类型,那么用户给出的每个类型的平均评分是多少。在用户评分的所有爱情电影中,平均评分是多少?在用户评分的所有动作电影中,平均评分是多少?所有其他类型也是如此。这个特征的一个有趣之处在于它实际上取决于用户给出的评分。但这并没有错。构建一个取决于用户评分的特征向量是一种完全可以开发特征向量来描述该用户的方法。有了这些特征,你就可以得到一个特征向量1500
个,而电影特征可能只有50
个。在基于内容的过滤中,我们将开发一种匹配用户和电影的学习算法。之前,将用户32
。总结一下,在协同过滤中,需要让大量用户对不同的项目进行评分。相比之下,在基于内容的过滤中,有用户的特征和项目的特征,希望用一种方法来找到用户和项目之间的良好匹配。我们需要计算这些向量,
使用深度学习实现基于内容的过滤算法是一个好方法。给定一个描述用户的特征向量,例如年龄、性别、国家等,必须计算向量
它将用户的特征列表32
个单元,因此32
个值列表。与之前使用的大多数神经网络不同,最后一层不是只有一个单元的层,而是32
个单元的层。同样,计算电影的向量
该网络以电影的特征作为输入,并通过神经网络的几层输出S
型函数,并用它来预测
在上图中的上半部分,我们有用户网络,它的输入是32
的向量,它描述了具有这些特征32
的向量,它描述了一部具有这些特征
推荐系统(Recommendation system
)有时需要从数千、数百万、数千万项目的目录中挑选出一些项目进行推荐。如何做到这一点?一个大型电影流媒体网站可能有数千部电影,或者一个广告系统。可能有数百万个广告目录可供选择。或者一个音乐流媒体网站可能有数千万首歌曲可供选择。大型在线购物网站可能有数百万甚至数千万种产品可供选择。当用户浏览网站时,他们会提供一些特征。如果你需要把数千万个项目输入到神经网络,以便预测产品。每次用户访问网站时,就必须运行神经网络推理数千万次,这在计算上是无法实现的。许多推荐系统都是通过两个步骤来实现,这两个步骤称为检索和排名。其原理是在检索(也叫召回)中生成大量合理的候选项目列表。它试图涵盖您可能推荐给用户的许多可能的项目。如果包含用户不太喜欢的项目,那么在排名中进行微调并挑选出最佳项目推荐给用户。
这里有一个示例,在检索中,针对用户观看过的最近10
部电影中的每一部,找出10
部中最相似的电影。例如,如果用户使用向量3
种类型的电影添加进来。假设用户看过很多爱情电影、很多喜剧电影和很多历史剧。然后将这三种类型中排名前10
的电影添加到候选项目列表中。接下来将用户所在国家/地区的排名前20
的电影添加到此列表中。因此,这个检索步骤可以非常快速地完成,您最终会得到一个包含100
部或数百部推荐电影的列表。但如果它包含一些用户不喜欢的电影,那也没有关系。检索步骤的目标是确保覆盖范围广泛,以便拥有足够多的电影,至少其中有很多好电影。最后,我们将在检索步骤中检索到的所有项目合并到一个列表中。删除重复项,删除用户已经看过或已经购买过的项目,以及不想被再次推荐的项目。第二步是排名步骤。在排名步骤中,将获取在检索步骤中检索到的列表。这可能包含数百部的电影,并使用机器学习模型对它们进行排名。意味着将把用户特征向量和电影特征向量输入到神经网络中。然后为每个用户-电影对计算预测评分。基于此,现在有了100
多部电影,即用户最有可能给出高评分的电影。然后,可以根据预测评分显示项目的排名列表。对于所有电影,需要做的就是对神经网络的进行一次推理,计算100
部电影,你需要决定在检索步骤中检索多少个项目?输入到排名步骤中。在检索步骤中,检索更多项目会带来更好的质量。但算法也会变得更慢,无法对分析或优化100
、500
或1000
个项目做出权衡。这里建议离线实验。通过单独的检索步骤和排名步骤,当下的推荐系统(Recommendation system
)可以快速且准确的提供结果。因为检索步骤会删除影响内积的项目。而排名步骤会更好地预测用户喜欢的项目。这就是推荐系统即使在庞大的电影或产品目录上也能很好的工作。
尽管推荐系统(Recommendation system
)为某些企业带来了丰厚的利润,但有些情况下却使整个社会丧失了公平。当使用推荐系统时,接下来看看推荐系统带来的一些问题和改进方法。在设计推荐系统时,推荐系统的目标是什么?实际上,许多公司会尝试显示最有可能被点击的广告以及广告商出价较高的广告,因为对于许多广告模型而言,公司获得的收入取决于广告是否被点击以及广告商对每次点击的出价。虽然这是一种利润最大化策略,但这种广告也可能产生一些负面影响。许多公司做的另一件事是尝试推荐产生最大利润的产品。如果今天访问网站并搜索产品,许多网站不会向您显示最相关的产品或最有可能购买的产品。而是试图向您展示将为公司带来最大利润的产品。如果某种产品对他们来说更有利可图,因为他们可以以更低的价格购买并以更高的价格出售,那么该产品在推荐中的排名就会更高。现在,许多公司都面临着利润最大化的压力。这似乎不是一件不合理的事情,但另一方面,从用户的角度来看,当一个网站向你推荐一个产品时,有时你会觉得如果网站能够向你透明地告知它决定向你展示什么?那就太好了。它是在试图最大化他们的利润,还是试图向你展示对你最有用的东西?在视频网站或社交媒体网站上,推荐系统也可以进行修改,向你展示能够带来最大观看时间的内容。具体来说,以广告为收入来源的网站往往会有动机让你在网站上停留很长时间。试图最大限度地延长你在网站上花费的时间获得更多向你展示更多广告的一种方式。如今,推荐系统用于最大限度地提高用户参与度或最大限度地延长某人在网站或特定应用上花费的时间。让我们更深入地研究一下这些潜在的问题。
广告业有时会成为一些最有害业务的放大器。它们也可能成为一些最好和最有成效的业务的放大器。让我举一个好例子和一个坏例子来说明。以旅游业为例。我认为在旅游业,成功的方式是努力为用户提供良好的旅行体验,真正努力为用户服务。如果有一家非常好的旅行社,他们可以向您出售前往理想目的地的旅行,并确保您和您的朋友和家人玩得开心。那么,我认为一个好的旅游业务最终往往会更有利可图。然后他们可以出更高的广告费。它可以支付更多的费用来吸引用户。由于有能力出更高的广告费,在线广告网站会更频繁地展示其广告,从而吸引更多用户访问这家优秀的公司。这是一个良性循环,您服务的用户越多,业务就越有利可图,您可以出更高的广告费,获得的流量就越多,等等。从统计上看,良性循环甚至可能有助于优秀的旅行社做得更好。让我们来看看有问题例子,例如,贷款行业往往收取极高的利率,而且通常针对的是低收入人群。在贷款行业取得成功的方法之一就是非常高效地从客户身上榨取每一分钱。如果有一家贷款公司非常善于剥削客户,真正从客户身上榨取每一分钱,那么这家公司就会更赚钱。因此,他们可以提高广告价格。因为他们可以获得更高的广告出价,所以他们会获得更多的流量。这让他们能够榨取更多的客户,吸引更多的人来获利。这反过来也会增加正反馈循环。此外,正反馈循环可能会导致最具剥削性、最有害的贷款公司获得更多的流量。这似乎与我们认为对社会有益的效果相反。我不知道是否有简单的解决方案。这些都是推荐系统面临的非常棘手的问题。一种改善方法是拒绝投放剥削性企业的广告。当然,说起来容易,但如何定义什么是剥削性业务?什么不是?这是一个非常困难的问题。但当我们为广告或其他东西构建推荐系统时,我认为这些问题是我们每个从事这些技术的人都应该问自己的,以便我们能够公开的讨论,从更多的人那里获得多种意见,并尝试提出改进方案,让推荐系统能够做更多有益的事情而不是潜在的危害。
让我们看一些其他例子,新闻中广泛报道,最大化用户参与度,例如某人在网站上观看视频的时间或某人在社交媒体上花费的时间。这导致大型社交媒体和视频共享网站放大阴谋论或仇恨和毒害性,因为阴谋论和某些类型的仇恨毒害性内容非常吸引人,并导致人们花费大量时间。即使放大阴谋论的效果放大了隐藏的毒害性,最终对个人和整个社会都是有害的。改善这一不完整和不完善的措施之一是尝试过滤掉有问题的内容,例如仇恨言论、欺诈、骗局,甚至某些类型的暴力内容。同样,我们到底应该过滤掉什么内容,这一定义出奇地难以制定。我认为这是个人、公司和政府必须继续努力解决的问题。最后一个例子。当用户访问许多应用程序或网站时,用户认为我向用户推荐的应用程序或网站会让他们喜欢。我认为许多用户没有意识到,许多应用程序和网站都在试图最大化他们的利润,而不是一种很好的体验。如果可能的话,我建议相关公司对用户保持透明,告诉他们推荐的标准是什么。这样做会增加信任,也会让我们的推荐系统对社会产生更多好处。推荐系统是一项非常强大的技术,非常有利可图,非常赚钱。但也有一些存在的问题。如果你正在使用推荐技术。我希望你不仅要考虑它带来的好处,还要考虑可能存在的危害。
在这个例子中,我们有两个密集层,隐藏单元的数量在此处指定,最后一层有32
个单元,输出32
个数值。对于电影网络将它称为项目网络,因为电影是这里的项目,代码如下所示。
1 | # the user network |
这里耦合了密集隐藏层,是输出32
个数值的层。对于隐藏层,使用默认的激活函数,即relu
激活函数。接下来,需要告诉TensorFlow Keras
如何将用户特征和项目特征(即电影特征)提供给两个神经网络。这会提取用户的输入特征,然后将其提供给用户,我们在此定义了计算用户向量1
。这个标准化长度,也称为l2
范数。接下来对项目网络(电影网络)执行相同的操作。这会提取项目特征并将其提供在此定义的项目神经网络,并计算电影向量1
。计算Keras
有一个特殊的层类型,注意这里有tf.keras
密集层。有一个特殊的Keras
层,它们只是在两个向量之间取点积。我们将使用它来在向量TensorFlows
有l2
归一化函数,它可以对向量进行归一化,也称为对向量的l2
范数进行归一化。