LSH那些事儿
https://zhuanlan.zhihu.com/p/74813776
https://zhuanlan.zhihu.com/p/75597761


针对用户对物品的浏览记录还有搜索记录的embedding做平均(感觉可以上注意力机制?)(注意年龄的),三层全连接网络。
基于用户向量与不同商品的内积计算TopN物品得到候选集合。
局部敏感性hash(一维投影+分桶hash)(参考文本近似hash一章)
遍历全部商品样本实在太难,如何快速召回(粗排)就成了关键。因为要求的商品还有用户都在同一个空间内,可以使用最近邻搜索的算法(kd树索引),但是O(logn)并不是最快的方法,而且kd树还需要回溯确保是最近邻。维度高于10之后,基于空间划分的算法时间复杂度反而不如线性查找。
首先说明一个定理:在欧式空间中,将高维空间的点映射到低维空间,原本靠近的样本依旧很近,但原本远离的样本有一定概率靠近。
所以可以利用hash函数,
是分桶宽度,
是k维embedding向量,
是随机生成的k维向量,
是0到w间的一个均匀分布的随机变量避免边界固化。映射有一定概率得出错误的解,所以需要多个hash函数做补充,提升准确率。
- 采取"与"还是"或"?
hash函数之间与,可以提升准确率,但是容易漏掉分桶边界附近的点
hash函数之间或,可以降低漏掉的概率,但是计算太多,没法提前截止。
- 对于非欧式空间的怎么办?(曼哈顿距离,汉明距离(一般用于图片相似),余弦相似度距离)
求一个能使相似度关系在降维hash后仍能保留的函数。
常见的几种用于LSH的hash函数
- Bit sampling for Hamming distance(适用于海明距离)
最简单的Hash函数,仅适用于原始特征空间是Binary的Hamming空间,即原始的特征向量每一维的取值为{0,1}的特征串,其Hash函数的基本思想就是随机选取d维特征向量中的某一维
- Random projection(适用于余弦距离)
超平面将整个原始的特征空间划分为两部分(平面的两侧),用{0, 1}表示,每一个不同的w即定义一个超平面(可令b=0),可证明两个特征vector经Hash函数散列后碰撞的概率和其在原始空间的余弦距离成正比。
- Stable distributions(适用于欧式距离)
多路召回策略
多种召回策略的内容,取TOPN(热门新闻,兴趣标签,CF,朋友喜欢)合并成一个新的列表。这个新的列表,可以直接返回给前端,进行展示;也可以发给精排,进行排序。(N是一个超参数需要离线评估+A/B测试来确定合理的范围)
精排模型非常耗时,所以召回的内容,会经过粗排之后,把少量的数据给精排进行排序。

基于Embedding召回
可以将"热门程度","流行趋势"作为附加信息,跟商品信息融合(比如阿里的EGES)。
实时推荐系统

直观地看,在用户使用个性化新闻应用时,用户的期望是更快找到与自己兴趣相符的文章;在使用短视频服务时,期待更快地“刷”到自己感兴趣的内容;在进行在线购物时,同样希望更快找到自己喜欢的商品。所有的推荐都突出一个“快”字,这就是推荐系统“实时性”作用的直观体现。
影响推荐系统实时性的两大要素:
- 推荐系统「 特征」的实时性;
- 推荐系统「 模型」的实时性。

- 客户端实时特征
客户端是最接近用户的环节,在经典的推荐系统中,经常利用客户端收集时间、地点、推荐场景等上下文特征,然后让这些特征随http请求一起到达服务器端,参与模型预测。但是客户端对于实时性的重要性,经常被忽视的一点是客户端还是能够实时收集session内用户行为的地方。
对于网络状况比较差的地区,会对预加载的新闻还有特征在客户端进行排序计算,实现实时推荐。

- 流处理平台的准实时特征处理
随着storm,spark streaming,特别是flink等一批非常优秀的流处理平台的日益成熟。利用流处理平台进行准实时的特征处理已经成为了当前推荐系统的标配。
所谓流处理平台,是将日志以流的形式进行mini batch处理的准实时计算平台。由于每次需要等待并处理一小批日志,流处理平台并非完全实时的平台,但优势是能够进行一些简单的统计类特征的计算,比如一个物品在该时间窗口内的曝光次数,点击次数,一个用户在该时间窗口内的点击话题分布等等。
流处理平台计算出的特征可以立马存入特征数据库供推荐系统模型使用,虽然无法实时的根据用户行为改变用户结果,但分钟级别的延迟基本可以保证用户的推荐结果准实时地受到之前行为的影响。
几种更新方法:

- 全量更新
模型训练最常用的方式就是全量更新。模型会利用某时间段内的所有训练样本进行重新训练,再用训练好的新模型替代“过时”的模型。
但全量更新需要训练的样本量大,因此所需训练时间较长;而且全量更新往往在离线的大数据平台上进行,如spark+tensorflow,因此数据的延迟也较长,这都导致了全量更新是“实时性”最差的模型更新方式。
事实上,对于已经训练好的模型,可以仅对新加入的增量样本进行学习就可以了,这就是所谓的增量更新。
- 增量更新(Incremental Learning)
增量更新仅将新加入的样本喂入模型进行增量学习。从技术上来说,深度学习模型往往采用随机梯度下降(SGD)以及其变种进行学习,模型对增量样本的学习相当于在原有样本的基础上继续输入增量样本进行梯度下降。因此在深度学习模型的基础上,由全量更新改为增量更新的难度并不大。
但工程上的任何事情都是tradeoff,永远不存在完美的解决方案,增量更新也不例外。由于仅利用增量样本进行学习,因此模型在多个epoch之后也是收敛到新样本的最优点,而很难收敛到 原所有样本+增量样本 的全局最优点。
因此在实际的推荐系统中,往往采用增量更新与全局更新相结合的方式,在进行几轮增量更新后,在业务量较小的时间窗口进行全局更新,纠正模型在增量更新过程后中积累的误差。在“实时性”和“全局最优”中间进行取舍和权衡。
- 在线学习(online learning)(难点在于稀疏难)
“在线学习“是“增量更新”的进一步改进,“增量更新”是在获得一批新样本时进行增量更新,而在线学习是在每次获得一个新样本的时候就实时更新模型。在线学习在技术上也可以通过SGD类的方式实现。但如果使用general的SGD方法,在线学习会导致一个很严重的问题,就是模型的稀疏性很差,打开过多“碎片化”的不重要特征。
我们关注模型的“稀疏性”某种意义上也是工程上的考虑,比如在一个输入向量达到几百万维的模型中,如果模型的稀疏性好的话,可以在模型效果不受影响的前提下,仅让极小一部分维度的输入向量的对应权重非零,也就是说在模型上线的时候,模型的体积是很小的,这无疑有利于整个模型serving的过程。无论是存储模型所需的内存空间,以及线上inference的速度都会因为模型的稀疏性收益。
如果使用SGD的方式进行模型更新,相比batch的方式,容易产生大量小权重的特征,这就增大了模型部署和更新的难度。那么为了在在线学习过程中兼顾训练效果和模型稀疏性,有大量相关的研究,最著名的包括微软的RDA
,google的FOBOS
和最著名的FTRL
等(稀疏主要是因为未能遍历全部数据集,导致一些有用的特征来不及训练接近于0,或者)
- 模型局部更新
提高模型实时性的另外一个改进方向是进行模型的局部更新,大致的思路是降低训练效率低的部分的更新频率,提高训练效率高的部分的更新频率。这种方式比较有代表性的是facebook的GBDT+LR模型。因此为了兼顾GBDT的特征处理能力和LR快速拟合优化目标的能力,Facebook采取的部署方法时每天训练一次GBDT模型,在固定GBDT的前提下,LR部分可以做到增量或online更新。
Wide&Deep模型采用embedding层单独训练甚至预训练,embedding层以上的模型部分高频更新的策略。
- 客户端模型更新
对于物品embedding的更新来说,往往需要全局的数据,因此只能在服务器端进行整体的更新;而对用户embedding来说,则更多依赖于用户自身的数据。那么把用户embedding的更新过程移植到客户端来做,就能够实时地把用户最近的行为数据反应到用户的embedding中来,从而通过实时改变用户embedding的方式完成实时推荐。(比如说用户embedding是商品embedding的平均,那么就可以下载全商品的embedding然后在客户端计算)
网友评论