机器学习(ML)(十一) — 推荐系统探析

介绍

推荐系统(Recommendation system)的商业影响和实际使用案例数量甚至远远超过学术界的关注程度。每次你访问京东app、淘宝app、美团app等或腾讯视频等电影流媒体网站,或者访问提供短视频(抖音、快手)应用时,这类应用都会向你推荐他们认为你可能想买的东西、他们认为你可能想看的电影或他们认为你可能想尝试的餐馆。对于许多公司来说,很大一部分销售额是由他们的推荐系统(Recommendation system)推动的。因此,对于许多公司来说,推荐系统(Recommendation system)带来的经济效益或价值非常大。因此,我们很有必要深入了解一下什么是推荐系统(Recommendation system)。

我将使用预测电影评分的应用作为示例。假设您经营一家大型电影流媒体网站,您的用户使用一到五颗星对电影进行评分。因此,在典型的推荐系统(Recommendation system)中,您有一组用户,这里有四个用户Alice、Bob CarolDave。用户编号为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表示没有购买商品。问号表示没有看到商品。或者在社交媒体环境中,标签10可以表示用户在看到某项商品后是否喜欢或不喜欢该商品。问号表示用户尚未看到该商品,或者许多网站不要求用户明确评分,而是使用用户行为来猜测用户是否喜欢该商品。例如,您可以测量用户是否在某项商品上花费了至少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。第三部电影的评分为40,平均得分为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
2
3
4
5
6
7
8
9
10
11
w = tf.Varibale(3.0)
x, y = 1.0
alpha = 0.01
iterations = 30

for iter in range(iterations):
with tf.GradientTape() as tape:
costJ = (w*x - y)**2

[djdw] = tape.gradient(costJ, [w])
w.assign_add(-alpha * djdw)

w=tf.variable(3.0),参数初始化为3.0。设置x=1.0、y=1.0并将学习率(alpha)设置为0.01。运行梯度下降30次,即30次迭代。这是让TensorFlow自动为您计算导数的语法。TensorFlow有一个被称为梯度带(Gradient Tape)的工具。计算f(x)和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部电影,你需要决定在检索步骤中检索多少个项目?输入到排名步骤中。在检索步骤中,检索更多项目会带来更好的质量。但算法也会变得更慢,无法对分析或优化1005001000个项目做出权衡。这里建议离线实验。通过单独的检索步骤排名步骤,当下的推荐系统(Recommendation system)可以快速且准确的提供结果。因为检索步骤会删除影响内积的项目。而排名步骤会更好地预测用户喜欢的项目。这就是推荐系统即使在庞大的电影或产品目录上也能很好的工作。

尽管推荐系统(Recommendation system)为某些企业带来了丰厚的利润,但有些情况下却使整个社会丧失了公平。当使用推荐系统时,接下来看看推荐系统带来的一些问题和改进方法。在设计推荐系统时,推荐系统的目标是什么?实际上,许多公司会尝试显示最有可能被点击的广告以及广告商出价较高的广告,因为对于许多广告模型而言,公司获得的收入取决于广告是否被点击以及广告商对每次点击的出价。虽然这是一种利润最大化策略,但这种广告也可能产生一些负面影响。许多公司做的另一件事是尝试推荐产生最大利润的产品。如果今天访问网站并搜索产品,许多网站不会向您显示最相关的产品或最有可能购买的产品。而是试图向您展示将为公司带来最大利润的产品。如果某种产品对他们来说更有利可图,因为他们可以以更低的价格购买并以更高的价格出售,那么该产品在推荐中的排名就会更高。现在,许多公司都面临着利润最大化的压力。这似乎不是一件不合理的事情,但另一方面,从用户的角度来看,当一个网站向你推荐一个产品时,有时你会觉得如果网站能够向你透明地告知它决定向你展示什么?那就太好了。它是在试图最大化他们的利润,还是试图向你展示对你最有用的东西?在视频网站或社交媒体网站上,推荐系统也可以进行修改,向你展示能够带来最大观看时间的内容。具体来说,以广告为收入来源的网站往往会有动机让你在网站上停留很长时间。试图最大限度地延长你在网站上花费的时间获得更多向你展示更多广告的一种方式。如今,推荐系统用于最大限度地提高用户参与度或最大限度地延长某人在网站或特定应用上花费的时间。让我们更深入地研究一下这些潜在的问题。

广告业有时会成为一些最有害业务的放大器。它们也可能成为一些最好和最有成效的业务的放大器。让我举一个好例子和一个坏例子来说明。以旅游业为例。我认为在旅游业,成功的方式是努力为用户提供良好的旅行体验,真正努力为用户服务。如果有一家非常好的旅行社,他们可以向您出售前往理想目的地的旅行,并确保您和您的朋友和家人玩得开心。那么,我认为一个好的旅游业务最终往往会更有利可图。然后他们可以出更高的广告费。它可以支付更多的费用来吸引用户。由于有能力出更高的广告费,在线广告网站会更频繁地展示其广告,从而吸引更多用户访问这家优秀的公司。这是一个良性循环,您服务的用户越多,业务就越有利可图,您可以出更高的广告费,获得的流量就越多,等等。从统计上看,良性循环甚至可能有助于优秀的旅行社做得更好。让我们来看看有问题例子,例如,贷款行业往往收取极高的利率,而且通常针对的是低收入人群。在贷款行业取得成功的方法之一就是非常高效地从客户身上榨取每一分钱。如果有一家贷款公司非常善于剥削客户,真正从客户身上榨取每一分钱,那么这家公司就会更赚钱。因此,他们可以提高广告价格。因为他们可以获得更高的广告出价,所以他们会获得更多的流量。这让他们能够榨取更多的客户,吸引更多的人来获利。这反过来也会增加正反馈循环。此外,正反馈循环可能会导致最具剥削性、最有害的贷款公司获得更多的流量。这似乎与我们认为对社会有益的效果相反。我不知道是否有简单的解决方案。这些都是推荐系统面临的非常棘手的问题。一种改善方法是拒绝投放剥削性企业的广告。当然,说起来容易,但如何定义什么是剥削性业务?什么不是?这是一个非常困难的问题。但当我们为广告或其他东西构建推荐系统时,我认为这些问题是我们每个从事这些技术的人都应该问自己的,以便我们能够公开的讨论,从更多的人那里获得多种意见,并尝试提出改进方案,让推荐系统能够做更多有益的事情而不是潜在的危害。

让我们看一些其他例子,新闻中广泛报道,最大化用户参与度,例如某人在网站上观看视频的时间或某人在社交媒体上花费的时间。这导致大型社交媒体和视频共享网站放大阴谋论或仇恨和毒害性,因为阴谋论和某些类型的仇恨毒害性内容非常吸引人,并导致人们花费大量时间。即使放大阴谋论的效果放大了隐藏的毒害性,最终对个人和整个社会都是有害的。改善这一不完整和不完善的措施之一是尝试过滤掉有问题的内容,例如仇恨言论、欺诈、骗局,甚至某些类型的暴力内容。同样,我们到底应该过滤掉什么内容,这一定义出奇地难以制定。我认为这是个人、公司和政府必须继续努力解决的问题。最后一个例子。当用户访问许多应用程序或网站时,用户认为我向用户推荐的应用程序或网站会让他们喜欢。我认为许多用户没有意识到,许多应用程序和网站都在试图最大化他们的利润,而不是一种很好的体验。如果可能的话,我建议相关公司对用户保持透明,告诉他们推荐的标准是什么。这样做会增加信任,也会让我们的推荐系统对社会产生更多好处。推荐系统是一项非常强大的技术,非常有利可图,非常赚钱。但也有一些存在的问题。如果你正在使用推荐技术。我希望你不仅要考虑它带来的好处,还要考虑可能存在的危害。

在这个例子中,我们有两个密集层隐藏单元的数量在此处指定,最后一层有32个单元,输出32个数值。对于电影网络将它称为项目网络,因为电影是这里的项目,代码如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# the user network
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),
])

# the item network
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),
])

# create the user input and point to the base network
input_user = tf.keras.layout.Input(shape= (num_user_features))
vu = user_NN(input_user)
vu = tf.linalg.l2_normalize(vu, axis = 1)

# create the item input and point to the base network
input_item = tf.keras.layout.Input(shape= (num_user_features))
vm = item_NN(input_user)
vm = tf.linalg.l2_normalize(vu, axis = 1)

# measure the similarity of the two vector outputs
output = tf.keras.layers.Dot(axes = 1)([vu, vm])

# specify the inputs and output of the model
model = Model([input_user, input_item], output)

# specify the cost function
cost_fn = tf.keras.losses.MeanSquaredError()

这里耦合了密集隐藏层,是输出32个数值的层。对于隐藏层,使用默认的激活函数,即relu激活函数。接下来,需要告诉TensorFlow Keras如何将用户特征项目特征(即电影特征)提供给两个神经网络。这会提取用户的输入特征,然后将其提供给用户,我们在此定义了计算用户向量的方法。然后,一个额外的步骤是将向量标准化为长度设置为1。这个标准化长度,也称为l2范数。接下来对项目网络(电影网络)执行相同的操作。这会提取项目特征并将其提供在此定义的项目神经网络,并计算电影向量。最后,该步骤还会将该向量标准化长度为1。计算后,对这两个向量进行点积Keras有一个特殊的层类型,注意这里有tf.keras密集层。有一个特殊的Keras层,它们只是在两个向量之间取点积。我们将使用它来在向量之间取点积。这给出了神经网络的输出。最后,输入是用户特征电影或项目特征,输出是在上面定义的输出。这个模型的成本函数均方误差成本函数。这些是基于内容的过滤实现为神经网络的关键代码片段。还有一个步骤就是对向量的长度进行归一化,这会使算法工作得更好一些。TensorFlowsl2归一化函数,它可以对向量进行归一化,也称为对向量的l2范数进行归一化