{"value":"#### **前言**\n\n\n\n我们之前详细介绍了 Data-centric AI 的两个核心即特征工程和样本工程,让大家对特征工程的方法论以及样本工程的艺术特质有了更多更深的理解,本文我们继续介绍 Data-centric AI 的第三个核心即数据集质量。\n\n\n\n数据集的质量再如何强调都不过分,我认为在数据这个领域,数据集的质量就是第一要务。对于机器学习来说,没有高质量的数据集作为前提,模型就学习不到有用的知识,也就是所谓的“垃圾进,垃圾出”。数据集的质量是个很大的话题,本文根据我在多个计算广告和推荐系统的项目中的实战经验尝试总结一下,其实对于结构化数据建模来说,基本上下面谈到的内容都是通用的。\n\n\n\n更详细的 data-centric AI 相关的内容请参考该 **github** **repo**。数据集的质量包括但不限于如下的几种(我认为以下四个是最重要的),即异常样本以及异常特征的识别和处理,Label的正确性问题,特征的覆盖度问题,样本和特征的正确性检查。在具体的项目中,常常发现很多客户都是在发现模型效果(包括离线效果和线上效果)不理想或者在训练过程中遇到一些错误时才会去检查样本和特征,这个是非常不建议的做法。\n\n\n\n最建议的做法还是在开始训练之前和线上预测时就对数据集的质量进行严格检查。可能这样做的话,前期的投入是比较大的,但是只有这样,之后训练完的模型的离线效果才更可信;否则遇到问题再回溯来检查数据集的做法看似投入小,实则是定时炸弹,你永远不知道它什么时候爆炸!\n\n\n\ngithub repo:\n\n[https://github.com/yuhuiaws/ML-study](https://github.com/yuhuiaws/ML-study)\n异常样本以及异常特征的识别和处理\n\n\n\n用数据集来训练模型,我们希望送入模型的数据是干净合理的,首要的任务就是把原始的数据集进行清洗,把异常样本和异常特征识别出来并做相应的处理,因此一般建议把异常检测和异常处理作为常规任务(比如排序任务)的前置任务来做。异常样本和异常特征的检测/识别属于异常检测的范畴,经常用统计方法,数据分析或者机器学习的方法来识别异常(三者结合起来做异常检测的效果最好),这里我们不做介绍,感兴趣的同学可以参考我总结的**异常检测的文章**([https://github.com/yuhuiaws/ML-study/tree/main/ML%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E5%85%A5%E9%97%A8](https://github.com/yuhuiaws/ML-study/tree/main/ML%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E5%85%A5%E9%97%A8))。\n\n\n\n异常点的归因是特征粒度即异常特征的话,经常用的处理方式就是把异常值当做缺失值处理(缺失值处理可以参考之前的 **Data-centric** **AI 之特征工程第一讲**),或者使用 3-sigma 上下界截断处理,最大最小值截断处理以及分位数上下界截断处理(参考 **Amazon** **SageMaker** **Data** **Wrangler 中关于异常值的处理** , 它提供了免代码实现);异常点的归因如果是样本粒度即异常样本的话,常见的方式就是从该数据集中剔除该异常样本,注意这里剔除并不是丢弃,建议的方法是把这个宝贵的异常样本单独存储以便之后做异常检测任务。\n\n\n\nAmazon SageMaker Data Wrangler 中关于异常值的处理:\n\n[https://docs.aws.amazon.com/sagemaker/latest/dg/data-wrangler-transform.html](https://docs.aws.amazon.com/sagemaker/latest/dg/data-wrangler-transform.html)\n\n\n\n下面介绍项目中遇到的几个典型的案例:\n![image.png](https://dev-media.amazoncloud.cn/cf7298b2c49e4544a7047243fa16f22c_image.png)\n### **Label 的正确性问题**\n\n\n\nLabel 就是模型学习的指导/监督信号,所以保证 label 的正确性是显而易见并且非常重要的。但是保证样本的 label 的正确性不是看起来那么容易的,在搜推广三大领域的排序任务的数据集中经常会遇到如下几种情况:\n\n\n\n#### **1.转化延迟问题:**\n\n\n\n这个问题在计算广告领域很常见,由于转化日志上报时间比较晚,比如某些广告当天实际上发生了转化,但是 DSP 侧要过几天才能拿到这些广告的转化日志,因此就会发生一些负样本其实是正样本的问题。在这样的情况下,要对 CVR 预估来建模的话,就需要权衡样本的正确性和时效性了。在之后拿到转化延迟的数据后,记得重新给之前对应的同一个样本重新修改 label(实现时每个样本可以设置唯一 id,然后通过 id 来对齐),目的是下一次训练的时候这个样本的 label 是正确的。针对转化延迟问题,这里有三种方案:![image.png](https://dev-media.amazoncloud.cn/4f03bbe7df6b43c889d2b799248b1505_image.png)\n#### **2.误点击**:\n\n\n\n误点击这样的事件是很正常的,但是把误点击作为最后的用户的点击反馈就不合理了。对于终端用户不小心点击了 item 或者广告的情况,应该 label 为0。\n\n\n\n比如在一个客户的项目中,开屏广告(开屏广告就容易让人误点击)日志中发现了很多疑似的误点击。我们这里需要合适的代码逻辑来判定当前的点击事件是否是误点击,或者通过埋点 SDK 来判定是否是合理的点击,如果是的话才写点击事件到日志中。\n\n#### **3.点击了并不表示就感兴趣:**\n\n\n\n这个情况在推荐系统和个性化搜索领域中比较常见。我们经常会被一些图片或者文本标题所“吸引”,从而点击进去看看详实,进去以后发现原来是标题党或者图文不符,而且我们对里面的内容本身并不感兴趣,这个时候就不应该把这个 item 打 label 为1。\n\n\n\n我们要明白,对 item 打 label 的目的是刻画该用户对这个 item 是否感兴趣,而不是说对 item 是否发生了点击操作(这个对于建模没有意义)。举个例子,比如在长视频/电影推荐中,某用户对某个推荐的 item 点击进入并观看了5秒就关闭,那么可以认为该用户对这个 item 并不感兴趣,因此这样的点击对应的样本的 label 需要标注为0而不是1(对于这个场景,可能用播放比率和播放时长做条件或的方式来打label可能更合理)。\n\n\n\n#### **4.是否是 re-label 导致的问题**:\n\n\n\n使用 T+1训练方式时,经常会遇到同一个设备 id 或同一个 userid 对同一个 item 或者广告在多次曝光行为下会有不同的点击行为或者转化行为。由此带来的现象就是在比如7天的训练日志中,除了时间戳,会有其他特征完全一样的样本出现,但是前几次 label 为0,最后一次label 为1。这种情况下,是否需要把前几次的 label 修改为1,也就是所谓的 re-label 问题。在这种情况下,建议的处理方式:\n\n\n\n不要对反复曝光的样本做 re-label,也就是遵守该用户的真实点击行为或者转化行为就可以。这个情况在很多客户的项目中都出现过,甚至有的客户说,他们做过统计,item 或者广告被点击需要平均曝光7次;转化的话需要平均曝光20次。\n\n\n\n从这个角度来说,太严格的过滤模块不一定对业务就好:比如对于某个用户,在召回的结果中是否应该过滤掉该用户最近三个月曝光过或者点击过的 item/广告。太频繁的曝光肯定是需要过滤的(否则对终端用户不友好),这个频率需要具体根据业务来确定。\n\n\n\n可以增加一些其他的特征来让样本有辨识度(目的是在 label 取值不同的情况下,让特征向量对于模型来说区别比较大)。比如可以利用时间戳来把一天分为24个桶作为一个离散特征;还可以把对应 userid/设备 id 最近一段时间的安装列表以及点击列表作为强特征加入模型(这一块的数据处理,我们可以借助 Amazon EMR 大数据平台或者 Amazon Redshift 数据仓库来实现)。\n\n\n\nAmazon EMR:\n\n[https://www.amazonaws.cn/elasticmapreduce/](https://www.amazonaws.cn/elasticmapreduce/)\n\nAmazon Redshift:\n\n[https://www.amazonaws.cn/redshift/](https://www.amazonaws.cn/redshift/)\n#### **特征的覆盖度问题**\n\n\n\n特征的覆盖度(Category 特征和连续特征都有覆盖度的问题)尤其是训练集中的特征的覆盖度,最终会反映到模型对该特征能了解的程度。理想情况下,我们希望训练集中的每个样本都没有缺失值,并且训练集会把每个特征的所有可能的取值都能覆盖到并且每个取值出现的频次足够高并且频次有上限(为了样本公平性),这样模型学习的才够充分,之后对验证集以及线上数据做推理才更准确。\n\n\n\n现实中,每个特征总是或多或少会有覆盖度的问题。Category 特征的覆盖度问题更复杂和常见,因此我们这里主要讨论 Category 特征的覆盖度问题(连续特征通过特征缩放处理或者离散化可以把它的覆盖度问题缓解或者转移)。导致特征覆盖度问题的经常会有如下的3种情况:\n\n\n\n特征获取困难:在项目的过程中,经常有很多特征的获取是比较困难的,具体又分为2种情况:\n![image.png](https://dev-media.amazoncloud.cn/6d45a12097524617a2e0229f8be2d6c4_image.png)\n对于样本粒度来说,需要逐个检查每个样本的缺失情况。对于某个样本,如果缺失的特征数量太多比如超过1半数量的特征都缺失,那么可以考虑是否可以把这个样本给去除。\n\n\n\n在一些客户的项目中,发现他们尝试通过其他模型来生成一些用户的隐私特征,并且把这些特征用在下游的模型中:比如男女性别,年龄段,是否有孩子等等这样的特征对于某些目标任务来说比较重要,但是这些特征很难从终端用户真实的获得。因此有的客户就通过规则/数据分析/机器学习的方式来根据该用户的行为来生成这些特征。\n\n\n\n本身这个生成的特征的正确性就没有办法保证,那么把这个生成的特征放入下游的模型中,对模型是有帮助还是有负作用是需要离线评估以及线上AB test 来评价的。\n\n\n\n非高基数id类特征的 category 特征(比如“国家”这样的特征)分布可能天然就不均衡:如果某些特征值的样本数很低比如少于10次,那么可以考虑特征向上合并或者把那些小类别统一归并为“Other”(所谓的特征向上合并,指的是可以重新规划该 category 的类别,把细类别合并为粗类别,从而改善特征的覆盖度)。\n\n\n\n这里有个例外,比如约会类 app,有的“城市”比如“合肥”的样本少,如果把这些小样本的城市都合并为一个 other 或特征向上合并,会违背了同城约会可能性更高这样的事实,这个时候可能就不要合并了。\n\n\n\n低频的高基数 id 类特征值被过滤:也就是把包含长尾 id 的整个样本从训练集中干掉了。对于搜推广三大领域来说,像 userid/deviceid/itemid 这样的特征是典型的高维稀疏特征,他们的长尾的 id 有很多。长尾的 id 常见的处理方式有如下三种:![image.png](https://dev-media.amazoncloud.cn/92a5b45bf0c24a95b5995b20cf1d7d18_image.png)\n由此可以看到,如果特征的覆盖度问题是因为低频的高基数id类特征被过滤后导致的,那么可以考虑特征的频次阈值是否可以根据业务特点来重新调整,或重新评估并权衡其他的长尾id的处理方法(可能评估完后会仍然使用低频特征被过滤的方案)。围绕这一块的特征处理,我们可以通过 **SageMaker** **Processing** 来完成,写好处理逻辑的脚本,调用一下 SageMaker Processing API 就可以了。\n\n\n\n另外一个相关的问题是,对于训练集中有的用户的样本很多,有的用户的样本很少,这样模型可能会被样本多的活跃用户所影响,如何缓解这样的问题?Youtube 电影推荐深度模型中采用的方法是为每个用户固定样本数量上限,尽量平等地对待每个用户,能明显提升线上效果。\n\n\n\nSageMaker Processing:\n\n[https://docs.aws.amazon.com/sagemaker/latest/dg/processing-job.html](https://docs.aws.amazon.com/sagemaker/latest/dg/processing-job.html)\n#### **样本和特征的正确性检查**\n\n\n\n这个看似最简单的事情,但是确实是最容易忽略,也是经常出问题的地方。我见到的客户中,或多或少都会对样本和特征做一些检查,但是仍然检查力度太少。\n\n\n\n先不说对模型学习效果如何,就是出了问题 debug 也费劲(尤其是当出现奇怪的问题或者复杂的问题的时候),而且经常会前功尽弃(比如训练到几个小时因为样本有问题报错退出,尽管通过保存 checkpoint 可以尽量降低伤害程度,但是仍然会浪费感情),对成本带来无谓的消耗。因此,我建议至少做如下的正确性检查:\n![image.png](https://dev-media.amazoncloud.cn/4c42fa48a1a74a04bdf725a529d68fa1_image.png)\nSageMaker Pipe mode:\n\n[https://docs.aws.amazon.com/sagemaker/latest/dg/model-access-training-data.html](https://docs.aws.amazon.com/sagemaker/latest/dg/model-access-training-data.html)\n\n\n\n关于样本和特征的正确性检查,建议如下:每个公司对每个数据集都建立和维护一个 checklist;对样本和特征的这个卫生检查,建议不要放在训练脚本中去做,而是用一个单独的前置任务去做这个事情,不要浪费宝贵的训练资源(我们可以在整个 ML workflow 中用 SageMaker Processing 做样本和特征的卫生检查,然后用 SageMaker Training做模型训练,并且两者可以通过 SageMaker Pipeline 串起来,自动执行全部流程)。\n\n\n\nSageMaker Processing:\n\n[https://docs.aws.amazon.com/sagemaker/latest/dg/processing-job.html](https://docs.aws.amazon.com/sagemaker/latest/dg/processing-job.html)\n\nSageMaker Training:\n\n[https://docs.aws.amazon.com/sagemaker/latest/dg/train-model.html](https://docs.aws.amazon.com/sagemaker/latest/dg/train-model.html\n)\nSageMaker Pipeline:\n\n[https://docs.aws.amazon.com/sagemaker/latest/dg/pipelines-sdk.html](https://docs.aws.amazon.com/sagemaker/latest/dg/pipelines-sdk.html)\n#### **总结**\n\n\n\n线上和线下都应该尽可能对数据集的质量进行检查。线下的时候,这个检查并不只是发生在数据集清洗的开始阶段,其实只要对数据集进行了修改(比如在异常样本/特征的识别和处理后增加了新的交叉特征),那么都需要再做一遍质量检查的。\n\n\n\nData-centric AI 之数据集的质量到此介绍完毕,本文详细介绍了数据集质量最重要和最常见的四个方面即异常样本以及异常特征的识别和处理,Label的正确性问题,特征的覆盖度问题,样本和特征的正确性检查。到此为止,整个 Data-centric AI 系统的讲解也结束了。\n\n\n\n整个系列文章比较完整的涵盖了 Data-centric AI 的三个核心即特征工程,样本工程和数据集质量的内容,相信大家对结构化数据建模有了整体的把握以及对数据更深刻的理解和洞察。只要你有高质量的数据,现在就可以尝试用一个简单模型来对小型的目标任务来建模了,再次感谢大家耐心的阅读。\n\n**本篇作者**\n\n**梁宇辉**\n\n亚马逊云科技\n\n机器学习产品技术专家\n负责基于亚马逊云科技的机器学习方案的咨询与设计,专注于机器学习的推广与应用,深度参与了很多真实客户的机器学习项目的构建以及优化。对于深度学习模型分布式训练,推荐系统和计算广告等领域具有丰富经验。\n\n\n\n","render":"<h4><a id=\"_0\"></a><strong>前言</strong></h4>\n<p>我们之前详细介绍了 Data-centric AI 的两个核心即特征工程和样本工程,让大家对特征工程的方法论以及样本工程的艺术特质有了更多更深的理解,本文我们继续介绍 Data-centric AI 的第三个核心即数据集质量。</p>\n<p>数据集的质量再如何强调都不过分,我认为在数据这个领域,数据集的质量就是第一要务。对于机器学习来说,没有高质量的数据集作为前提,模型就学习不到有用的知识,也就是所谓的“垃圾进,垃圾出”。数据集的质量是个很大的话题,本文根据我在多个计算广告和推荐系统的项目中的实战经验尝试总结一下,其实对于结构化数据建模来说,基本上下面谈到的内容都是通用的。</p>\n<p>更详细的 data-centric AI 相关的内容请参考该 <strong>github</strong> <strong>repo</strong>。数据集的质量包括但不限于如下的几种(我认为以下四个是最重要的),即异常样本以及异常特征的识别和处理,Label的正确性问题,特征的覆盖度问题,样本和特征的正确性检查。在具体的项目中,常常发现很多客户都是在发现模型效果(包括离线效果和线上效果)不理想或者在训练过程中遇到一些错误时才会去检查样本和特征,这个是非常不建议的做法。</p>\n<p>最建议的做法还是在开始训练之前和线上预测时就对数据集的质量进行严格检查。可能这样做的话,前期的投入是比较大的,但是只有这样,之后训练完的模型的离线效果才更可信;否则遇到问题再回溯来检查数据集的做法看似投入小,实则是定时炸弹,你永远不知道它什么时候爆炸!</p>\n<p>github repo:</p>\n<p><a href=\"https://github.com/yuhuiaws/ML-study\" target=\"_blank\">https://github.com/yuhuiaws/ML-study</a><br />\n异常样本以及异常特征的识别和处理</p>\n<p>用数据集来训练模型,我们希望送入模型的数据是干净合理的,首要的任务就是把原始的数据集进行清洗,把异常样本和异常特征识别出来并做相应的处理,因此一般建议把异常检测和异常处理作为常规任务(比如排序任务)的前置任务来做。异常样本和异常特征的检测/识别属于异常检测的范畴,经常用统计方法,数据分析或者机器学习的方法来识别异常(三者结合起来做异常检测的效果最好),这里我们不做介绍,感兴趣的同学可以参考我总结的<strong>异常检测的文章</strong>(<a href=\"https://github.com/yuhuiaws/ML-study/tree/main/ML%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E5%85%A5%E9%97%A8\" target=\"_blank\">https://github.com/yuhuiaws/ML-study/tree/main/ML%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E5%85%A5%E9%97%A8</a>)。</p>\n<p>异常点的归因是特征粒度即异常特征的话,经常用的处理方式就是把异常值当做缺失值处理(缺失值处理可以参考之前的 <strong>Data-centric</strong> <strong>AI 之特征工程第一讲</strong>),或者使用 3-sigma 上下界截断处理,最大最小值截断处理以及分位数上下界截断处理(参考 <strong>Amazon</strong> <strong>SageMaker</strong> <strong>Data</strong> <strong>Wrangler 中关于异常值的处理</strong> , 它提供了免代码实现);异常点的归因如果是样本粒度即异常样本的话,常见的方式就是从该数据集中剔除该异常样本,注意这里剔除并不是丢弃,建议的方法是把这个宝贵的异常样本单独存储以便之后做异常检测任务。</p>\n<p>Amazon SageMaker Data Wrangler 中关于异常值的处理:</p>\n<p><a href=\"https://docs.aws.amazon.com/sagemaker/latest/dg/data-wrangler-transform.html\" target=\"_blank\">https://docs.aws.amazon.com/sagemaker/latest/dg/data-wrangler-transform.html</a></p>\n<p>下面介绍项目中遇到的几个典型的案例:<br />\n<img src=\"https://dev-media.amazoncloud.cn/cf7298b2c49e4544a7047243fa16f22c_image.png\" alt=\"image.png\" /></p>\n<h3><a id=\"Label__43\"></a><strong>Label 的正确性问题</strong></h3>\n<p>Label 就是模型学习的指导/监督信号,所以保证 label 的正确性是显而易见并且非常重要的。但是保证样本的 label 的正确性不是看起来那么容易的,在搜推广三大领域的排序任务的数据集中经常会遇到如下几种情况:</p>\n<h4><a id=\"1_51\"></a><strong>1.转化延迟问题:</strong></h4>\n<p>这个问题在计算广告领域很常见,由于转化日志上报时间比较晚,比如某些广告当天实际上发生了转化,但是 DSP 侧要过几天才能拿到这些广告的转化日志,因此就会发生一些负样本其实是正样本的问题。在这样的情况下,要对 CVR 预估来建模的话,就需要权衡样本的正确性和时效性了。在之后拿到转化延迟的数据后,记得重新给之前对应的同一个样本重新修改 label(实现时每个样本可以设置唯一 id,然后通过 id 来对齐),目的是下一次训练的时候这个样本的 label 是正确的。针对转化延迟问题,这里有三种方案:<img src=\"https://dev-media.amazoncloud.cn/4f03bbe7df6b43c889d2b799248b1505_image.png\" alt=\"image.png\" /></p>\n<h4><a id=\"2_56\"></a><strong>2.误点击</strong>:</h4>\n<p>误点击这样的事件是很正常的,但是把误点击作为最后的用户的点击反馈就不合理了。对于终端用户不小心点击了 item 或者广告的情况,应该 label 为0。</p>\n<p>比如在一个客户的项目中,开屏广告(开屏广告就容易让人误点击)日志中发现了很多疑似的误点击。我们这里需要合适的代码逻辑来判定当前的点击事件是否是误点击,或者通过埋点 SDK 来判定是否是合理的点击,如果是的话才写点击事件到日志中。</p>\n<h4><a id=\"3_66\"></a><strong>3.点击了并不表示就感兴趣:</strong></h4>\n<p>这个情况在推荐系统和个性化搜索领域中比较常见。我们经常会被一些图片或者文本标题所“吸引”,从而点击进去看看详实,进去以后发现原来是标题党或者图文不符,而且我们对里面的内容本身并不感兴趣,这个时候就不应该把这个 item 打 label 为1。</p>\n<p>我们要明白,对 item 打 label 的目的是刻画该用户对这个 item 是否感兴趣,而不是说对 item 是否发生了点击操作(这个对于建模没有意义)。举个例子,比如在长视频/电影推荐中,某用户对某个推荐的 item 点击进入并观看了5秒就关闭,那么可以认为该用户对这个 item 并不感兴趣,因此这样的点击对应的样本的 label 需要标注为0而不是1(对于这个场景,可能用播放比率和播放时长做条件或的方式来打label可能更合理)。</p>\n<h4><a id=\"4_relabel__78\"></a><strong>4.是否是 re-label 导致的问题</strong>:</h4>\n<p>使用 T+1训练方式时,经常会遇到同一个设备 id 或同一个 userid 对同一个 item 或者广告在多次曝光行为下会有不同的点击行为或者转化行为。由此带来的现象就是在比如7天的训练日志中,除了时间戳,会有其他特征完全一样的样本出现,但是前几次 label 为0,最后一次label 为1。这种情况下,是否需要把前几次的 label 修改为1,也就是所谓的 re-label 问题。在这种情况下,建议的处理方式:</p>\n<p>不要对反复曝光的样本做 re-label,也就是遵守该用户的真实点击行为或者转化行为就可以。这个情况在很多客户的项目中都出现过,甚至有的客户说,他们做过统计,item 或者广告被点击需要平均曝光7次;转化的话需要平均曝光20次。</p>\n<p>从这个角度来说,太严格的过滤模块不一定对业务就好:比如对于某个用户,在召回的结果中是否应该过滤掉该用户最近三个月曝光过或者点击过的 item/广告。太频繁的曝光肯定是需要过滤的(否则对终端用户不友好),这个频率需要具体根据业务来确定。</p>\n<p>可以增加一些其他的特征来让样本有辨识度(目的是在 label 取值不同的情况下,让特征向量对于模型来说区别比较大)。比如可以利用时间戳来把一天分为24个桶作为一个离散特征;还可以把对应 userid/设备 id 最近一段时间的安装列表以及点击列表作为强特征加入模型(这一块的数据处理,我们可以借助 Amazon EMR 大数据平台或者 Amazon Redshift 数据仓库来实现)。</p>\n<p>Amazon EMR:</p>\n<p><a href=\"https://www.amazonaws.cn/elasticmapreduce/\" target=\"_blank\">https://www.amazonaws.cn/elasticmapreduce/</a></p>\n<p>Amazon Redshift:</p>\n<p><a href=\"https://www.amazonaws.cn/redshift/\" target=\"_blank\">https://www.amazonaws.cn/redshift/</a></p>\n<h4><a id=\"_105\"></a><strong>特征的覆盖度问题</strong></h4>\n<p>特征的覆盖度(Category 特征和连续特征都有覆盖度的问题)尤其是训练集中的特征的覆盖度,最终会反映到模型对该特征能了解的程度。理想情况下,我们希望训练集中的每个样本都没有缺失值,并且训练集会把每个特征的所有可能的取值都能覆盖到并且每个取值出现的频次足够高并且频次有上限(为了样本公平性),这样模型学习的才够充分,之后对验证集以及线上数据做推理才更准确。</p>\n<p>现实中,每个特征总是或多或少会有覆盖度的问题。Category 特征的覆盖度问题更复杂和常见,因此我们这里主要讨论 Category 特征的覆盖度问题(连续特征通过特征缩放处理或者离散化可以把它的覆盖度问题缓解或者转移)。导致特征覆盖度问题的经常会有如下的3种情况:</p>\n<p>特征获取困难:在项目的过程中,经常有很多特征的获取是比较困难的,具体又分为2种情况:<br />\n<img src=\"https://dev-media.amazoncloud.cn/6d45a12097524617a2e0229f8be2d6c4_image.png\" alt=\"image.png\" /><br />\n对于样本粒度来说,需要逐个检查每个样本的缺失情况。对于某个样本,如果缺失的特征数量太多比如超过1半数量的特征都缺失,那么可以考虑是否可以把这个样本给去除。</p>\n<p>在一些客户的项目中,发现他们尝试通过其他模型来生成一些用户的隐私特征,并且把这些特征用在下游的模型中:比如男女性别,年龄段,是否有孩子等等这样的特征对于某些目标任务来说比较重要,但是这些特征很难从终端用户真实的获得。因此有的客户就通过规则/数据分析/机器学习的方式来根据该用户的行为来生成这些特征。</p>\n<p>本身这个生成的特征的正确性就没有办法保证,那么把这个生成的特征放入下游的模型中,对模型是有帮助还是有负作用是需要离线评估以及线上AB test 来评价的。</p>\n<p>非高基数id类特征的 category 特征(比如“国家”这样的特征)分布可能天然就不均衡:如果某些特征值的样本数很低比如少于10次,那么可以考虑特征向上合并或者把那些小类别统一归并为“Other”(所谓的特征向上合并,指的是可以重新规划该 category 的类别,把细类别合并为粗类别,从而改善特征的覆盖度)。</p>\n<p>这里有个例外,比如约会类 app,有的“城市”比如“合肥”的样本少,如果把这些小样本的城市都合并为一个 other 或特征向上合并,会违背了同城约会可能性更高这样的事实,这个时候可能就不要合并了。</p>\n<p>低频的高基数 id 类特征值被过滤:也就是把包含长尾 id 的整个样本从训练集中干掉了。对于搜推广三大领域来说,像 userid/deviceid/itemid 这样的特征是典型的高维稀疏特征,他们的长尾的 id 有很多。长尾的 id 常见的处理方式有如下三种:<img src=\"https://dev-media.amazoncloud.cn/92a5b45bf0c24a95b5995b20cf1d7d18_image.png\" alt=\"image.png\" /><br />\n由此可以看到,如果特征的覆盖度问题是因为低频的高基数id类特征被过滤后导致的,那么可以考虑特征的频次阈值是否可以根据业务特点来重新调整,或重新评估并权衡其他的长尾id的处理方法(可能评估完后会仍然使用低频特征被过滤的方案)。围绕这一块的特征处理,我们可以通过 <strong>SageMaker</strong> <strong>Processing</strong> 来完成,写好处理逻辑的脚本,调用一下 SageMaker Processing API 就可以了。</p>\n<p>另外一个相关的问题是,对于训练集中有的用户的样本很多,有的用户的样本很少,这样模型可能会被样本多的活跃用户所影响,如何缓解这样的问题?Youtube 电影推荐深度模型中采用的方法是为每个用户固定样本数量上限,尽量平等地对待每个用户,能明显提升线上效果。</p>\n<p>SageMaker Processing:</p>\n<p><a href=\"https://docs.aws.amazon.com/sagemaker/latest/dg/processing-job.html\" target=\"_blank\">https://docs.aws.amazon.com/sagemaker/latest/dg/processing-job.html</a></p>\n<h4><a id=\"_151\"></a><strong>样本和特征的正确性检查</strong></h4>\n<p>这个看似最简单的事情,但是确实是最容易忽略,也是经常出问题的地方。我见到的客户中,或多或少都会对样本和特征做一些检查,但是仍然检查力度太少。</p>\n<p>先不说对模型学习效果如何,就是出了问题 debug 也费劲(尤其是当出现奇怪的问题或者复杂的问题的时候),而且经常会前功尽弃(比如训练到几个小时因为样本有问题报错退出,尽管通过保存 checkpoint 可以尽量降低伤害程度,但是仍然会浪费感情),对成本带来无谓的消耗。因此,我建议至少做如下的正确性检查:<br />\n<img src=\"https://dev-media.amazoncloud.cn/4c42fa48a1a74a04bdf725a529d68fa1_image.png\" alt=\"image.png\" /><br />\nSageMaker Pipe mode:</p>\n<p><a href=\"https://docs.aws.amazon.com/sagemaker/latest/dg/model-access-training-data.html\" target=\"_blank\">https://docs.aws.amazon.com/sagemaker/latest/dg/model-access-training-data.html</a></p>\n<p>关于样本和特征的正确性检查,建议如下:每个公司对每个数据集都建立和维护一个 checklist;对样本和特征的这个卫生检查,建议不要放在训练脚本中去做,而是用一个单独的前置任务去做这个事情,不要浪费宝贵的训练资源(我们可以在整个 ML workflow 中用 SageMaker Processing 做样本和特征的卫生检查,然后用 SageMaker Training做模型训练,并且两者可以通过 SageMaker Pipeline 串起来,自动执行全部流程)。</p>\n<p>SageMaker Processing:</p>\n<p><a href=\"https://docs.aws.amazon.com/sagemaker/latest/dg/processing-job.html\" target=\"_blank\">https://docs.aws.amazon.com/sagemaker/latest/dg/processing-job.html</a></p>\n<p>SageMaker Training:</p>\n<p><a href=\"https://docs.aws.amazon.com/sagemaker/latest/dg/train-model.html\" target=\"_blank\">https://docs.aws.amazon.com/sagemaker/latest/dg/train-model.html</a><br />\nSageMaker Pipeline:</p>\n<p><a href=\"https://docs.aws.amazon.com/sagemaker/latest/dg/pipelines-sdk.html\" target=\"_blank\">https://docs.aws.amazon.com/sagemaker/latest/dg/pipelines-sdk.html</a></p>\n<h4><a id=\"_182\"></a><strong>总结</strong></h4>\n<p>线上和线下都应该尽可能对数据集的质量进行检查。线下的时候,这个检查并不只是发生在数据集清洗的开始阶段,其实只要对数据集进行了修改(比如在异常样本/特征的识别和处理后增加了新的交叉特征),那么都需要再做一遍质量检查的。</p>\n<p>Data-centric AI 之数据集的质量到此介绍完毕,本文详细介绍了数据集质量最重要和最常见的四个方面即异常样本以及异常特征的识别和处理,Label的正确性问题,特征的覆盖度问题,样本和特征的正确性检查。到此为止,整个 Data-centric AI 系统的讲解也结束了。</p>\n<p>整个系列文章比较完整的涵盖了 Data-centric AI 的三个核心即特征工程,样本工程和数据集质量的内容,相信大家对结构化数据建模有了整体的把握以及对数据更深刻的理解和洞察。只要你有高质量的数据,现在就可以尝试用一个简单模型来对小型的目标任务来建模了,再次感谢大家耐心的阅读。</p>\n<p><strong>本篇作者</strong></p>\n<p><strong>梁宇辉</strong></p>\n<p>亚马逊云科技</p>\n<p>机器学习产品技术专家<br />\n负责基于亚马逊云科技的机器学习方案的咨询与设计,专注于机器学习的推广与应用,深度参与了很多真实客户的机器学习项目的构建以及优化。对于深度学习模型分布式训练,推荐系统和计算广告等领域具有丰富经验。</p>\n"}