同现购买
协同过滤为用户做推荐的依据包括:所有人购物的历史纪录,还有用户和商品之间的一般化的关联关系,显然当我们为用户推荐商品的时候,如果有人买过这件商品,而且可能他们大部分还同时都买过其它的某些物品,我们有必要将这些过去一起买的商品推荐给此时买这件商品的用户。也有可能有些商品不是同时买的,但只要在历史购物的记录里就可以考虑,这样就有了同现购买的概念。
比如买尿布的人同样买了婴儿湿巾,如果我们刚刚买了尿布,那么如何使用同现购买现象帮助我们做出推荐呢?
同现矩阵
首先先来看一下同现矩阵是什么样的?
这个同现矩阵是一个对称矩阵,其中每一行表示一件商品,所有行就表示所有的商品。每一列同样也表示一件商品,所有列就表示所有的商品,行i与列j相交的位置就是即买这个商品i又买那个商品j的用户数。
因为这是一个对称矩阵,所以同时买物品i和j的用户个数,和同时买物品j和i的用户个数是一样的。只要有人买尿布和其它的商品,我们就将对应的位置加1.
现在同现矩阵已经有了,现在我们如何使用同现矩阵来做商品推荐?
使用同现矩阵做商品推荐
假设有一个用户刚买了尿布,我们找到同现矩阵的尿布行,将该行提取出来
然后我们就可以将最大计数的商品作为推荐,我们发现婴儿湿巾的数量为100,所以商品推荐系统和很有可能给购买了尿布的人推荐婴儿湿巾。
使用同现矩阵做商品推荐的问题
如果有一件商品非常流行,那么会出现什么问题?
比如对于家里有婴儿的用户来说,婴儿的尿布非常流行,几乎所有用户在购买婴儿类商品的时候都会购买尿布。那么对于这些用户来说只要购买婴儿类产品(比如长颈鹿咀嚼器)的时候,系统会从同现矩阵中取出长颈鹿咀嚼器行:
我们会发现尿布永远都是次数最多的,所以如果按照这个来推荐给用户的话,我们可以发现只要购买婴儿类的产品就会推荐尿布,这个看起来很正常,但是缺乏了个性化,淹没了其它的产品(也就是说很多人买了尿布,并不代表买了长颈鹿咀嚼器的用户也想买尿布),要想克服这么问题,使其更加个性化,我们需要解决流行商品推荐力度过强的问题。我们可以将同现矩阵正规化,我们常常使用矩阵正规化的方法叫做Jaccard相似度。
同现矩阵正规化
具体来说就是同时买商品i和j的人的数量除以买商品i或j的人的数量
这个操作叫做Jaccard相似度,它也有一些局限性,它只考虑当前的购买行为,也就是它只根据当前用户购买的商品来推荐,不考虑历史的购买行为,要想解决这个问题,我们需要对所有的购物历史都加上权重系数(将最近购买的设置大一些的权重,对买的比较时间长的商品设置小一些的权重),然后给所有可能推荐的商品打个分。
比如来说,用户A购买过商品{尿布,牛奶},现在要对用户A进行推荐,那么模型将浏览所有可能推荐给A的商品,并对它们进行打分
(S湿巾,尿布)表示购买尿布和湿巾的人数,S(湿巾,牛奶)表示购买牛奶和湿巾的人数,然后对其进行求和,然后求平均,结果就是对推荐湿巾的打分。系统只需要推荐分数最高的商品就好了。(这里并没有对购买过的商品设置权重)。
这里还有一些问题,因为所有的推荐都是根据所有用户来的,这个系统这时并没有考虑上下文(比如时间),没有考虑用户的特征(比如年龄和性别),它只考虑了所有用户的同现矩阵,它也没有考虑商品的特征。
协同过滤算法
还有一个问题就是冷启动的问题,如果来了一个新用户或者上架了一个新商品的时候就会遇到冷启动问题。
要想解决这些问题,我们需要使用另外一种思路,这种思路很好的考虑了不同的用户,而且很好的考虑了不同的商品的特征,就是协同过滤算法。
我们使用电影推荐系统举例,每个电影都有特征,比如分别表示该电影中动作片、爱情片、喜剧片的成分的占比是多少?
对于每一个用户也有对应的权重,分别表示该用户对动作片、爱情片、喜剧片喜爱的权重。我们将用户的权重参数和电影的特征相乘就是该用户对电影的预测评分。
上图是一部电影的特征,现在有两个用户:
我们可以推断出一个用户对该电影的预测评分为7.2,另外一个用户对该电影的预测评分为0.8,所以自然而言该电影对于评分7.2的用户更值得推荐(虽然电影评分最高只有5分,这里只是随便举一个例子)
当我们知道所有用户的权重,那么我们可以将其组装成权重矩阵(L),矩阵的每一行表示一个用户。当我们知道所有电影的权重,那么我们也可以将其组装成一个矩阵(R),矩阵的每一列表示一个电影,将这两个矩阵相乘,我们就可以得到行为用户,列为电影的电影评分矩阵了(绿色的大矩阵)。
现在的问题是我们可能并不知道用户和电影的主题,也就是不知道矩阵L和矩阵R,我们要来尝试逆向思维,也就是估计L和R,我们可以认为它们是模型的参数。
现在我们有一些数据,也就是部分用户对部分电影的评分,也就是下面矩阵中的黑色的小方块。
矩阵因子分解模型
我们要用这些已知的数据来估计出最好的模型参数L和R,这种方式称为矩阵因子分解模型。
并且通过L、R来对为评分的电影进行评分预测。但是至此这种方法还是解决不了冷启动的问题。我们可以将特征和矩阵分解结合起来
特征可以是时间、看到的东西、用户的信息、历史购买这些非常明显的特征,而使用矩阵分解,我们可以得到隐含的一些特征。
那么面对冷启动的问题,我们可以仅仅通过特征(年龄、性别)来估计新用户的评分,当发现更多的信息后,我们就可以用矩阵分解的方法来发现主题特征(学到的特征),这样以后推荐的时候使用这些学到的特征,使用这种理念,将基于特定用户特征的模型和矩阵分解模型得到的特征结合起来,这是一种非常普遍的混合模型的想法。
推荐系统的性能度量
为了测量推荐系统的性能,我们可以使用召回率和准确率
以上就是所有的商品,其中有推荐两个字的表示推荐的商品,打着×的表示不被推荐的商品,画着粉色方块的表示用户喜欢的。
推荐出的喜欢的物品=带有推荐+粉色方块的,全部喜欢的物品是带有粉色方块的
推荐出的喜欢的物品=带有推荐+粉色方块的,推荐的物品是带有推荐标识的。
如果系统只要推荐所有的物品就能保证召回率=1,但是这样准确率结果会非常小,显然推荐所有的产品不是一个好的想法,好的想法应该是推荐的产品正好都是用户喜欢的。
如何使用准确率和召回率的这些度量来比较我们可能会使用的不同算法,我们需要画一个准确率-召回曲线
为了画出召回率曲线,需要变化推荐物品数的阈值,对于每一种推荐商品数设置,计算准确率和召回率,如下图所示
最优的推荐系统是这样的,随着推荐商品数量的增加,召回率和准确率双双为1
判断最优算法
当我们有多个算法对应的准确率-召回曲线的时候,我们如何根据曲线来判断哪个算法最好呢?
对于给定的准确率,我们希望召回率越高越好(反之亦然),假如现在有三个推荐算法,由此产生了三个准确率-召回曲线,我们可以使用单一的度量标准:最大的曲线面积(AUC),也就是曲线下的面积。
至此我们就知道了基于协同过滤构造推荐系统,以及如何通过准确率-召回曲线来选择最优的推荐算法。