标签:在大数据机器学习特征工程11年的那段时间我刚加入百度,在凤巢通过机器学习对广告点击进行预测。当时我还十分惊讶于过去两年内训练数据如此疯狂的增长。大家都在热情的谈特征,每次新特征的加入都能立即得到AUC的提升和收入的增长。大家坚信特征才是王道,相信还会有源源不断的特征加入,数据规模还会成倍的增长。我也深受感染,坚定的相信未来两年数据至少还会长十倍,因此一切的工作都围绕这个假设进行。现在两年过去了,回过头来看,当时的预测是正确的吗?
数据的飞速增长,给模型训练带来极大压力。事实上,11年的时候模型训练已经是新特征上线的主要障碍了。凭着年轻的冲动,和对分布式系统和数值算法优化的一点点知识,我头脑一热就开始设计下一代模型训练系统了。目标是在同样的资源下,能容纳当前十倍的数据。项目是在情人节立项,取了一个好玩的名字,叫darlin【吐槽1】,这个系统应该是百度使用率最高的机器学习训练系统之一了。一个重要问题是,它会像前任一样在两年后成为性能瓶颈吗?
目前看来,以上两个问题的答案都是否定的。
【吐槽1】意思是distributed algorithm for linear problems。更好玩的是,计算核心模块叫heart,络通讯模块叫telesthesia。数据是用类似bigtable的格式,叫cake,因为切起来很像蛋糕。开发的时候开玩笑说,以后上线了就会时不时听人说“darlin”,是 不是会很有意思?可惜全流量上线后我就直奔CMU了,没享受到这个乐趣:)
我们首先讨论特征。特征是机器学习系统的原材料,对最终模型的影响是毋庸置疑的。如果数据被很好的表达成了特征,通常线性模型就能达到满意的精度。一个使用机器学习的典型过程是:提出问题并收集数据,理解问题和分析数据继而提出抽取特征方案,使用机器学习建模得到预测模型。第二步是特征工程,如果主要是人来完成的话,我们称之为人工特征工程(human feature engineering)。举个例子,假设要做一个垃圾邮件的过滤系统,我们先收集大量用户邮件和对应的标记,通过观察数据我们合理认为,标题和正文含有“交友“、”发票“、”免费促销“等关键词的很可能是垃圾邮件。于是我们构造bag-of-word特征。继而使用线性logisitic regression来训练得到模型,最终把模型判断成是垃圾邮件的概率大于某个值的邮件过滤掉。
就这样搞定啦?没有。特征工程是一个长期的过程。为了提升特征质量,需要不断的提出新特征。例如,通过分析bad case,不久我们便发现,如果邮件样式杂乱含有大量颜色文字和图片,大概率是垃圾邮件。于是我们加入一个样式特征。又通过头脑风暴,我们认为如果一个长期使用中文的人收到俄语的邮件,那估计收到的不是正常邮件,可以直接过滤掉。于是又加入字符编码这一新特征。再通过苦苦搜寻或买或央求,我们得到一个数据库包含了大量不安全ip和发信地址,于是可以加入不安全来源这一新特征。通过不断的优化特征,系统的准确性和覆盖性不断的提高,这又驱使我们继续追求新特征。
由此可以看出,特征工程建立在不断的深入理解问题和获取额外的数据源上。但问题是,通常根据数据人能抽象出来的特征总类很有限。例如,广告点击预测,这个被广告投放公司做得最透彻的问题,目前能抽象出来的特征完全可以写在一张幻灯片里。好理解的、方便拿来用的、干净的数据源也不会很多,对于广告无外乎是广告本身信息(标题、正文、样式),广告主信息(行业、地理位置、声望),和用户信息(性别、年龄、收入等个人信息,cookie、session等点击信息)。KDD CUP2013腾讯提供了广告点击预测的数据,就包含了其中很多。所以最终能得到的特征类数上限也就是数百。另外一个例子是,google使用的数据集里每个样本含有的特征数平均不超过100,可以推断他们的特征类数最多也只是数百。
图1
因此,新数据源和新特征的获得会越来越难。然而,模型的精度并不是随着特征的增长而线性提高。很多情况是指数。随着人工特征工程的深入,投入的人力和时间越来越长,得到的新特征对系统的提升却越来越少。最终,系统性能看上去似乎是停止增长了。Robin曾问过我老大一个问题:“机器学习还能持续为百度带来收益吗?” 但时候我的第一反应是,这个商人!现在想一想,Robin其实挺高瞻远瞩。
另外一个例子是IBM的Watson。从下图中可以看出,虽然每次性能的提升基本都是靠引入了新数据和新特征,但提升幅度是越来越小,也越来越艰难。
图2
这解释了第一个问题,为什么特征数量的涨幅比当初预计的要少很多。一个特征团队,5个经验丰富的大哥加上10个动手强的小弟,几个月就能把可能的特征发掘得差不多,然后再用1、2年把特征全部做进系统。再然后呢?就会被发现有点后续无力了,进入中年稳定期了。
接下来讨论模型训练,因为不想被跨国追捕所以主要用google sibyl?来举例子。Sibyl是一个线性分类器,支持多种常见loss,例如logistc loss,square loss,hingle loss。还可以使用l2罚,或者l1罚来得到稀疏模型。Sibyl每天要被运行数百次,被广泛应用在google的搜索,gmail,youtube等应用上。由于这些应用直接关系到用户体验和收入,通常需要得到收敛精度很高而且收敛点稳定的模型。因为一个有着数百亿项的模型,如果收敛不够,即使只是少数特征上权重计算误差过大,也很容易引起bad case。同时,应用也希望模型的输出在一段时间是稳定的。
Sibyl使用parallel boosting,而darin用了一个更生僻的算法。后来听说了linkedin,yahoo,facebook的算法之后,狠下心survey了一些古老的优化论文,发现虽然大家名字各不相同,但其实都等价的【吐槽2】。在合适算法下,收敛到所要求的精度通常只需要数十论迭代。而且随着数据量的增大迭代数还会进一步降低。更多的,在online/incremental的情况下,还能更进一步大幅减少。