init
- 我个人建立的推荐系统认知如下:
- 首先推荐系统的目的是什么?
- 用户的角度是从海量信息中获得感兴趣信息,获得满足感;
- 公司的角度是提高收益,这与提高用户满足感是正比;
- 那么推荐系统做什么?
- 想象推荐系统就是一口井,每一个人的信息似一杯水,每杯水包含不同杂质,包括红色的物质,这是每个人的最爱🍎 ;所有的人往井里倒水,这口井的目的是过滤出来红色物质,反馈给倒水的每个人,诱导每个人继续灌水。这些红色物质便可算人的潜在感兴趣信息。
- 首先推荐系统的目的是什么?
Models
辛普森悖论:高维特征上的简单合并特征,损失大量有效信息;
Level-1:
- 矩阵分解:做法:梯度下降,优势:全局信息生成隐向量,泛化能力更强;缺点:无法引入上下文信息;
- 逻辑回归:做法:用户CTR转换为一个投掷偏心硬币的过程;优势:并行;缺点:表达能力单薄,无法特征交叉;
- POLY2:做法:暴力枚举所有特征之间的组合,并附一个对应的参数权重,复杂度$O(n^2)$,缺点:稀疏向量更加稀疏,无法特征交叉;
- FM:做法:为每个特征学习一个隐权重向量, 优势:权重参数降低为$O(n*k)$,未出现的特征组合也可计算得分,缺点:只能进行二阶特征交叉。
- FFM:做法:每个特征对应一组特征隐向量,考虑特征属于不同的域;缺点:时间复杂度$O(k*n^2)$,只能进行二阶特征交叉。
- GDBTR + LR(逻辑回归):优势:特征自动化,端到端进行。
- 混合逻辑回归:做法:样本分片在进行LR。
Level2:
- To be continuing…
Framework :
- 推荐系统 = 数据处理 + 模型【离线训练 + 线上服务】
数据处理
- 批处理:HDFS(存储)+ MapReduce(计算),缺点:只能批量处理静态数据。
- 框架:数据源→服务器端预处理→HDFS→MapReduce →应用
- 流计算:通过滑动窗口完成数据暂时缓存并消费。优势:流计算平台的延迟仅与滑动窗口大小有关。缺点:数据误差,比如滑动窗口较短造成的数据遗漏。
- 平台:Storm、Spark Streaming、Flink。
- 框架:数据源→服务器端预处理→流计算平台 →存储系统 →应用
- lambda架构:做法:批处理平台(全量计算)+流计算平台(增量计算);缺点:两类平台上的代码冗余。
- 框架:数据源→服务器端预处理→批处理+流计算平台 →存储系统 →应用
- kappa架构:做法:批处理也是特殊的流处理,数据重播, 缺点:重播效率,批处理与流处理是否完全共享。
- 框架:数据源→服务器端预处理→流计算平台 →存储系统 →应用
- 数据处理后的去处:
- HDFS为代表的离线海量数据存储平台,如离线训练样本;
- Redis为代表的在线实时特征数据库,为模型提供实时特征。
离线训练: Spark MLlib、Parameter Server、TensorFlow
- Spark:
- 处理有向无环图程序时,将图分解为不同的stage,stage内部并行计算,stage边界【shuffle操作】合并或终止【Reduce操作】。
1 |
Parameter Server:
- 并行梯度做法:每个worker载入一部分训练数据,
pull
相关参数,计算局部梯度,push
给sever节点,Sever
节点更新参数。 - 优势:与spark相比,spark是“同步阻断式”的并行梯度下降,parameterSever是“异步非阻断式”的。【比如迭代到第k+1轮,但某节点还未把最新的权重参数
pull
到本地,此时仍计算使用的是K+1轮之前的梯度,可设置“最大延迟”参数保证多少次內节点参数必须pull
更新。】 - 使用一致性哈希、参数范围拉取、推送,避免广播参数带来的全局性阻塞和带宽浪费。
- 参数服务器仅仅是一个管理并行训练梯度的权重平台,常常作为组件(集成到Mxnet、Tensorflow中)。
- 并行梯度做法:每个worker载入一部分训练数据,
- Tensorflow:
- 做法:建立任务关系图,存在依赖关系的子图是为一个节点,内部串行计算,不存在依赖关系的并行计算。
- 单机版:GPU+ CPU任务级别并行计算;
- 分布式:数据并行方式训练,即各个woker以同样的任务关系图的方式训练,但数据不一样,同Parameter Server方式一样。
上线部署
1、训练好的推荐结果存入Redis。优势:冷启动、热门榜单推荐。缺点:组合爆炸存不下。
2、预存用户和物品的Embedding + 线上清亮模型拟合。 缺点:无法引入线上场景特征。
3、PMML(预测模型标记语言):模型序列化 + 解析:完成推断。
4、Tensorflow Serving:部署Tensorflow模型 + 配合docker。