一个特殊场景的 LR 预测优化 Trick

推荐系统常用分类算法包括 LR、XGBoost 和最新的 Deep Learning 。libFM 可以看出是自动特征交叉和 LR 算法的结合。XGBoost 在竞赛中用得多,但在实际工业中鲜见其成功案例。Deep Learning 则是未来可能成为 CTR 预估范式的新兴算法,但现在受限于成本和性能。LR 作为老牌工业推荐系统中算法,至今活跃在一些推荐场景中。

1. LR 在推荐系统中应用

给定实例 x, LR 算法计算该实例为正样本的概率,如下所示。

(1)

其中 w 是 LR 的参数。LR 算法的训练过程是,最小化在训练数据中预测概率和真实标签之间的区别。

(2)

其中 p 是 LR 的预测值,t是真实标签。这个无约束最小化问题,可以用一系列梯度相关的算法进行求解。

推荐系统的职能是向用户 (u) 推荐其感兴趣的物品 (i)。转换成机器学习问题,给定 u,i 预测是否感兴趣 tag。因此 LR 输入的特征向量 x=(u的特征,i的特征, u 和 i 的交互特征),输出用户 u 对物品 i 感兴趣的概率。

推荐系统有一种简单的架构:线下计算好所有预测结果(广告和推荐系统部署机器学习模型的两种架构)。具体过程如下所示:1)在线下,从用户和广告(物品)属性抽取用户和物品特征,将抽取的特征合并进日志生成训练数据,训练机器学习模型;将几乎所有可能的请求合并特征,进而生成预测实例,用模型得到预测结果;2)线上就很简单了,接入线下传过来的预测结果。因此物品系统的预测结果 “userid,adid1,adid2…,adidn” 上载到线上,一旦线上传一个 userid 请求展示广告,线上模块就按照一定的逻辑返回预测结果中这个用户对应的物品。

这种架构需要提前计算所有可能的情况,预测的计算量比较大。在物品特征不是很多 (小于500) 和用户特征数不是很多 (十万级) 的场景, 我们可以优化 LR 的预测,减少预测的计算量。

2. 特殊场景的 LR 预测优化

在物品特征不是很多 (小于500) 和用户特征数不是很多 (十万级) 的场景, 我们可以优化 LR 的预测。ID 类用户特征不考虑的话,如果离散化和 dummy 化平均分十桶,十万用户特征相当于一万个用户属性(相当于用户表有一万列)。这已经很大了。一般我们说千万甚至上亿特征,大量来自于用户和物品特征的交叉,就是我们下面要处理的。LR 的预测公式可以进行下面的推导。

(3)

其中ai=∑k∈ifeatfkwkai=∑k∈ifeatfkwka_i = \sum_{k \in ifeat} f^kw^k 表示物品 i 中特征加权和, bk,i=∑(k1∈ifeat)fk_fk1wfk_fk1bk,i=∑(k1∈ifeat)fk_fk1wfk_fk1 b_{k,i} =\sum_{(k1 \in ifeat)} f^{k}\_f^{k1} w^{f^{k}\_f^{k1}} 表示特征用户特征 fkfkf^{k} 和物品 i 中特征的交叉特征的加权和。 这两个加权和的权重都是由 LR 模型提供。在物品特征不是很多 (小于500) 和用户特征数不是很多 (十万级) 的场景下, aaa 容量等于 500, bbb 的容量为千万量级, 我们可以在内存保存一份 aaa 和 bbb,预测的时候直接获取就可以了。经过这样优化,计算用户和物品 p 值的复杂度为从 O(num_ufeatures * num_ifeatures) 减为 O(num_ufeatures)。 当然,这个 Trick 是以牺牲空间为代价的,是典型的 “空间换时间” Trick。 针对内存使用过大的情况,我们可以做一些妥协,比如只保存高频用户特征的 b。

我们在我们部门的业务中做实验。该业务的推荐场景,有 4 亿用户,80 个物品。如果完全展开,需要对 4*80 = 320 亿条数据进行预测。我们用 Spark 实现了程序,用了 200 cores。实验得到了如下结果。

从上面的表格,我们可以看到,优化之后性能得到了极大提升。优化前,LR 需要 20 个小时才能完成 320 亿条数据的预测;优化之后,LR 只需要 10 分钟就完成了 320 亿条数据的预测;耗时减为原来的 120 分之一。

3. 总结

我们的业务碰到了一个很特殊的场景:用户数量巨大,上亿;物品数目比较少,不超过 500 个。针对这个特点,我们设计了一个小程序 Trick。这个程序 Trick 极大地提高了 LR 的预测性能,预测耗时减为原来的 120 分之一。

目前我在和小伙伴们开发非完美信息游戏 AI 环境:RoomAI,所以无力保持两周一次的更新频率。向期待更新的大伙说一声对不起,希望后续稳定两周一次的更新。RoomAI 的目标是提供一些非完美信息游戏环境和一些基线模型算法,方便 AI 开发人员快速地构建、测试和对比自己的非完美信息游戏 AI 算法。目前 RoomAI 已经支持德州、梭哈和七鬼,基本流程如下所示:玩家 AI 获得游戏环境给出的信息,当前玩家 AI 选择合适的动作,游戏环境根据该动作推进游戏逻辑;重复上述过程,直到分出胜负。

RoomAI 的用法也是简单明了,下面是一个随机玩家的示例。

from roomai.kuhn import *;
import roomai.common
import random

#### Define your player Bot ####
class KuhnPokerExamplePlayer(roomai.common.AbstractPlayer):
    def receive_info(self, info):
        if info.person_state.available_actions is not None:
            self.actions = info.person_state.available_actions
           
    def take_action(self):
        idx = int(random.random() * len(self.actions))
        return list(self.available_actions.values())[idx]
        
    def reset(self):
        pass

if __name__ == "__main__":
    #### init ####
    env     = KuhnPokerEnv()
    players = [KuhnPokerExamplePlayer() for i in range(2)]

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据挖掘DT机器学习

你还在用“人工特征工程+线性模型”?

作者:李沐M 11年的时候我加入百度,在凤巢使用机器学习来做广告点击预测。当时非常惊讶于过去两年内训练数据如此疯狂的增长。大家都在热情的谈特征,每次新特征的...

39780
来自专栏企鹅号快讯

现在 tensorflow和mxnet 很火,是否还有必要学习 scikit-learn 等框架?

本文整理自作者在知乎问题《现在 tensorflow 和 mxnet 很火,是否还有必要学习 scikit-learn 等框架?》下的回答,AI 研习社获其作者...

35470
来自专栏机器之心

业界 | 谷歌推出神经网络可视化库Lucid,推进模型的可解释性工作(附GitHub)

30460
来自专栏机器之心

Jeff Dean与David Patterson:不思考体系结构的深度学习研究者不是好工程师

今年 1 月,谷歌人工智能负责人 Jeff Dean(当时还是谷歌大脑负责人)与 2017 年图灵奖得主、体系结构巨擘 David Patterson(当时获奖...

10940
来自专栏量子位

强化学习如何入门?看这篇文章就够了

对于大脑的工作原理,我们知之甚少,但是我们知道大脑能通过反复尝试来学习知识。我们做出合适选择时会得到奖励,做出不切当选择时会受到惩罚,这也是我们来适应环境的方式...

16430
来自专栏智能算法

关于深度学习的框架、特征和挑战

在嵌入式系统上的深度学习 随着人工智能 (AI) 几乎延伸至我们生活的方方面面,主要挑战之一是将这种智能应用到小型、低功耗设备上。这需要嵌入式平台,能够处理高性...

34870
来自专栏IT派

全程中文:谷歌上线机器学习速成课程

IT派 - {技术青年圈} 持续关注互联网、区块链、人工智能领域 IT派日常小剧场 全球AI第一大厂Google推了新课程! ? Google今天上线了一...

29740
来自专栏机器之心

入门 | 强化学习的基本概念与代码实现

28550

如何实现机器学习算法

在代码中实现一个机器学习的算法能够使你更加了解该算法以及其工作机理。

221100
来自专栏人工智能头条

深度学习在推荐领域的应用

19240

扫码关注云+社区

领取腾讯云代金券