基本目标
算法的基本目标就是根据历史数据计算出给用户推荐的数据.这里的历史数据不一定是当前用户的历史数据.可能是其他用户的.这就是协同的意思.
从最基本的业务需求介绍
我开了一家杂货店.通过网络销售.用户登录到我的店铺之后需要给用户推荐一些商品.由于商品的种类很多.不可能一次都推荐给用户,需要根据一些策略筛选出来一批商品. 定一个简单的策略是历史上用户点击最多的商品或者评分最高的商品.根据简单的策略很容易就可以选择出来一批商品. 这个策略通过商品自身的条件筛选. 想一下这个策略有什么问题呢? 例如键盘的点击和评分最高,无论哪个用户来了都会首先看到键盘.但是键盘不一定是用户想要的商品.例如用户上次购买的是电饭煲.再次登录想要什么呢? 用户买了电饭煲是否可以看看历史上买了电饭煲的用户还买了什么东西? 假设历史上用户买了电饭煲之后又买了电烤箱.那是不是当发现一个买过电饭煲的用户查看商品的时候推荐电烤箱更合适? 这个就是基于物品的协同过滤.协同指的就是以用户购物习惯大致相似作为前提,根据历史数据找到相似的数据进行比较
分析一下具体实现流程和数据模型.
根据上面的介绍很容易就可以梳理出来一个流程:
首先积累历史数据,记录每个用户购买商品的类型:例如用户A购买了电饭煲和电烤箱.用户B购买了键盘和鼠标.用户C购买了尿不湿和啤酒
然后,当一个用户登录系统查看商品列表的时候先看一看用户历史买过什么.例如:用户买过键盘.
然后,查一下历史上买过键盘的其他用户买过什么.如果买过鼠标就给登录的用户展示鼠标.
好像很简单.
再思考一下这里面有什么问题:
如果商品很多.例如买过键盘的用户还买过鼠标、电饭煲、电烤箱等等.由于商品太多无法一次都展示给当前用户.
怎么办?需要给商品排序.按顺序给用户展示.但是排序需要一个排序策略.
根据前面讨论的选择商品是根据历史用户的购买情况选择的.那么我们就找到购买商品之间的相关性.打个相关性分数.根据分数排序
打个分数
打个分数?需要一个数字.这个时候需要对商品相关性进行数学建模了.这个有点麻烦.需要一些数学基础.我们还是先从最简单的说起.先讲原理后面再说难懂的数学公式.
我们先看一组数据:
1代表用户买过商品 0代表没有买过商品
数据分析
我们思考一下如果A用户登录系统查看商品列表我们要如何推荐呢?
首先:A已经买过键盘的了,没必要推荐了(假设用户不会重复购买),我们需要给用户推荐鼠标和电饭煲.
那么是鼠标排在前面还是电饭煲排在前面呢?
分析一下用户B和C的购买商品.用户B购买过键盘和用户A购买的一样.同时B也购买了鼠标.说明购买键盘的用户购买鼠标的可能性大.那么就把鼠标排在电饭煲前面.协同的意思就在这里.
再考虑一个复杂一些的:
如果用户D登录系统查看商品列表:
D购买过电饭煲.那么需要给用户推荐键盘、鼠标、电烤箱.那么这三个商品如何排序呢?
分析ABC的购买商品情况:
由于C用户购买过电饭煲.与D的历史购买习惯一样.C购买过鼠标和电烤箱.那么鼠标和电烤箱要排在键盘的前面.
鼠标和电烤箱如何排序呢?
我们继续看AB用户,用户A鼠标和电烤箱都没买过.可以不考虑.
用户B购买过鼠标.那么鼠标是应该排在烤箱前面还是后面呢?
这个时候需要我们分析一下.
我们回到算法的原始逻辑上.找到商品的相关性.通过C用户我们得到的情况是鼠标电烤箱的相关性是一样的.
通过B用户的数据如何分析呢?
我们通过一个朴素的想法.B购买了鼠标但是没有购买电饭煲.那么B用户就拉低了鼠标和电饭煲的相关性.由于C用户鼠标和电烤箱与电饭煲的相关性一样.但是B拉低了鼠标和电饭煲的相关性.所以电烤箱需要排在鼠标的前面.
这样键盘鼠标和电烤箱的顺序就有了:电烤箱、鼠标、键盘
注意:
这里有一个很重要的观点.B购买了鼠标没有购买电饭煲就拉低了鼠标与电饭煲的相关性.你说这个观点对不对呢?
其实根据人的惯性思维来看是对的.当然你也可以不同意.可以提出反对意见.下面所讲的数据模型是认为这个观点是正确的来建立的.如果你认为这个观点不正确那就没必要看下面的数学模型了.
建立模型
有了上面的朴素认知之后我们通过理性思维来建立数学模型.
建立模型之前我们先介绍几个概念:
商品的相关性:
商品的相关性是描述商品与商品之间的关系.描述的方式是通过历史用户的购物、点击或者评分计算出来的一个数值.
例如前面说的不同用户购买过相同的商品的相关性高.数据建模为了量化相关性.通过余弦相似度函数计算出来[0,1]的值域
推荐评分:
推荐评分是给用户推荐的商品打分.分数高的排在前面.分数是通过商品与商品的相关性计算出来的.例如商品A和B的相关性是0.5.A和C的相关性是0.4.假设A的定义域(A可以取哪些值)是固定值1的情况下.A的分数是0.9.
下面具体介绍数据模型: 采集到的历史数据的模型: 行是用户、列是商品
根据历史数据计算相关性数据:
上面这个矩阵的数据是如何根据用户点击的数据计算的呢?
下面说一下相关性数据的计算公式:
我们取键盘和鼠标作为例子:
(用户A键盘数据用户A鼠标数据 + 用户B键盘数据用户B鼠标数据 + 用户C键盘数据用户C鼠标数据 + 用户D键盘数据用户D鼠标数据) / 开平方(用户A的键盘数据的平方+用户B的键盘数据的平方 + 用户C的键盘数据的平方 + 用户D的键盘数据的平方) * 开平方(用户A的鼠标数据的平方+用户B的鼠标数据的平方 + 用户C的鼠标数据的平方 + 用户D的鼠标数据的平方)
= (1*0 + 1*1 + 0*1 + 0*0) / 开平方(1的平方 + 1的平方 + 0的平方 + 0的平方) * 开平方(0的平方 + 1的平方 + 1的平方 + 0的平方) = 1/开平方(2) * 开平方(2) = 1/2 = 0.5
数学表达式:
推荐商品分数计算:
取用户D作为例子:
由于电饭煲用户D已经选择过.推荐键盘、鼠标和电烤箱.
取电烤箱作为例子:
由于用户D只操作过电饭煲.所以分数只能通过电饭煲计算.
电烤箱的分数=电烤箱和电饭煲的相似度*用户D的电饭煲
在看是用户B的分数.由于B操作过键盘和鼠标.所以计算分数要把键盘和鼠标都加上
用户B推荐电烤箱的分数=电烤箱和键盘的相似度*键盘 + 电烤箱和鼠标的相似度*鼠标
数学表达式
用户U对物品i的分数 = 物品(i,j)的相似度*用户对物品j的评分
要计算用户 u对物品 j的预测评分,需要找到与物品 j相似的物品 i(这些物品 i是用户u已经评分过的),然后将 “物品i和物品 j的相似度” 与 “用户 u对物品 i 的评分” 相乘,最后对所有这样的乘积求和,得到用户 u 对物品 j 的预测评分。简单来说,就是利用用户对相似物品的评分,来预测用户对目标物品的评分。
数学表达式:
上面的公式看着让人头疼.重点是了解什么是协同,什么是相关性就可以了.因为在深入研究的时候不是必须使用上面的公式.我们自己也可以创建一个公式.
实际生产中开发人员主要做的事情是收集历史数据.然后使用开源的工具包进行刷数排序就可以了.
这个文章是希望大家对协同过滤有一个感性的认识.