用户的购买行为很容易能够用二分图(二部图)来表示。而且利用图的算法进行推荐。基于邻域的模型也能够成为基于图的模型,由于基于邻域的模型都是基于图的模型的简单状况。咱们能够用二元组\((u,i)\)来表示用户\(u\)对物品\(i\)有过购买行为,这样的话数据集能够用一个二分图来表示。我这里尝试画一个二分图(有点丑,不要介意哈):python
左边是用户节点,右边是物品节点。连线表明用户对物品有过购买行为。算法
咱们把个性化推荐算法放在二分图当中,给用户推荐物品就转变成了度量用户节点和商品节点的相关性,相关性越高的物品在推荐列表当中的权重就越大。通常来讲顶点相关性取决于三个方面:学习
相关性高的一对顶点通常具备以下特征:spa
基于上面3个主要因素,研究人员设计了不少计算图中顶点之间相关性的方法。下一节将介绍一种基于随机游走的PersonalRank算法。设计
假设要给用户\(u\)进行个性化推荐,能够从用户\(u\)对应的节点\(v_u\)开始在用户物品二分图上进行随机游走。游走到任何一个节点时,首先按照几率\(\alpha\)决定是继续游走,仍是中止此次游走并从\(v_u\)节点开始从新游走。若是决定继续游走,那么就从当前节点指向的节点中按照均匀分布随机选择一个节点做为游走下次通过的节点。这样,通过不少次随机游走后,每一个物品节点被访问到的几率会收敛到一个数。最终的推荐列表中物品的权重就是物品节点的访问几率。code
用代码来表示:视频
def PersonalRank(G, alpha, root): rank = dict() rank = {x:0 for x in G.keys()} rank[root] = 1 for k in range(20): tmp = {x:0 for x in G.keys()} for i, ri in G.items(): for j, wij in ri.items(): if j not in tmp: tmp[j] = 0 tmp[j] += 0.6 * rank[i] / (1.0 * len(ri)) if j == root: tmp[j] += 1 - alpha rank = tmp return rank
虽然PersonalRank算法能够经过随机游走进行比较好的理论解释,但该算法在时间复杂度上有明显的缺点。由于在为每一个用户进行推荐时,都须要在整个用户物品二分图上进行迭代,直到整个图上的每一个顶点的PR值收敛。这一过程的时间复杂度很是高,不只没法在线提供实时推荐,甚至离线生成推荐结果也很耗时。为了解决PersonalRank每次都须要在全图迭代并所以形成时间复杂度很高的问题,这里给出 两种解决方案。第一种很容易想到,就是减小迭代次数,在收敛以前就中止。这样会影响最终的 精度,但通常来讲影响不会特别大。另外一种方法就是从矩阵论出发,从新设计算法。深度学习
咱们将PR算法设计成矩阵的形式,令\(M\)为二分图的转移几率矩阵,即it
那么迭代公式修改成:io
咱们解一下这个方程
这里的\((1-\alpha M^T)\)是稀疏矩阵,对其快速求逆便可。
最近这两天出去过节了,断更了几天,我又开始继续更新这个系列了。这个系列后续可能就比较快的更新完,再说一个好消息,更新完这个系列以后,王喆编著的《深度学习推荐系统》以及相关的实践课程视频我也买了,将继续更新《深度学习推荐系统》以及实践视频课的读书笔记,你们能够关注一下,敬请期待。