与许多机器学习技术一样,推荐系统根据用户的历史行为进行预测。推荐系统是一种信息过滤系统,具体来说,是根据用户的历史行为、社交关系、兴趣点。来预测用户对一组项目的偏好。
推荐系统在某些行业中非常重要,因为它们在高效时可以产生巨额收入,也是从竞争对手中脱颖而出的一种方式。作为推荐系统重要性的证明,我们可以提一下,几年前,Netflix组织了一个挑战赛(“Netflix奖”),其目标是产生一个性能比自己的算法更好的推荐系统并获得奖励100万美元的奖金。
要构建推荐系统,最典型的两种方法是
其中协同过滤又分为基于记忆(memorybased)和基于模型(Modelbased)两种方法,接下来我们将重点探讨它们的原理、优缺点等。
如果我们的分类(或回归)是基于用户特征的,我们说这种方法是以项目为中心的:建模、优化和计算可以“按项目”完成。在这种情况下,我们基于用户特征构建和学习一个模型,试图回答“每个用户喜欢这个项目的概率是多少?”这个问题。(或者“每个用户给这个项目的评分是多少?”)。通常有许多用户与某一个项目进行交互,因此得出的模型是基于稳健性的。然而,考虑到学习模型的交互来自每个用户,即使这些用户具有相似的特征(特征),他们的偏好也可能不同。这意味着虽然这种方法更鲁棒,但是它比之后的以用户为中心的方法更不具有个性化。
如果我们正在研究项目特征,则该方法以用户为中心:建模、优化和计算可以“由用户”完成。然后,我们根据项目特征按用户训练一个模型,试图回答“这个用户喜欢每个项目的概率是多少?”。此时,我们可以为每个用户训练一个模型,所获得的模型比以项目为中心的模型更具个性化推荐,因为它只考虑了来自所研究用户的交互。然而,大多数时候用户与相对较少的项目进行交互,因此,我们获得的模型远不如以项目为中心的模型鲁棒。
从实际的角度来看,在大多数情况下,得到新用户一些信息(用户不想回答太多问题)比得到有关新物品的大量信息要困难得多。(因为使用过这些物品的人有兴趣填写这些信息,以便将他们的项目推荐给正确的用户)。我们还可以注意到,根据要表达的关系的复杂性,我们构建的模型可能从简单到复杂:线性回归到深度神经网络。最后,让我们提一下,基于内容的方法既可以以用户为中心,也可以项目为中心:关于用户和项目的信息都可以用于我们的模型,例如通过堆叠两个特征向量并构建神经网络架构。
让我们首先考虑以项目为中心的分类的情况:对于每个项目,我们想要训练一个贝叶斯分类器,该分类器将用户特征作为输入并输出“喜欢”或“不喜欢”。所以,为了完成分类任务,我们要计算pitem(like∣userfeatures)pitem(dislike∣userfeatures)\frac{p_{item}(like|user_{features})}{p_{item}(dislike|user_{features})}pitem(dislike∣userfeatures)pitem(like∣userfeatures)具有给定特征的用户喜欢所考虑的项目的概率与其不喜欢它的概率之间的比率。定义我们的分类规则(具有简单阈值)的条件概率比率可以按照贝叶斯公式表示pitem(like∣userfeatures)pitem(dislike∣userfeatures)=pitem(userfeatures∣like)×pitem(like)pitem(userfeatures∣dislike)×pitem(dislike)\frac{p_{item}(like|user_{features})}{p_{item}(dislike|user_{features})}=\frac{p_{item}(user_{features}|like)\timesp_{item}(like)}{p_{item}(user_{features}|dislike)\timesp_{item}(dislike)}pitem(dislike∣userfeatures)pitem(like∣userfeatures)=pitem(userfeatures∣dislike)×pitem(dislike)pitem(userfeatures∣like)×pitem(like)
其中:pitem(like)p_{item}(like)pitem(like)是先验概率,可以通过之前的数据计算。
pitem(∣like)p_{item}(·|like)pitem(∣like)是条件概率,这是贝叶斯模型中最重要的一部分,首先朴素贝叶斯假设各特征之间是条件独立的。这样我们就可以将条件概率进行拆解。
当特征是离散型数据时,只要很方便的统计训练样本中各个划分在每个类别中出现的频率即可用来估计P(userfeaturei∣like)P(user_{feature_i}|like)P(userfeaturei∣like)。
下面重点讨论特征属性是连续值的情况。
当特征是连续型数据:通常假定其值服从高斯分布(也称正态分布)。因此只要计算出训练样本中各个类别中此特征项划分的各均值和标准差,代入正态分布的公式即可得到需要的估计值。均值与标准差的计算在此不再赘述。
另一个需要讨论的问题就是当P(userfeaturei∣like)=0P(user_{feature_i}|like)=0P(userfeaturei∣like)=0怎么办,当某个类别下某个特征项划分没有出现时,就会产生这种现象,这会令分类器质量大大降低。为了解决这个问题,我们引入拉普拉斯平滑法,它的思想非常简单,就是对没类别下所有划分的计数加1,这样如果训练样本集数量充分大时,并不会对结果产生影响,并且解决了上述频率为0的尴尬局面。
协同过滤是一种动态的方法。协同过滤除了用户对一组项目的历史偏好之外,不需要其他任何东西。因为它基于历史数据,所以这里的核心假设是过去喜欢的用户在未来也会喜欢。在用户偏好方面,通常以两类来表示。明确评级,是用户给一个滑动比例的项目的比率,比如泰坦尼克号的5星评分。这是用户最直接的反馈,表明他们有多喜欢一个项目。ImplicitRating,间接反应用户偏好,例如页面浏览量、点击量、购买记录、是否听音乐曲目等。在本文中,我们将仔细研究协同过滤,它是推荐系统的传统且强大的工具。
推荐系统的协同过滤是仅基于用户和项目之间记录的过去交互以产生新推荐的方法。这些交互存储在的“用户-项目交互矩阵”中。
然后,协同过滤方法的主要思想是这些过去的用户-项目交互以检测相似的用户和/或相似的项目,并根据这些估计的相似度度进行预测。
协同过滤算法的类别分为两个子类别,通常称为基于记忆的方法和基于模型的方法。基于记忆的方法直接使用记录的交互值,假设没有模型,并且基本上是基于最近邻搜索(例如,从感兴趣的用户中找到最近的用户并给他们推荐在这些用户中最受欢迎的项目)。基于模型的方法假设一个潜在的“生成”模型来解释用户-项目的交互并尝试发现它以做出新的预测。
然而,由于它只考虑过去的交互来进行推荐,协同过滤存在“冷启动问题”:不可能向新用户推荐任何东西或向任何用户推荐新项目,并且许多用户或项目的太少的交互得到有效处理。这个缺点可以通过不同的方式解决:向新用户推荐随机项目或向随机用户推荐新项目(随机策略),向新用户推荐流行项目或向最活跃用户推荐新项目(最大期望策略),推荐一组不同的新用户的项目或一组不同用户的新项目(探索性策略),或者最后,对用户或项目的早期使用非协同过滤方法。下面,我们将主要介绍三种经典的协同过滤方法:两种基于记忆的方法(用户-用户和项目-项目)和一种基于模型的方法(矩阵分解)。
用户-用户和项目-项目的方法主要特征在于它们仅使用来自用户-项目交互矩阵的信息并且他们假设没有模型来产生新的推荐。
为了向用户做出新的推荐,用户-用户方法粗略地尝试识别具有最相似“交互概况”的用户(最近的邻居),以便推荐在这些邻居中最受欢迎的项目(并且这些项目对于我们的用户而言是新的)。
通俗的来说就是首先根据用户的历史数据信息对其进行分类,然后推荐在同一类用户受欢迎的项目。例如A、B、C三个用户是很相似的,现在A、B用户经常购买D产品,但是C用户从来没买过,我们可以向C用户推荐D产品。
这种方法被称为“以用户为中心”,因为它根据用户与项目的交互来表示用户并评估用户之间的距离。
假设我们想为给定用户做出推荐。首先,每个用户都可以用它与不同项目的交互向量(交互矩阵的每一行)来表示。然后,我们可以计算我们感兴趣的用户和其他所有用户之间的某种“相似性”。该相似性度量使得在相同项目上具有相似交互的两个用户应被视为接近。一旦计算出与每个用户的相似度,我们就可以将k个最近邻的用户,然后建议其中最受欢迎的项目(仅查看我们的参考用户尚未与之交互的项目)。
为了向用户提出新的推荐,item-item方法的想法是找到与用户已经“积极”交互过的项目相似的项目。如果与两个项目交互的大多数用户都以相似的方式进行操作,则认为两个项目是相似的。这种方法被称为**“以项目为中心”**,因为它基于用户与他们的交互来表示项目,并评估这些项目之间的距离。
假设我们想为给定用户做出推荐。首先,我们考虑这个用户最喜欢的项目,并通过它与每个用户的交互向量(交互矩阵中的“它的列”)来表示它(与所有其他项目一样)。然后,我们可以计算“最佳项目”与所有其他项目之间的相似性。一旦计算出相似性,我们就可以保留k个最近邻的项目给我们感兴趣的用户推荐这些项目。
用户-用户方法基于在与项目的交互方面搜索相似用户。一般来说,每个用户只与几个项目进行交互,这使得该方法对任何记录的交互都非常敏感(高方差)。另一方面,由于最终推荐仅基于与我们感兴趣的用户相似的用户记录的交互,因此我们获得了更加个性化的结果(低偏差)。相反,item-item方法是基于在用户-item交互方面搜索相似的item。因为一般来说,很多用户都与一个项目进行了交互,所以邻域搜索对单个交互的敏感度要低得多(较低的方差)。作为对应,来自各种用户的交互(甚至是与我们的参考用户非常不同的用户)然后在推荐中被考虑,使得该方法不那么个性化(更多偏见)。因此,这种方法不像用户-用户方法那样个性化,但更鲁棒。
复杂度和副作用
基于模型的协同过滤方法仅依赖于用户-项目交互信息,并假设一个潜在模型应该解释这些交互。例如,矩阵分解算法(MatrixFactorization)包括将巨大而稀疏的用户-项目交互矩阵分解为两个较小且密集的矩阵的乘积:一个用户-因素矩阵(包含用户表示)乘以一个因素-项目矩阵(包含项目表示)
例如,考虑我们有一个用户电影评分矩阵。为了对用户和电影之间的交互进行建模,我们可以假设
但是,我们不想将这些特征明确地赋予我们的模型(因为它可以用于我们稍后将描述的基于内容的方法)。相反,我们更愿意让系统自己发现这些有用的特征,并自动对用户和物品进行表示。由于它们是学习而不是给出的,因此单独提取的特征具有数学意义,但没有直观的解释。然而,这种算法最终产生的结构非常接近人类可以想到的直观分解。事实上,这种分解的结果是,在偏好方面接近的用户以及在特征方面接近的项目最终在潜在空间中具有接近的表示。
矩阵分解的数学解释
接下来我们将简单的介绍矩阵分解的数学概述。更具体地说,我们描述了一种基于梯度下降的经典迭代方法,它可以在不将所有数据同时加载到计算机内存中的情况下获得非常大矩阵的分解。让我们考虑一个包含评分的交互矩阵M(nxm),其中每个用户仅对某些项目进行了评分
其中大多数为None,表示用户对该电影暂无评分,在推荐系统任务重,往往这个评分矩阵是一个十分稀疏的矩阵。矩阵分解要做的是预测出矩阵中缺失的评分,使得预测评分能反映用户的喜欢程度。我们想要分解该矩阵,使得:M=XYTM=XY^TM=XYT其中X是用户矩阵(UserMatrix)(n×l),每一行代表一个用户,Y项目矩阵(ItemMatrix)(l×k),每一列代表一个物品。
这里l是表示用户和项目的潜在空间的维度。因此,我们搜索矩阵X和Y,其点积最接近现有交互。将E表示成对(i,j)的集合,使得MijM_{ij}Mij不是空值,我们想要找到最小化“评分误差”的X和Y(X,Y)=min∑Mij≠0[Mij(Xi)(Yj)T]2(X,Y)=min\sum_{M_{ij}\neq0}[M_{ij}-(X_i)(Y_j)^T]^2(X,Y)=minMij=0∑[Mij(Xi)(Yj)T]2添加一个L2正则化,我们得到:(X,Y)=min12∑Mij≠0[Mij(Xi)(Yj)T]2+λ2(∑i,k(Xik)2+∑j,k(Yjk)2)(X,Y)=min\frac{1}{2}\sum_{M_{ij}\neq0}[M_{ij}-(X_i)(Y_j)^T]^2+\frac{\lambda}{2}(\sum_{i,k}(X_{ik})^2+\sum_{j,k}(Y_{jk})^2)(X,Y)=min21Mij=0∑[Mij(Xi)(Yj)T]2+2λ(i,k∑(Xik)2+j,k∑(Yjk)2)我们要做的就是最小化上面这个损失函数。这个时候就是一个最优化的过程。以如何从评分矩阵中分解出User矩阵和Item矩阵,只有左侧的评分矩阵M是已知的,User矩阵和Item矩阵是未知。为了学习出User矩阵和Item矩阵,使得User矩阵*Item矩阵与评分矩阵中已知的评分差异最小(最优化问题)
然后可以通过梯度下降求解获得矩阵X和Y,我们可以注意到两件事。首先,不必在每一步对E中的所有计算梯度,我们可以只考虑这些对的一个子集,以便我们“批量”优化我们的目标函数。其次,X和Y中的值不必同时更新,并且梯度下降可以在每个步骤中交替地在X和Y上完成(这样做,我们认为一个矩阵是固定的,并在下一步执行相反的操作之前优化另一个矩阵迭代),假设得到结果如下:
一旦矩阵被分解,我们就可以用更少的信息来做出新的推荐:我们可以简单地将用户向量乘以任何项目向量,以估计相应的评分。请注意,我们还可以将用户-用户和项目-项目方法用于用户和项目的这些新表示:(近似)最近邻搜索不会在巨大的稀疏向量上进行,而是在小的密集向量上进行,这使得一些近似技术更易于处理。以电影推荐为例:
某个用户u对电影i的预测评分=User向量和Item向量的内积
把这两个矩阵相乘,就能得到每个用户对每部电影的预测评分了,评分值越大,表示用户喜欢该电影的可能性越大,该电影就越值得推荐给用户。
最后我们可以注意到,这种基本分解的概念可以扩展到更复杂的模型,例如,更通用的神经网络,我们可以想到的第一个就是布尔值交互矩阵。如果我们想重建布尔交互,简单的点积就不能很好地完成。但是,如果我们在该点积之上添加一个logistic函数,我们会得到一个模型,它的值在[0,1]中,因此可以更好地解决问题。在这种情况下,要优化的模型是min12∑Mij≠0[f(Xi,YjT)Mij]2+λ2(∑i,k(Xik2)+∑j,k(Yik)2)min\frac{1}{2}\sum_{M_{ij}\neq0}[f(X_i,Y_j^T)-M_{ij}]^2+\frac{\lambda}{2}(\sum_{i,k}(X_{ik}^2)+\sum_{j,k}(Y_{ik})^2)min21Mij=0∑[f(Xi,YjT)Mij]2+2λ(i,k∑(Xik2)+j,k∑(Yik)2)其中f(.)是logistic函数。更深层次的神经网络模型通常在复杂的推荐系统中实现接近最先进的性能(SOTA)。
对于任何机器学习算法,我们都需要能够评估推荐系统的性能,以确定哪种算法最适合我们的情况。推荐系统的评估方法主要可以分为两组:基于定义明确的指标的评估和主要基于人类判断和满意度估计的评估。
如果我们的推荐系统基于输出数值的模型,例如评分预测或匹配概率,我们可以使用误差测量指标,例如均方误差(MSE)以非常经典的方式评估这些输出的质量。在这种情况下,模型仅在部分可用交互数据上进行训练,并在其余交互数据上进行测试。
如果我们的推荐系统基于预测数值的模型,我们也可以使用经典的阈值方法对这些值进行二值化(高于阈值的值为正,低于阈值的值为负)并以“分类方式”评估模型.实际上,由于用户-项目过去交互的数据集也是二值化的(或者可以通过阈值化进行二值化),因此我们可以评估模型在测试数据集上的二值化输出的准确性(以及精度和召回率)。
最后,如果我们现在考虑一个不基于数值的推荐系统,它只返回一个推荐列表(例如基于knn方法的用户-用户或项目-项目),我们仍然可以定义一个精度,如度量估计真正适合我们用户的推荐项目的比例。为了估计这个精度,我们不能考虑我们的用户没有与之交互的推荐项目,我们应该只考虑我们有用户反馈的测试数据集中的项目。
第一、推荐算法可以分为两大经典模型:基于协同过滤方法(例如用户-用户、项目-项目和矩阵分解)和基于内容的方法
第二、基于记忆的协同过滤方法不假设任何潜在模型,因此具有低偏差但高方差;基于模型的协同过滤假设一个潜在的交互模型需要从头开始学习用户和项目的特征,因此具有更高的偏差但更低的方差;基于内容的方法假设一个潜在模型围绕用户和/或项目特征构建,因此具有最高的偏差和最低的方差
第三、推荐系统难以评估:如果可以使用MSE、准确率、召回率或精确率等一些经典指标,则应记住,我们无法以这种方式评估某些属性,例如多样性(偶然性)和可解释性;实地工作中(离线测试、小批量线上AB测试、全流量上线)最终是评估新推荐系统的唯一真实方法,但需要设定一定的置信水平