机器学习的坑

之前拜读过Xavier Amatriain 大神的“10 lessons learned from building ML systems”以及“10 more Lessons learned from building real-life Machine Learning System - Quora” 感受颇深,而且相当可以引起共鸣。因此,今天小编就结合从大神那里get到的精华和自己和队友一起踩过的坑和大家分享一下我们工作中遇到的问题,以及一些解决方法。希望能让刚入行不久的童鞋们避开我们曾经踩过的坑。

小编之前工作做的是电商推荐,现在是在做招聘推荐,包括求职方和招聘方的推荐。二者在业务上虽然差异很大,但万变不离其宗,无非就是数据,特征,模型以及效果评估这四个方面。今天小编也就从这四个方面和大家分享一下自己的经验和体会。数据部分会和大家分享一下常用的数据类型,异常数据对模型训练的负面影响以及如何避免,模型训练时正负样本不均衡的影响及其解决方案;特征部分会主要介绍一下特征选取的原则,以及一些基本的特征处理方法;模型主要想和大家分享的是多模型融合是趋势;最后的效果评估会介绍一下小编常用的三个离线评测指标以及模型debug. 其中有些例子可能会用到电商中的场景,有些会用到招聘推荐。

数据

显性数据&隐性数据

数据也许有很多不同的分发,“显性数据”和“隐形数据”是其中一种。所谓“显性数据”就是可以直观反映出用户喜好的数据,比如说电影评分,点赞,踩;而“隐性数据”就是那些不是很直观的反应用户喜好的数据,比如说电商用户的浏览,收藏,加购物车。而且有时候用户直接表达的喜好也许并非他真正的喜好,换言之“话可以骗人,但长期的行为骗不了人”表1列出了二者的差别。很明显,在实际应用中我们用到最多的还是隐性数据。

表1. 显性数据和隐性数据比较

Junk in Junk out

我们先来看看数据。我们是做大数据处理的,因此数据是我们的根本。引用一句统计业内非常流行的话“Junk in, Junk out”,如果你的输入数据是Junk,那你能期望的输出也只能是Junk。因此我们要时刻考虑异常数据对计算结果的影响。下面我举两个栗子:

电商的“打包购买”模块,也叫“拍档组合”,“最佳拍档”等,如图一所示。顾名思义就是适合和当前商品一起购买的其他商品。这个模块的推荐用到的是关联规则算法。“打包购买”用数学式子表达就是求的概率,其中Y表示当前商品,X表示适合一起买的其他商品,即如果用户要买商品Y,他有多大的概率买商品X。将候选商品集合按照从高到低排序取topN就是展示在用户面前的这个模块的结果。这个模块用到的数据就是用户的订单数据。而我们都知道电商中普遍存在“刷单”和“囤货”的行为”,这些“刷单”以及“囤货”的行为就属于我们订单数据中的“异常点”,如果不加以处理必然会影响推荐结果。

图1. 图书“拍档组合”模块

我们先讨论一下“刷单”的影响。通常理解的“刷单”就是刷销量,充其量会影响到热销排行榜推荐。但我们在分析数据中发现还有一种更高级的刷单方式,就是“刷搭配”,就是反复的和畅销书一起购买,这样不用像单纯的刷销量那样需要刷非常多单,也可以有很多机会出现在用户面前。他们会出现在畅销书的“打包购买”推荐模块里。比如出现畅销书A的订单总共有1000单,其中有100单里包含了作弊书B,50单里包含C书,35包含D书,那么P(B|A)的概率必然是最大的,因此会被放在推荐位的第一位。而这绝对不是我们期望的结果。

讨论完“刷单”,我们再讨论一下“囤货”的影响。电商的各种造节造就了一批又一批的剁手党,这些剁手党往往会提前把想买的商品提前放入购物车,可能有母婴,可能有男装,也可能有童书,或者是文学,社科什么的,然后等节日那一天一并下单。如果利用这些订单进行计算关联规则,会使得原本根本不“相关”的商品关联起来,这样也会影响我们的推荐结果

当然,这里的例子只是影响结果的两种类型,在不同的业务场景下也会有不同的影响模型计算的结果。比如说简历推荐中会有如图2中的“批量查看简历”,职位推荐中的“批量申请”等。这些批量处理的数据都会对模型学习产生影响。

那如何处理这种因数据造成的学习结果不尽人意呢。我们常用的有两种方法:一种是直接从数据本身下手,想办法去掉对结果产生不良影响的“异常点”。比如说去作弊订单,去除掉双11等大促订单;另一种方法是在计算的时候对“异常点”数据进行降权处理,将其对结果的影响尽可能的衰减。比如说在计算关联规则的时候,计算两两商品共同出现次数的时候,根据订单中包含商品的数量进行适当衰减。

图2:简历详情页“您的同行还查看了以下简历”模块

样本不均衡

正负样本不均衡的问题大家应该都不陌生。电商推荐中被点的商品总是远小于展现;招聘推荐中用户申请的职位也是众多职位中的一小部分,其他互联网应用也大多如此。这就造成的实际样本中正样本会远远小于负样本的个数。

而理想情况下,模型训练时我们期望正负样本比为1:1。 为什么这么说呢?我们举个极端的例子,假设正负样本比为1:99,如果模型的目标是尽可能的减少误判。如果各位就是那个“模型”,新来样本之后,你会怎么办呢?你是不是会无脑全部判成负样本呢?因为即使全部判成负样本,都可以保证99%的准确率! 而当正负样本比我1:1 的时候,模型就没办法“投机取巧”,只能“静下心”的去学习哪些特征可以激发点击,哪些特征无法勾起用户点击的欲望。

现实PK理想,那实际工作中我们该如何解决样本不均衡造成的问题呢?主要有两种方法,一种方法就是从代价函数入手。这里我用SVM的代价函数为例,我们可以对正负样本做不同程度的惩罚,对正样本惩罚小点,而对负样本却加大惩罚力度,如式1。这样就会让模型“知道”我们是“偏心”正样本的,进而会影响权重w的结果。

式1:从代价函数入手解决样本不均衡

考虑到实际工作中我们都会采用各种各样开源的工具,因此调整代价函数的可操作性相对较差,因此还有另外一种应用更多的方法,就是直接从样本入手,人工调整正负样本的比例,主要有降采样和过采样两种方法。降采样是针对样本多的那个类别,;而过采样是针对样本比较少的那个类别。因为小编经历的大多数情况都是负样本远远大于正样本,所以之后我都会用负样本降采样和正样本的过采样来介绍。但需要注意的是,对样本做了人工调整后,并不是没有代价的。下面我们具体分析一下两种采样方法可能付出的代价。

负样本降采样,顾名思义就是对负样本进行抽样。但需要注意的是,降采样也需要有度,如果要降采样到正负样本比为1:1就有点太夸张了。降采样可以采用随机抽样的方法,也可以根据业务特点,针对性根据一定的条件做降采样。降采样之后导致负样本丢失,可能会使得最后的模型和真是结果存在一定的偏差。如图3所示。因此我们需要在降采样导致的偏差和用原样本进行训练的不足之间进行权衡,选择对业务更有利的一方。

图3. 降采样对结果的影响

介绍完负样本的降采样,我们来一起看一下正样本过采样的方法以及可能导致的结果。过采样其实也可以称作“插值”,就是在现有正样本的基础上根据一定的原则再插入一些正样本。最简单粗暴的方法,就是将部分正样本复制多次,但也不是无理由的复制,一般都是会结合业务来进行复制。比如说招聘推荐中某个职位被点击了,而且用户还申请了,那么这种样本可以做适当加强。这样可能导致的问题如图4所示。因为某些正样本被加强了,因此模型会过分去拟合那些正样本,从而导致过拟合的问题。

图4. 正样本简单复制对训练结果的影响

另外一种相对高明的方法,就是插值出一些“伪正样本”,纯数字特征的话,可以考虑中值插值,最近邻点插值等方法。我遇到的情况一般是会根据业务进行插值,比如可以把和正样本相似度非常高的那些负样本强行变成正样本。这种方法也会产生如图5的问题。虽然也会偏离理想模型,但比之前单纯复制的过采样方法还是好很多,过拟合问题会相对缓解一些。

图5. 增加伪正样本对训练结果的影响

总结一下,实际的大部分应用样本都是不均衡的,而且可能不均衡的特别严重。在这种样本上训练模型多数情况下达不到我们预期的结果。因此很多时候我们需要对样本做一些抽样,但这样必然会导致偏差,毕竟抽样之后样本分布已经发生变化,和线上真实情况是不一致的。但只要抽样带来的好处远大于导致的误差,我们就还是可以进行样本抽样的。

特征

特征是模型训练中非常重要的环节,而特征的选取一般都是和业务高相关,特征选取的好坏直接影响模型预测的准确性。那么选取特征时有哪些原则呢?Xavier Amatriain 大神在他的分享中提到好的特征应该具有以下四个特质:

  1. 可复用,好的特征不应该是只用一次

  2. 可变换,灵活性要比较好

  3. 可解释,选取的特征得对业务有意义,否则只是噪声而已

  4. 可靠,方便监测和debug

除此之外,还需要注意的是特征组选取时应该尽可能独立,即使不能独立,也要低相关。

常用的特征有数字特征和文本特征两类。数字特征一般会涉及到去异常点,离散化,归一化等基本操作;而文本特征会涉及到分词,提取主题词等操作。模型训练时候可以直接采用原始特征,但很多情况下我们也会根据实际应用对特征做一些转化,我们也称之为“特征工程”。比如说生物信息应用中(小编读书时候做过生物信息学的研究),样本的特征通常是基因,而基因的数量级那就上了天了, 因此在生物信息学界经常会遇到“curse of dimension”,所以在此类应用中一般都会做降维处理,一方面达到降维的效果,另一方面也是提取出对模型更重要的,表达性更好的,相对独立性更好的特征组,比较常用的如PCA, LDA等。又或者在某些场景下原始特征太少,而导致线性不可分,这时候我们可能就需要做一些工作提高维度,使之在高维度下线性可分,比如说SVM中的核函数,它成功的将低维线性不可分的样本变换成高纬线性可分。亦或是在另一些应用下,原始特征的表达能力比较弱,这时候也需要特征变化提高特征的表达能力,比如深度学习在图像中的应用,将像素预处理得到边缘,然后再抽象为对象的组件,最后再进一步抽象为对象模型。实际应用中,大家可以根据具体的业务来进行具体选择。

在特征处理中还有一个不可忽视的内容就是适当的人工干预。适当的人工干预对模型训练结果的提升效果那是杠杠的!模型不懂业务,真正懂业务的是人。模型能做的只是根据代价函数和样本进行学习,找到符合当前样本的最优的拟合。因此机器学习工作者应该根据也许需求适当对特征进行一些人工干预和“指导”,比如说硬规则的摒弃一些噪音特征。如何判断是噪音,那就依赖对业务的理解了。小编之前做电商推荐的时候,就做过这样的事情。当时推荐效果遇到瓶颈,于是大家一横心就对商品标题,商家分类信息等的分词后结果,去掉低频词和太高频词,对剩余的词人工过滤了一遍,眼都看瞎了有木有!但过滤一遍之后,特征不但增多了,而且质量更好,模型的效果提升异常明显!

当然会有人说“特征多不怕啊,把它们丢给模型,然后让模型去训练找到好的特征”,这种想法小编认为too young too naïve!模型训练只是工具,它不是阿拉丁神灯,可以对你有求必应;它也不是牛,你给它草,它能给你牛奶。你需要给模型一个高质量的输入,它才能返还你一个完美的结果。

模型

模型是根据训练样本,目标函数以及评价指标这三个内容来进行学习的。模型的效果直接依赖三者的设计。不同的目标函数造就不同的机器学习算法。

说到模型,那就不得不提过拟合和欠拟合的问题了。所谓过拟合就是过分的去拟合训练样本而导致泛化能力太弱,等面对新的数据就会产生较大的偏差;而欠拟合就是模型表达能力太弱,根本没有很好的“描述”出样本。

图6. 欠拟合,完美拟合,过拟合示例

因此为了保证模型一方面可以完美拟合训练样本,一方面也不损失泛化能力,我们都需要做交叉验证,即一部分样本用来训练,另一部分用来测试。除此之外,我们一般还需要通过正则化来防止过拟合,常用的有L1正则,也叫Lasso; L2正则Ridge。 以最小二乘为例,带L1和L2正则化的代价函数如式2所示:

式2. 带L1正则和L2正则代价函数示例

也就是说,我们将模型空间限制在w的一个 norm ball中。为了方便理解,正则化这部分我就直接引用ref[3]中的解释, 我个人认为解释的非常好。假定我们只考虑二维的情况,在(w1, w2)平面上画出目标函数等高线,而约束条件则成为平面上半径为C的一个norm ball. 等高线与norm ball首次相交的地方就是最优解。可以看到,L1-ball 与L2-ball 的不同就在于L1在和每个坐标轴相交的地方都有“角”出现,而目标函数的测地线除非位置摆得非常好,大部分时候都会在角的地方相交。注意到在角的位置就会产生稀疏性,例如图中的相交点就有w1=0,而更高维的时候(想象一下三维的L1-ball 是什么样的?)除了角点以外,还有很多边的轮廓也是既有很大的概率成为第一次相交的地方,又会产生稀疏性。相比之下,L2-ball 就没有这样的性质,因为没有角,所以第一次相交的地方出现在具有稀疏性的位置的概率就变得非常小了。这就从直观上来解释了为什么L1-regularization 能产生稀疏性,而L2-regularization 不行的原因了。

图6. L1正则和L2正则图示

因此,一句话总结就是:L1会趋向于产生少量的特征,而其他的特征都是0,而L2会选择更多的特征,这些特征都会接近于0。Lasso在特征选择时候非常有用,而Ridge就只是一种规则化而已。

关于模型,还需要说的就是多模型融合。“Everything is an ensemble”,“三个臭皮匠顶个诸葛亮”,综合不同算法的优势,扬长避短,集成一个牛掰的super model. 很多互联网公司在单一模型遇到瓶颈之后,大多都会采用模型融合,比较流行的是GBDT+LR。从根本上说多模型的融合,实质上是一个模型的输出作为另一个模型的输入,第一个模型充当特征转换的角色。

效果评估

训练出模型后一般都需要对模型做效果评估。除了离线评测指标之外,还需要一个debug工具来真实模拟线上环境,并且可以将模型结果可视化。

小编常用的离线评测指标有AUC, 校准(Calibration), 归一化熵(Normalized Entropy, NE)。 表2中列出三个评测指标的具体计算方式。AUC大家都很熟悉,这边就不多说了。Calibration计算的是实际的点击和预测点击的比值,这个值越接近1,说明预测越准确。Calibration其实是对AUC的一种补充,因为AUC在意的只是排序,而不关心具体预测值。NE的分子部分其实是交叉熵,也是LR的代价函数。(y是样本label, 取1 或者-1; pi 为样本i的点击预测概率);分母部分是原样本的信息熵(p为正样本的概率,或者准确的说是频率),即原始样本的不确定性。所以NE反应的是在模型的帮助下,样本剩余的不确定性和没有模型时候样本的不确定性的比值。那么, 1-NE其实就是相对信息增益,也即模型帮助我们消除的样本的不确定性。再通俗点讲就是当我们没有模型帮助的时候,样本正负的不确定性会大,我们不是很容易判断样本正负;但有了模型帮助之后,我们会得到一个预测的点击率,在这个帮助下我们就可以更容易的去判断样本正负,这时候不确定性就下降了。换言之模型是给我们带来了更多的信息。这也是模型训练的主要目的。那为什么要用三种离线测试指标呢?小编最开始也是只用AUC,但后来我们发现AUC即使结果很好,上线后也可能不尽人意。因此多增加两个评测指标,多指标一起评测,更可靠。一定程度上可以保证上线后的效果。

表2. 三种评测指标计算方法

除了指标评测外,我们还需要模拟线上环境,人工的观察模型效果。比如说看看用新模型排序后的推荐职位是否比现有的好;排在第一位的简历都有哪些特征;每个特征的权重是多少;是哪些特征导致它排在第一位;这些特征的权重是不是合理;是有多少训练样本中含有这些特征;是不是样本太少而导致权重不合理等等。我们需要对模型的结果有全面清晰的认识,这样也方便我们对症下药的对模型训练做出一些调整。不能盲目的信赖模型训练的结果。

总结一下:实际应用中隐性数据使用得更多;数据处理时要特别注意异常数据的清理;适当的样本采样(过采样或者降采样)可以调整正负样本比,有利于算法训练出真正有意义的模型;当单一模型性能遇到瓶颈的时候,考虑多模型融合;多指标评测让我们对模型更有信心,线下模拟线上情况很有必要。

以上就是小编和自己的队友们共同遇到过的一些问题,以及相应的解决方法。知识有限,有不对的地方欢迎大家指出,一起讨论一下。小编联系方式:

risingsun123@163.com

Reference

[1]10 lessons learned from building ML system – Netflix, Xavier Amatriain

[2] 10 more Lessonslearned from building real-life Machine Learning System – Quora, XavierAmatriain

[3] blog.csdn.net/zouxy09

[4] Practical Lessonsfrom Predicting Clicks on Ads at Facebook - Facebook

谢谢阅读~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值