{"value":"#### **前言:**\n\n之前的文章我们深入探讨了**推荐系统的召回阶段**,接下来我们进入到**排序阶段**,本文我们介绍**排序任务的样本工程**。\n\n对于**个性化搜索,计算广告和推荐系统**三大领域来说(下面我们会简称为搜推广),他们的排序阶段比较相似,因此下面的内容对于这三个领域的排序任务来说是相通的。\n\n排序任务的一个通用特点就是数据集都很大(比如训练集经常都是几百GB以上),这个时候通常使用**分布式训练**来加速,而利用亚马逊云科技的 Amazon SageMaker 机器学习平台跑分布式训练是件简单方便的事情,更多的训练速度优化的细节可以参考我总结的另一篇文章。\n\n对于排序任务的样本工程,我们需要重点关注:**负样本的生成,数据集的来源,数据集的切分,数据集的采样,特征的线上线下一致性**。更多细节以及更详细的内容可以参考我的 github repo。\n\n### **负样本的生成**\n首先我们来看一个很重要的概念“**曝光**”,在搜索和推荐系统领域中常常提到的“曝光”和我们日常生活中说的“曝光”的含义有区别,日常生活中的“曝光”指的是某个东西/物体暴露在你面前,而搜索和推荐系统领域中的“曝光”常常指的是**从服务器侧需要返回的整个列表**,而不只是终端用户看到的那些物品item/搜索结果;而计算广告领域中的“曝光”则与我们日常生活中的“曝光”的含义比较接近。**“曝光”并不表示终端用户看到了**(这个是很重要的,也是很容易被忽略的),这里又细分两种情况:\n![image.png](https://dev-media.amazoncloud.cn/068b680d110c456a8f831862e15a7ba2_image.png)\n\n现在我们理解了“曝光”的含义了,我们接着来看排序任务的负样本生成。这里我们以推荐系统的 CTR 点击率预估排序任务为例,常见有三种方案:\n![image.png](https://dev-media.amazoncloud.cn/f6431808b37047b38addd7da99ba2d68_image.png)\n\n在我接触的客户中,使用方案 A 的是大多数。相对于方案 B,方案 A 和 C 可能会引入更多的**噪声**(因为有一些负样本并不是真的是终端用户不感兴趣的,可能仅仅是因为他们没有看到而已)。\n\n前面的三个方案都是关注曝光的 item,并没有关心用户是否看到了这些 item,那有没有更好的逻辑来提升负样本的可信度呢?\n\n在某些客户中,据说他们能从客户端的**埋点日志**中相对比较准确的判断终端用户是否看到了曝光的东西,我理解这个判断逻辑可能会涉及到:屏幕的大小,曝光位的大小,手指滑动触屏的速度(太快的滑动速度其实会啥都看不到),手指在曝光位停留的时间(停留的时间越长可能表示看清楚了)等等。\n\n如果能有比较靠谱的判断逻辑知道终端用户看了哪些曝光的 item,这样获得的负样本可能更可信。\n\n### **数据集的来源**\n关于**数据集的来源**,我遇到过两个很典型的子问题:一是数据集从多个**不同的地方/公司**收集;二是数据集从多个**不同的模型或者策略**收集。\n\n我们先看第二个子问题即数据集从多个**不同的模型或者策略收集**,下面即将介绍的新模型经历的某个阶段会涉及到这个子问题。\n\n新模型一般都会经历如下几个阶段(这里的新模型指的是完全不同的模型,不是同一个模型的不同版本,比如老模型是 xgboost 模型,新的模型是wide & deep 模型;或者新模型是 DeepFM 模型,老的用的业务规则):\n![image.png](https://dev-media.amazoncloud.cn/11d2886b597a481aaf67f6853a507817_image.png)\n\n对于第一个子问题即数据集从多个**不同的地方/公司**收集,我的一个客户的数据集就是来自三个不同的公司实体,那么就面临如何使用这样的数据集的问题,有三种方案:\n![image.png](https://dev-media.amazoncloud.cn/ea67ae7cf5534e9b964fe546d160beca_image.png)\n\n通过对两个子问题的阐述,我们能发现这样的数据集本质上不是“同质“的,都是混血的。从直觉上看,不同来源的数据的分布会不一致,用这样的数据集直接建模可能对模型效果有不好的影响。\n\n对于第二个子问题,可以通过新模型的重生阶段和成长阶段来规避;对于第一个子问题,可以参考 **A/B test** 的结果做调整,只要自己家公司模型产生的数据集足够多,并且特征覆盖度也足够好,那么可以尝试给用这样的数据集训练完的模型更大的线上流量,更大的线上流量可能会得到更高的特征覆盖度的数据,从而形成良性循环。\n\n### **数据集的切分**\n数据集切分常遇到的两种问题:一种是验证集和训练集如何切分;另一种是单个数据集是否切分为多个数据集。\n\n我们先来看第一个问题即**验证集和训练集如何切分**:在做计算广告的排序模型和推荐系统的排序模型的项目中,发现大部分的客户的训练使用的就是2种典型方式即**T+1训练方式**和**每天增量训练方式**,而T+1训练方式占据绝大多数,因此这里的数据集切分就只是讨论这种方式及其变体,T+1训练参考下图:\n![image.png](https://dev-media.amazoncloud.cn/2758de3008e24134b16f9b31db02caa4_image.png)\n\n正如上图所示,所谓的**T+1训练方式**有几个**要素**:全量T天的训练集,并且模型从头开始训练;紧接着的那一天作为验证集;基于滑动窗口的训练,滑窗为1天;每天都会更新线上模型。虽然排序任务并不是像时间序列预测那样的强时间依赖的任务,但是最常见的T+1训练方式中的T天的训练集和1天的验证集的边界还是按照时间先后顺序来切分的。\n\n对于T+1训练方式,有两个问题即**T取多少天**以及**验证集1天是否合适**。这两个问题会涉及到数据集的规模,选取几天的数据作为训练集和几天的数据作为验证集没有什么黄金法则,需要考虑下面几个因素:训练集中的正样本的个数;验证集中的正样本的个数;工作日和非工作日对于业务和目标任务的影响的差别是否很大。\n\n之所以关注**训练集和验证集中的正样本的个数**,是因为对于计算广告和推荐系统的排序任务,点击事件和转化事件相对于曝光事件就是小概率事件,因此这样的数据是非常稀疏的,太少这样的正样本对于模型的学习和评估都不好。\n\n到底训练集和验证集中的正样本多少是合适的,这个没有什么法则,可能的一个尝试的起点是:验证集的正样本至少1K以上,训练集的正样本至少1W以上。如果1天的验证集的正样本个数很少比如不到1K,这种情况就可能需要使用T+N训练方式了(N就是验证集的时间窗口长度),为了让验证集的正样本够量,可以把窗口N拉长到大于1。\n\n同样的道理,对于常见的T取值为7的情况,如果你发现7天的训练集的正样本很少比如小于1W,那么把窗口拉长到超过7天是建议的方式。工作日和非工作日对于业务和目标任务的影响的**差别如果很大**的话,有两种方案:\n![image.png](https://dev-media.amazoncloud.cn/9479e839fb5441659f903e68b87cc182_image.png)\n\n综上所述,工作日和非工作日对于业务的影响的差别如果很大的话,尽量用工作日和非工作日单独建模,其实这个就是子问题即单个数据集是否切分为多个数据集。\n\n理论上来说,基于任何的维度来切分单个数据集为多个数据集都是可以的,只要模型效果持续地好!\n\n在我参与过的项目中,还有一种常见的切分数据集为多个数据集的情况是**按照地域来切分**,或者说每个地域/国家单独一个模型,这个其实也可以归结为建模思路的范畴,在多个实际的项目中发现,当按照国家尤其是那些数据集足够大并且特征覆盖度足够好的国家来建模,就这个国家的业务线上表现的话,单独建模要比把所有国家的数据联合建模的线上效果好(而对于那些数据集比较小或者特征覆盖度不好的那些国家共用一个模型的效果要好一些)。\n\n### **数据集的采样**\n对**于个性化搜索/推荐系统/计算广告的排序任务**来说,主要大的挑战就是每天的正样本(点击样本或者转化样本)相对来说比较少,而负样本则每天都是海量的。那当我们使用**T+1训练方式(T经常选择7天)**的时候,面临如下的几个问题:\n\n**是否需要对负样本做单独采样**:对于这三大领域的排序任务来说,负样本和正样本的比例会非常大(比如经常是几千倍的比例),因此为了让模型学习的好一点,经常需要做一些样本类别不均衡的处理,其中一种常见的处理方法就是下采样,它就是从负样本中采样一定比例的作为最终的训练集中的负样本。\n\n如果要做采样,也是针对训练集中的样本进行采样,**验证集中的样本需要全部保留**(因为需要让验证集尽量和线上的数据分布保持一致,这里主要指的是验证集中的正负样本的比例)。\n\n对于**计算广告的排序任务**,如果训练集中的负样本进行了采样的话,最后用的 ecpm 的排序公式中的 pctr 需要校准(因为 ecpm 公式中的 pctr*bid的 值可能与采样前不同);对于个性化搜索和推荐系统的排序任务,即使训练集的负样本进行了采样,也不需要在最后排序的时候进行校准。\n\n即使做了负样本采样后,**总的数据集还是太大怎么办**。业界的一个共识是,数据集越大,需要的模型就会越大/越复杂,训练这样的模型需要的成本也越高。\n\n因此这里可能会想,是否把训练集窗口缩短为比如5天来减少总的数据集的数量吗?这个不是建议的方式,业界常见的做法还是仍然用**7天的数据做训练集**,然后用分布式训练来缩短训练时间。\n\n**转换延迟问题**:在计算广告领域还有一个常见的转化延迟问题,也就是转化日志上报时间比较晚,比如某些广告当天实际上发生了转化,但是 DSP 侧要过几天才能拿到这些广告的转化日志,因此就会发生一些负样本其实是正样本的问题(这个情况几乎是通用的)。\n\n在这样的情况下,要对 **CVR 预估/IVR 预估来建模**的话,就需要权衡样本的正确性和时效性了。这里有三种方案:\n![image.png](https://dev-media.amazoncloud.cn/9d642ec49873462cae2873548c6994f8_image.png)\n\n### **特征的线上线下一致性问题**\n**在排序任务中**,经常会遇到离线评价指标很好,线上评价指标不好的情况发生,我们称这个为“**线上线下不一致**”。而这个线上线下不一致的一个常见的原因就是因为特征的线上线下不一致。\n\n特征的**线上线下不一致指的是线下训练时样本中的特征的特征值可能会发生变化**,并不和该样本在线上生成时的特征值完全一样。这里有个例外,如果是因为在数据集的质量检查中,探测到有异常特征,应用异常特征处理后(比如用缺失值填充方式)导致的特征的线上线下不一致的话,这个是可以接受的(关于数据集的质量,可以参考我写的另一个文章)。\n\n在我参与的很多项目中,发现有的客户是线上特征处理一套逻辑,线下的特征处理又一套逻辑,这很容易发生线上线下特征不一致。\n\n下面我们先看两个概念,**即模型稳定和特征稳定**。\n\n**模型稳定**,指的是新模型的成长阶段,这个阶段新模型的数据完全可以自给自足;而其他阶段的话,离线特征处理和线上特征处理一般还是分为两套的。\n\n**特征稳定**,指的是没有增删特征,如果需要修改特征(比如增加了新的交叉特征,或者删除了某个特征),那么线上线下特征不一致是正常的。\n\n在满足特征稳定和模型稳定的前提下,为了做到特征的线上线下一致性,当前业界建议的方式:\n\n**线上**的时候**做特征的获取和拼接**(甚至某些特征的生成),并且把拼接得到的特征向量异步落盘(线上落盘的特征向量组成的日志就是原始数据集的特征部分,这样做对线上的系统要求比较高,尤其是对实时或者近实时特征的生成和获取);\n\n**离线**训练的时候,把线上落盘的特征向量日志和反馈的 label 对齐并 join 得到原始的数据集,然后对原始的数据集进行数据集质量的检查和处理后得到最终的数据集。\n\n这里并不是说离线的时候就不需要对数据做额外处理了,比如一些统计类的数据仍然需要离线做统计,得到的结果存到 feature store,线上的时候从 feature store 获取这些数据再做特征处理(比如离线的时候计算某个连续性特征的均值/方差,线上的时候在对该特征做Z-score标准化的时候需要用到它的均值和方差),也就是说这样类似的离线处理是为线上做准备,而不是为线下训练做直接的准备。\n\n#### **结语**\n\n推荐系统排序任务的样本工程到此就讲完了,本文重点讲解了负样本的生成,数据集的来源,数据集的切分,数据集的采样和特征的线上线下一致性,相信大家现在已经对排序阶段有了更深刻的理解。我们接下来会介绍排序模型的调优实践,感谢大家的耐心阅读。\n\n推荐阅读:[推荐系统系列精讲(第三讲): 推荐系统中的召回阶段深入探讨](http://mp.weixin.qq.com/s?__biz=Mzg4NjU5NDUxNg==&mid=2247520210&idx=1&sn=0986333fc176050bd8e88986ddc44c1c&chksm=cf958169f8e2087fee3657abca27e85996325c1307de68316f52314d9c0e0437c2c49b1b9aaf&scene=21#wechat_redirect)\n\n##### **本篇作者**\n\n**梁宇辉**\n亚马逊云科技\n机器学习产品技术专家\n\n负责基于亚马逊云科技的机器学习方案的咨询与设计,专注于机器学习的推广与应用,深度参与了很多真实客户的机器学习项目的构建以及优化。对于深度学习模型分布式训练,推荐系统和计算广告等领域具有丰富经验。\n\n[阅读原文](https://github.com/yuhuiaws/ML-study/tree/main/)\n","render":"<h4><a id=\"_0\"></a><strong>前言:</strong></h4>\n<p>之前的文章我们深入探讨了<strong>推荐系统的召回阶段</strong>,接下来我们进入到<strong>排序阶段</strong>,本文我们介绍<strong>排序任务的样本工程</strong>。</p>\n<p>对于<strong>个性化搜索,计算广告和推荐系统</strong>三大领域来说(下面我们会简称为搜推广),他们的排序阶段比较相似,因此下面的内容对于这三个领域的排序任务来说是相通的。</p>\n<p>排序任务的一个通用特点就是数据集都很大(比如训练集经常都是几百GB以上),这个时候通常使用<strong>分布式训练</strong>来加速,而利用亚马逊云科技的 Amazon SageMaker 机器学习平台跑分布式训练是件简单方便的事情,更多的训练速度优化的细节可以参考我总结的另一篇文章。</p>\n<p>对于排序任务的样本工程,我们需要重点关注:<strong>负样本的生成,数据集的来源,数据集的切分,数据集的采样,特征的线上线下一致性</strong>。更多细节以及更详细的内容可以参考我的 github repo。</p>\n<h3><a id=\"_10\"></a><strong>负样本的生成</strong></h3>\n<p>首先我们来看一个很重要的概念“<strong>曝光</strong>”,在搜索和推荐系统领域中常常提到的“曝光”和我们日常生活中说的“曝光”的含义有区别,日常生活中的“曝光”指的是某个东西/物体暴露在你面前,而搜索和推荐系统领域中的“曝光”常常指的是<strong>从服务器侧需要返回的整个列表</strong>,而不只是终端用户看到的那些物品item/搜索结果;而计算广告领域中的“曝光”则与我们日常生活中的“曝光”的含义比较接近。<strong>“曝光”并不表示终端用户看到了</strong>(这个是很重要的,也是很容易被忽略的),这里又细分两种情况:<br />\n<img src=\"https://dev-media.amazoncloud.cn/068b680d110c456a8f831862e15a7ba2_image.png\" alt=\"image.png\" /></p>\n<p>现在我们理解了“曝光”的含义了,我们接着来看排序任务的负样本生成。这里我们以推荐系统的 CTR 点击率预估排序任务为例,常见有三种方案:<br />\n<img src=\"https://dev-media.amazoncloud.cn/f6431808b37047b38addd7da99ba2d68_image.png\" alt=\"image.png\" /></p>\n<p>在我接触的客户中,使用方案 A 的是大多数。相对于方案 B,方案 A 和 C 可能会引入更多的<strong>噪声</strong>(因为有一些负样本并不是真的是终端用户不感兴趣的,可能仅仅是因为他们没有看到而已)。</p>\n<p>前面的三个方案都是关注曝光的 item,并没有关心用户是否看到了这些 item,那有没有更好的逻辑来提升负样本的可信度呢?</p>\n<p>在某些客户中,据说他们能从客户端的<strong>埋点日志</strong>中相对比较准确的判断终端用户是否看到了曝光的东西,我理解这个判断逻辑可能会涉及到:屏幕的大小,曝光位的大小,手指滑动触屏的速度(太快的滑动速度其实会啥都看不到),手指在曝光位停留的时间(停留的时间越长可能表示看清楚了)等等。</p>\n<p>如果能有比较靠谱的判断逻辑知道终端用户看了哪些曝光的 item,这样获得的负样本可能更可信。</p>\n<h3><a id=\"_25\"></a><strong>数据集的来源</strong></h3>\n<p>关于<strong>数据集的来源</strong>,我遇到过两个很典型的子问题:一是数据集从多个<strong>不同的地方/公司</strong>收集;二是数据集从多个<strong>不同的模型或者策略</strong>收集。</p>\n<p>我们先看第二个子问题即数据集从多个<strong>不同的模型或者策略收集</strong>,下面即将介绍的新模型经历的某个阶段会涉及到这个子问题。</p>\n<p>新模型一般都会经历如下几个阶段(这里的新模型指的是完全不同的模型,不是同一个模型的不同版本,比如老模型是 xgboost 模型,新的模型是wide & deep 模型;或者新模型是 DeepFM 模型,老的用的业务规则):<br />\n<img src=\"https://dev-media.amazoncloud.cn/11d2886b597a481aaf67f6853a507817_image.png\" alt=\"image.png\" /></p>\n<p>对于第一个子问题即数据集从多个<strong>不同的地方/公司</strong>收集,我的一个客户的数据集就是来自三个不同的公司实体,那么就面临如何使用这样的数据集的问题,有三种方案:<br />\n<img src=\"https://dev-media.amazoncloud.cn/ea67ae7cf5534e9b964fe546d160beca_image.png\" alt=\"image.png\" /></p>\n<p>通过对两个子问题的阐述,我们能发现这样的数据集本质上不是“同质“的,都是混血的。从直觉上看,不同来源的数据的分布会不一致,用这样的数据集直接建模可能对模型效果有不好的影响。</p>\n<p>对于第二个子问题,可以通过新模型的重生阶段和成长阶段来规避;对于第一个子问题,可以参考 <strong>A/B test</strong> 的结果做调整,只要自己家公司模型产生的数据集足够多,并且特征覆盖度也足够好,那么可以尝试给用这样的数据集训练完的模型更大的线上流量,更大的线上流量可能会得到更高的特征覆盖度的数据,从而形成良性循环。</p>\n<h3><a id=\"_40\"></a><strong>数据集的切分</strong></h3>\n<p>数据集切分常遇到的两种问题:一种是验证集和训练集如何切分;另一种是单个数据集是否切分为多个数据集。</p>\n<p>我们先来看第一个问题即<strong>验证集和训练集如何切分</strong>:在做计算广告的排序模型和推荐系统的排序模型的项目中,发现大部分的客户的训练使用的就是2种典型方式即<strong>T+1训练方式</strong>和<strong>每天增量训练方式</strong>,而T+1训练方式占据绝大多数,因此这里的数据集切分就只是讨论这种方式及其变体,T+1训练参考下图:<br />\n<img src=\"https://dev-media.amazoncloud.cn/2758de3008e24134b16f9b31db02caa4_image.png\" alt=\"image.png\" /></p>\n<p>正如上图所示,所谓的<strong>T+1训练方式</strong>有几个<strong>要素</strong>:全量T天的训练集,并且模型从头开始训练;紧接着的那一天作为验证集;基于滑动窗口的训练,滑窗为1天;每天都会更新线上模型。虽然排序任务并不是像时间序列预测那样的强时间依赖的任务,但是最常见的T+1训练方式中的T天的训练集和1天的验证集的边界还是按照时间先后顺序来切分的。</p>\n<p>对于T+1训练方式,有两个问题即<strong>T取多少天</strong>以及<strong>验证集1天是否合适</strong>。这两个问题会涉及到数据集的规模,选取几天的数据作为训练集和几天的数据作为验证集没有什么黄金法则,需要考虑下面几个因素:训练集中的正样本的个数;验证集中的正样本的个数;工作日和非工作日对于业务和目标任务的影响的差别是否很大。</p>\n<p>之所以关注<strong>训练集和验证集中的正样本的个数</strong>,是因为对于计算广告和推荐系统的排序任务,点击事件和转化事件相对于曝光事件就是小概率事件,因此这样的数据是非常稀疏的,太少这样的正样本对于模型的学习和评估都不好。</p>\n<p>到底训练集和验证集中的正样本多少是合适的,这个没有什么法则,可能的一个尝试的起点是:验证集的正样本至少1K以上,训练集的正样本至少1W以上。如果1天的验证集的正样本个数很少比如不到1K,这种情况就可能需要使用T+N训练方式了(N就是验证集的时间窗口长度),为了让验证集的正样本够量,可以把窗口N拉长到大于1。</p>\n<p>同样的道理,对于常见的T取值为7的情况,如果你发现7天的训练集的正样本很少比如小于1W,那么把窗口拉长到超过7天是建议的方式。工作日和非工作日对于业务和目标任务的影响的<strong>差别如果很大</strong>的话,有两种方案:<br />\n<img src=\"https://dev-media.amazoncloud.cn/9479e839fb5441659f903e68b87cc182_image.png\" alt=\"image.png\" /></p>\n<p>综上所述,工作日和非工作日对于业务的影响的差别如果很大的话,尽量用工作日和非工作日单独建模,其实这个就是子问题即单个数据集是否切分为多个数据集。</p>\n<p>理论上来说,基于任何的维度来切分单个数据集为多个数据集都是可以的,只要模型效果持续地好!</p>\n<p>在我参与过的项目中,还有一种常见的切分数据集为多个数据集的情况是<strong>按照地域来切分</strong>,或者说每个地域/国家单独一个模型,这个其实也可以归结为建模思路的范畴,在多个实际的项目中发现,当按照国家尤其是那些数据集足够大并且特征覆盖度足够好的国家来建模,就这个国家的业务线上表现的话,单独建模要比把所有国家的数据联合建模的线上效果好(而对于那些数据集比较小或者特征覆盖度不好的那些国家共用一个模型的效果要好一些)。</p>\n<h3><a id=\"_63\"></a><strong>数据集的采样</strong></h3>\n<p>对<strong>于个性化搜索/推荐系统/计算广告的排序任务</strong>来说,主要大的挑战就是每天的正样本(点击样本或者转化样本)相对来说比较少,而负样本则每天都是海量的。那当我们使用**T+1训练方式(T经常选择7天)**的时候,面临如下的几个问题:</p>\n<p><strong>是否需要对负样本做单独采样</strong>:对于这三大领域的排序任务来说,负样本和正样本的比例会非常大(比如经常是几千倍的比例),因此为了让模型学习的好一点,经常需要做一些样本类别不均衡的处理,其中一种常见的处理方法就是下采样,它就是从负样本中采样一定比例的作为最终的训练集中的负样本。</p>\n<p>如果要做采样,也是针对训练集中的样本进行采样,<strong>验证集中的样本需要全部保留</strong>(因为需要让验证集尽量和线上的数据分布保持一致,这里主要指的是验证集中的正负样本的比例)。</p>\n<p>对于<strong>计算广告的排序任务</strong>,如果训练集中的负样本进行了采样的话,最后用的 ecpm 的排序公式中的 pctr 需要校准(因为 ecpm 公式中的 pctr*bid的 值可能与采样前不同);对于个性化搜索和推荐系统的排序任务,即使训练集的负样本进行了采样,也不需要在最后排序的时候进行校准。</p>\n<p>即使做了负样本采样后,<strong>总的数据集还是太大怎么办</strong>。业界的一个共识是,数据集越大,需要的模型就会越大/越复杂,训练这样的模型需要的成本也越高。</p>\n<p>因此这里可能会想,是否把训练集窗口缩短为比如5天来减少总的数据集的数量吗?这个不是建议的方式,业界常见的做法还是仍然用<strong>7天的数据做训练集</strong>,然后用分布式训练来缩短训练时间。</p>\n<p><strong>转换延迟问题</strong>:在计算广告领域还有一个常见的转化延迟问题,也就是转化日志上报时间比较晚,比如某些广告当天实际上发生了转化,但是 DSP 侧要过几天才能拿到这些广告的转化日志,因此就会发生一些负样本其实是正样本的问题(这个情况几乎是通用的)。</p>\n<p>在这样的情况下,要对 <strong>CVR 预估/IVR 预估来建模</strong>的话,就需要权衡样本的正确性和时效性了。这里有三种方案:<br />\n<img src=\"https://dev-media.amazoncloud.cn/9d642ec49873462cae2873548c6994f8_image.png\" alt=\"image.png\" /></p>\n<h3><a id=\"_81\"></a><strong>特征的线上线下一致性问题</strong></h3>\n<p><strong>在排序任务中</strong>,经常会遇到离线评价指标很好,线上评价指标不好的情况发生,我们称这个为“<strong>线上线下不一致</strong>”。而这个线上线下不一致的一个常见的原因就是因为特征的线上线下不一致。</p>\n<p>特征的<strong>线上线下不一致指的是线下训练时样本中的特征的特征值可能会发生变化</strong>,并不和该样本在线上生成时的特征值完全一样。这里有个例外,如果是因为在数据集的质量检查中,探测到有异常特征,应用异常特征处理后(比如用缺失值填充方式)导致的特征的线上线下不一致的话,这个是可以接受的(关于数据集的质量,可以参考我写的另一个文章)。</p>\n<p>在我参与的很多项目中,发现有的客户是线上特征处理一套逻辑,线下的特征处理又一套逻辑,这很容易发生线上线下特征不一致。</p>\n<p>下面我们先看两个概念,<strong>即模型稳定和特征稳定</strong>。</p>\n<p><strong>模型稳定</strong>,指的是新模型的成长阶段,这个阶段新模型的数据完全可以自给自足;而其他阶段的话,离线特征处理和线上特征处理一般还是分为两套的。</p>\n<p><strong>特征稳定</strong>,指的是没有增删特征,如果需要修改特征(比如增加了新的交叉特征,或者删除了某个特征),那么线上线下特征不一致是正常的。</p>\n<p>在满足特征稳定和模型稳定的前提下,为了做到特征的线上线下一致性,当前业界建议的方式:</p>\n<p><strong>线上</strong>的时候<strong>做特征的获取和拼接</strong>(甚至某些特征的生成),并且把拼接得到的特征向量异步落盘(线上落盘的特征向量组成的日志就是原始数据集的特征部分,这样做对线上的系统要求比较高,尤其是对实时或者近实时特征的生成和获取);</p>\n<p><strong>离线</strong>训练的时候,把线上落盘的特征向量日志和反馈的 label 对齐并 join 得到原始的数据集,然后对原始的数据集进行数据集质量的检查和处理后得到最终的数据集。</p>\n<p>这里并不是说离线的时候就不需要对数据做额外处理了,比如一些统计类的数据仍然需要离线做统计,得到的结果存到 feature store,线上的时候从 feature store 获取这些数据再做特征处理(比如离线的时候计算某个连续性特征的均值/方差,线上的时候在对该特征做Z-score标准化的时候需要用到它的均值和方差),也就是说这样类似的离线处理是为线上做准备,而不是为线下训练做直接的准备。</p>\n<h4><a id=\"_102\"></a><strong>结语</strong></h4>\n<p>推荐系统排序任务的样本工程到此就讲完了,本文重点讲解了负样本的生成,数据集的来源,数据集的切分,数据集的采样和特征的线上线下一致性,相信大家现在已经对排序阶段有了更深刻的理解。我们接下来会介绍排序模型的调优实践,感谢大家的耐心阅读。</p>\n<p>推荐阅读:<a href=\"http://mp.weixin.qq.com/s?__biz=Mzg4NjU5NDUxNg==&mid=2247520210&idx=1&sn=0986333fc176050bd8e88986ddc44c1c&chksm=cf958169f8e2087fee3657abca27e85996325c1307de68316f52314d9c0e0437c2c49b1b9aaf&scene=21#wechat_redirect\" target=\"_blank\">推荐系统系列精讲(第三讲): 推荐系统中的召回阶段深入探讨</a></p>\n<h5><a id=\"_108\"></a><strong>本篇作者</strong></h5>\n<p><strong>梁宇辉</strong><br />\n亚马逊云科技<br />\n机器学习产品技术专家</p>\n<p>负责基于亚马逊云科技的机器学习方案的咨询与设计,专注于机器学习的推广与应用,深度参与了很多真实客户的机器学习项目的构建以及优化。对于深度学习模型分布式训练,推荐系统和计算广告等领域具有丰富经验。</p>\n<p><a href=\"https://github.com/yuhuiaws/ML-study/tree/main/\" target=\"_blank\">阅读原文</a></p>\n"}