通过 Spark SQL, Spark MLlib, Spark Streaming 技术,基于隐语义模型(LFM),结合实际项目经验,搭建一套个性化推荐系统
这边文章更多的是分享一下,在实际项目中,如何落地个性化推荐,因为晚上相关资料很杂,并且一些开发流程都涉及的很片面,并且有绝大部分教程都是以电影推荐为例子来讲解,不可否认,电影推荐来讲解确实方便,因为有现成的数据源加上本身就自带的评分体系,但是实际工作中,有很多没有直接评分的,所以我们从这些流程动手,带你一起过一下,真实项目中的开发流程
比如点了赞,给1分,分享了,给2分,收藏了,给三分
不同的行为,反映了用户的不同喜好程度,比如分享了比点赞更重要。面对众多指标,如何合理地确定各权重呢?这里通过层次分析法来确定各行为指标的权重
构造成对比较矩阵
播放时长 | 播放时长/视频时长 | 评论 | 下载 | 收藏 | 分享 | |
---|---|---|---|---|---|---|
播放时长 | 1 | 1/3 | 1 | 1/3 | 1/5 | 1/5 |
播放时长/视频时长 | 3 | 1 | 1 | 1 | 1 | 1/2 |
评论 | 1 | 1 | 1 | 1/3 | 1/2 | 1/5 |
下载 | 3 | 1 | 3 | 1 | 1 | 1/2 |
收藏 | 5 | 1 | 2 | 1 | 1 | 1/2 |
分享 | 5 | 2 | 5 | 2 | 2 | 1 |
比如第四行第一列的数字3,表示“下载”比“播放时长”稍重要。
标度 | 含义 |
---|---|
1 | 表示两个元素相比,具有同样重要性 |
3 | 表示两个元素相比,前者比后者稍重要 |
5 | 表示两个元素相比,前者比后者明显重要 |
7 | 表示两个元素相比,前者比后者强烈重要 |
9 | 表示两个元素相比,前者比后者极端重要 |
2,4,6,8 | 表示上述相邻判断的中间值 |
倒数 | 上边的行为反过来 |
- 把权重矩阵的每一行都归一化处理
- 每一行的数值相加 去掉一维
- 剩下的所有数据在进行归一化
例子
原矩阵
[[1, 1/3, 1, 1/3, 1/5, 1/5],
[3, 1, 1, 1, 1, 1/2]]
1. 进行每行的归一化
[[ 0.05555556 0.0521327 0.07692308 0.05830389 0.03508772 0.06896552]
[0.16666667 0.15797788 0.07692308 0.17667845 0.1754386 0.17241379]
2.每行相加
[ 0.34696846 0.92609846]
3.在进行归一化
[ 0.05782808 0.15434974]
播放时长 | 播放时长/视频时长 | 评论 | 下载 | 收藏 | 分享 |
---|---|---|---|---|---|
0.9 | 0.8 | 1 | 0 | 0 | 0 |
score = w1 * x1 + w2 * x2.......
从业务的数据源选取对应的操作数据,数据源可以是日志文件、或者Hadoop、MySQL、MongoDB等选取,选取的内容无外乎点赞、分享、收藏、观看记录等,通过Spark进行数据的整理和清洗,保存清洗后的数据。
其实在项目的冷启动阶段,一些简单的推荐策略不但能达到比较好的推荐策略,并且还能收集信息,为将来的使用更加"先进"的推荐算法做好数据收集
统计推荐可以考虑的点
-
按照点赞量
但是这样的策略会间接带来一些问题,前期上的一些内容基本都会一直在前边展示,解决思路就是加入时间维度进行惩罚,说一个简单思路 总的点赞量/物品上线时间
-
历史热门&近期热门
统计最近一段时间内热门的数据,热门定义根据自身业务来,可以是点赞量、分享、收藏、观看次数、完播率、或者某几项的评分等
-
根据物品的评分得分
统计电影历史的平均得分,推荐得分权重较高的
-
根据类别推荐TOPN
如果业务中的物品有类别的概念,可以考虑统计不同类别的评分TOPN数据
-
系统相关
这一块严格意义不太算统计推荐中的内容,可以先把它划为这里,就是根据自身业务特点,比如我想主推某几个物品
-
长尾
这一块严格意义也不太算统计推荐中的内容,可以把一些长尾的数据给一定的推荐量,根据后续的统计情况来判定是否进行二次推荐
内容推荐无外乎是定义两个物品的相似度,找到与当前物品相似的N个物品进行推荐,那么如何定义物品之间的相似度呢?
思路一:
- 业务中每个物品有N多属性,我们可以选取其中几个属性
- 把选取的属性数值为向量(例如: 性别抽象为0|1),然后进行归一化
- 根据余弦相似度或者其他相似度算法 计算两个物品的相似度
思路二:
- 假如一些特征是包含一些文字信息,可以考虑使用tf-idf进行词频统计,计算相似度
这一块主要是使用Spark MLlib 来进行矩阵分解,说一下大体流程
- 构建 用户-商品-评分 的矩阵
- 随机拆分 训练数据和测试数据
- 训练ALS包的涉及的不同参数,根据RMSE(均方根误差)选取较优的参数
- 根据训练出来的参数,拟合参数为用户-物品笛卡尔积的结果,预测所有的评分存储
- 在ALS拟合过程中会产生物品的特性向量,通过特征向量,得到物品的相似集合数据
这一块主要是基于Spark Streaming & Kafka来进行数据流的计算,大致流程如下
-
过来一个物品,选择一个候选物品集合,候选物品可以根据前几步计算的物品相似集合获取
-
过滤掉用户已经观看的数据
-
从业务系统中获取用户最近一段时间物品评分情况
-
分别计算候选物品与最近一段时间物品的关联情况进行选择,可以草考如下计算规则
规定: 评分超过3分为激励项,低于3分为惩罚项 设: 候选物品与当前物品的相似度s 各个最近物品的评分为c1,c2,c3 总的最近评分物品数量为n 计算公式: (s * c1 + s * c2 + s * c3) / n + log(激励项) - log(惩罚项)