part2背景:众所周知,数据是最终效果的天花板,而不同model在同一份数据上只不过是代表了不同逼近天花板的程度,有鉴于此,本小节也分两大块展开,将重点带给大家样本,特征的一些实战知识技巧以及youtube dnn model一些重要参数设置与注意事项。
一。图1是训练数据以及测试数据获取的整体流程,我一直以为在不同的业务线想要把model训练好,首先要了解业务场景,其次要了解原始log以及一些关键信息的存储获取方式。只有这样才能让数据为自己所用,才能比较随心的使用各种样本处理技巧,特征处理技巧。整体流程上输入源分为三大块feed 点展日志,小时级别存储在hdfs,user profile日志天级别存储在hdfs,格式是pb,item info存储与hbase。整体步骤主要经过了样本筛选,用户侧特征筛选与转换,item侧特征筛选与格式化,label筛选,以及user 侧或者是label侧的样本均衡【我都试验过后根据试验效果保留了裁剪版本的label均衡】,之后将得到的instance分成两部分train与test data。供每天的model train与model test使用。下面将每一部分拆开具体讲解一下。
样本选择:无论是recall model还是rank model的模型构建过程中,样本选择都是非常重要的,我这里主要是只筛选出了近3天的feed流下用户的真实点击短视频数据,不需要用户的展现,不需要用户的被动点击(watch time < thr以及一些产品形式下的自动播放),不需要图文的点击。重点是得到这部分用户。根据这些用户的历史点击的item,只要这些item不过期每个item都会产出一条样本。举个例子,用户的点击是1,2,3,4,5,6,7.那么根据1 我们能产出一条训练数据,只不过这个时候在历史点击特征下是2,3,4.还可以产出一条label是2 的训练数据,历史点击这一维度的特征是3,4,5.您可以根据自己的情况改变长度。这是我自己产出样本的一个方法,我猜youtube 也是这么产出的。
特征筛选:得到了哪部分用户是我们是需要构建训练数据需要的之后,我们开始进行特征的组织,先说一下重点,也就是用户侧特征的组织,根据原论文(part1 的引用1)的推荐,像用户的点击历史,用户的搜索历史,用户的一些基础信息的profile,比如年龄,性别等等这些之外,用户的地理信息,城市,省份等等,我自己又新加了一些新的特征,像字符串类型的用户的星座,数字类型的比如观看过多少视频,观看总时长等等。数字类型的特征一定要尽量作细统计分布之后的归一化处理在我个人多个模型的实战之中都起到非常重要的作用。如果您看了这篇文章,也在做您自己的model,没必要完全按我提到的上述特征,因为特征的抽取需要符合自己的产品,以及自己的产品的数据建设,没有规定的选择方式,不要拘泥于别人的形式,在覆盖率准确率都能保证的情况下,可以大胆的使用,尤其是深度模型里面对string的极大包容(hash之后的embeding)给了我们更宽广的处理空间,当然用户侧还有一些特征也是我们这里同学画像做的比如用户喜欢的item category等等标签,有就用。没有也没关系。item侧特征的组织在这里只有一个就是item score,相当于是click time与item产出时间的一个delta time的衰减得分。关于特征筛选最后说一句,我看过很多数据挖掘,特征筛选处理的文章与书,但是这些不足以让你成为一个好的构建model的工程师,一定要有自己对于业务的理解,数据的判断,最重要的加上大量的实践。
label筛选与编号:label 编号大家可以理解,以为你写itemid当label机器是识别不了的必须要转换成数字比如0,1,2...然后记录好这个对应关系。这样导出item侧特征的时候,能对应好itemid 与itemvector,如果这个对应关系错乱了,那么就后果不堪设想。为什么这里还有label筛选,这也和我们自己的产品形态有关系,也许您的产品就不需要,因为我们这里每天进入展现索引的不是历史上的全量itemid,是筛选了一部分,加上淘汰一些脏乱差和过期等等。这么说吧相当于每天早晨重新建一遍索引写一下搜索引擎,您可以理解成ES,当然我们用的不是es,用的是自有研发的一套。这样很多用户历史点击序列的里的item已经过期了也就不用在根据这些item去产出无用的样本。
样本均衡:样本均衡在大规模的分类问题上是极其有必要的,避免样本的不均衡造成model学习的不充分。样本均衡的方式方法两种:一,改变model里对不同label的权重,例如加一些词典来控制。二:改变样本的分布。第二种相对来说灵活可以试验多种方案,随意改变,落地成本低。所以我在实战中采用了第二种方法,分别尝试了对用户以及label做均衡。具体就是统计一下一共有多少个label或者user,限定一个具体num 让 label数目*num = fix_train_data 数目,这个fix train data数目是你自己理想的训练数目,因为说过这个model得在gpu训练特别的样本数量的话会慢。根据限定的具体的num数目,label多于这个数目的就随机裁剪掉,低于这个数目的就补充到这个数目。最后试验中发现对label做均衡效果好一些。我自己采用了label均衡。
好了,关于训练样本产出方面想要说的差不多说完了。来看model参数方面。
二:训练中model 参数的几点说明:
其实文本类 nn model在训练过程中所选择的参数也就那么一些个,常训练的话大差不差都会有感觉,但是我下面想说的几个综合反映一个思想就是不要迷信别人是怎么做的要有自己的思路。
激活函数:我在看paper[part1 引用1]时候paper使用的激活函数是relu,所以我在trainmodel 开始的几天里一直坚定不移的使用relu,但是搭起tf serving,用脚本发请求发现大量user embedding输出为0向量,观察tensorboard发现在最后一个隐层上0激活值占比0.9+,那就没法玩了,因为这个我调整了很多地方,都没能解决,因为关于这个youtube dnn落地文章在网上不仅仅是少,几乎没看到,网上的大多在翻译论文,没啥实战参考价值。最后调整了一下激活函数为sigmod好了。relu函数确实比sigmod在梯度弥散方面要表现的好。但是这里我猜wx+b好多负数值,所以不能选relu。
负采样函数:因为这里的负采样函数是两层采样,根据paper[part1,引用2]文章所说,第一层采用数目在总label数目的%1-%10为合适,亲测有效果,关键是第二层采样数目,试过为第一层的二分之一,四分之一,。。等等多轮尝试,发现效果不如第二层数目和第一层数目几乎一样好。这个效果是一看tensor board,交叉熵损失函数收敛曲线。二看,训练完model 搭起tf serving,随意抽取n个用户进行向量召回topkl的结果的重合度。重合度越小越好。
该model的离线效果分析也是分为两部分1.model在测试集上的top50预测准确率长期稳定在0.7-0.8之间。在百万级别的分类问题上,这个数字相当可以。2.model在随机抽取10个用户,top100向量召回的结果总itemid,长期稳定在990+,极少重合。有了离线的结果分析,也给在线尝试带来了一些信心,但是差点遭遇职业生涯的第一次惨败,预知详细故事以及最后如何转败为胜的。请看下回分解。
好了第二部分的内容也基本介绍完了。下面进行第三部分的介绍。online 部分的应用与收益分析。
原创文章如需转载注明出处。