基于spark训练点击率预估模型
综述
本篇文章是《讯飞AI营销平台算法实践》系列的第二篇,在上一篇的《讯飞AI营销平台广告点击率预估架构》中,我们介绍了广告点击率预估的架构,在本篇中我们将介绍如何基于spark平台训练一个基础的点击率预估模型。
Spark平台能够处理大数据集,同时其自带的MLlib提供了丰富的机器学习模型,基于spark平台我们可以搭建从数据预处理到特征生成,再到模型训练和评估的整套点击率预估系统。
讯飞AI营销平台的数据来源主要是两部分:ADX(AD Exchange,广告交易平台)和DMP(Data Management Platform, 数据管理平台)平台,从ADX的广告请求中可以获取到广告的展现点击数据,作为点击率预估模型的训练label,此外还能获取媒体和广告位相关的数据作为模型的特征;从DMP可以获取到用户的相关数据。
我们的训练流程分为四步:
- 根据从AD Exchange和DMP获取数据,构建特征工程
- 根据广告的展现和点击,构建训练样本
- 使用spark的MLlib进行模型训练
- 对模型进行评估
特征工程
特征的构建是CTR模型训练最核心的工作,特征抽取的好坏直接决定模型的最终效果。从数据中能够构建的基础特征分为两部分,一部分是用户特征,一部分是广告特征。在用户和广告两类基础特征之上,可以构建交叉特征、反馈特征,此外还可能用到场景特征,下面分别介绍这几类特征。
用户特征
用户的特征有很多,大部分的用户标签都是从DMP平台直接获取的,主要包括用户的自然属性、兴趣属性、地理位置和点击偏好等,具体的用户特征见下表。
特征种类 | 特征举例 | 来源 |
---|---|---|
自然属性 | 年龄、性别、收入 | DMP平台 |
兴趣属性 | 汽车、房产、购物 | DMP平台 |
地理属性 | 省、市、国家、是否一线城市 | DMP平台 |
点击偏好 | 偏爱点击视频类广告 | 从日志计算 |
广告特征
广告特征包括流量特征、广告位特征和广告创意特征等,广告特征的刻画一般会在广告投放之前进行填充,由于广告的数量有限,广告特征可以在编辑广告创意的时候人工进行记录,具体的广告特征见下表。
特征种类 | 特征举例 | 来源 |
---|---|---|
流量特征 | 视频流量、媒体名 | ADX |
广告位特征 | 尺寸、位置,长、宽 | ADX |
广告特征 | 广告行业、广告标签 | 人工编辑 |
广告创意特征 | 创意类型、文本、图片 | 人工编辑 |
场景特征
一般CTR模型还会加入场景特征,但是单独场景特征对CTR训练没有意义,场景特征主要通过和其他特征进行组合发挥作用,例如用户白天更喜欢点汽车类广告、非wifi流量下用户不喜欢点击视频广告,可见在使用场景特征时,需要与广告特征进行交叉,主要的场景特征见下表。
特征种类 | 特征举例 | 来源 |
---|---|---|
网络特征 | 3G、4G、WIFI | ADX |
时间 | 白天晚上、星期、是否休息日 | 直接获取 |
手机平台 | Android、IOS、华为 | ADX |
样本构建
根据广告的展示点击,我们构建训练样本,每天样本规模在5000W量级,上一篇文章中已经介绍过,为了更好的拟合长尾流量和提高模型的时效性,我们最终选择的是FM和FTRL模型,对于不同的模型样本构建方式有所区别。
- FM模型:采用历史7天的数据作为基础全量模型
- FTRL算法:采用历史1小时的数据作为增量数据
特征选择
在构建样本时,我们还会对特征进行选择,原因是特征工程中并非所有的特征都是有用的,无用的特征会增加训练时间,还会影响模型的效果。我们使用下图的方式进行特征选择。对于所有的特征,我们统计该特征的点击分布,根据统计的特征值点击分布的均值与方差,对于点击方差过小的特征进行剔除。
然后我们把转换成libsvm格式,取历史行为轨迹数据点击作为正样本1,展示且未点击作为负样本0,再对特征数据采用one-hot编码,就生成了可用于模型训练的样本,生成的样本如图所示。
模型训练
模型训练使用的是FM和FTRL模型,模型更新架构和FM的原理在上一篇文章中已经进行了介绍,在本文中重点介绍如何基于spark实现模型训练。
FM
FM用于模型的天级别更新,它的优点是支持高维one-hot、能够进行自动的特征组合,并且训练速度很快,spark的MLlib中没有现成的FM实现,我们首先定义了FM的目标函数,然后用MLlib自带的LBFGS方法进行FM的求解,基于spark实现FM模型,调用LBFGS方法训练FM模型的示例如下:
def train(input: RDD[LabeledPoint],
task: Int,
//迭代次数
numIterations: Int,
//LBFGS的修正值
numCorrections: Int,
//特征维度
dim: (Boolean, Boolean, Int),
//正则化项参数
regParam: (Double, Double, Double),
//采样率
parts: Double,
//初始化标准差
initStd: Double): FMModel = {
new FMWithLBFGS(task, numIterations, numCorrections, dim, regParam)
.setInitStd(initStd)
.setParts(parts)
.run(input)
}
FTRL
FTL思想是每次找到让之前所有损失函数之和最小的参数,它能够有效的产生稀疏解,它的推导比较复杂,这里不再详细介绍算法原理,想详细了解算法原理的同学可以阅读google的论文《Ad Click Prediction: a View from the Trenches》。
在实际使用时,我们只要按照下图中的公式进行模型参数的更新,其中gi是损失函数fi(wi)的次梯度,
再用更新后的参数按照如下公式计算模型的参数w即可。
可以看出,FTRL对于每一条样本数据,都会进行一次计算,作出模型w参数更新修正,基于spark实现FTRL的训练分为两步:第一步生成用于更新的样本,第二步用FTRL的公式更新参数,spark的代码实现示例如下:
//生成用于更新的样本
val dataCollect = trainData.mapValues { features =>
val indices = features.map(feat =>
featMapBCNew.value.getOrElse(feat, 0) - 1)
.filter(_ >= 0).mkString(" ")
indices
}.collect()
//用FTRL的更新公式,更新参数
dataCollect.foreach {
case (click, str) =>
val indices = str.split(" ").map(_.toInt)
val vec = Vectors.sparse(numFeatures, indices, Array.fill(indices.length)(1.0))
fmftrl.update(click.toDouble, vec)
}
模型评估
模型评估主要使用的指标是AUC和logloss,AUC越高,logloss越小,则表示模型越好,由于FTRL模型每小时进行更新,我们离线评估时,一般在FTRL模型更新后,用下一个小时的数据来计算AUC和logloss,下图是FTRL模型24小时的AUC和logloss变化,可以看到模型的指标有一些波动,且AUC越高时,logloss越小。
总结
目前网上对于点击率预估的技术介绍主要分为两类,第一类是阿里、美团等大厂基于内部的系统进行的大规模数据训练,另一类是基于python的点击率预估比赛经验分享。对于从无到有搭建上亿数据规模的点击率预估系统的介绍目前比较少。
本文介绍了如何基于spark用上亿数据训练一个基础的点击率预估模型,但是这个模型在线上使用时会存在效果波动大、预估点击率和实际存在偏差等问题。在《讯飞AI营销平台算法实践》系列的下一篇文章中,我们将介绍如何根据业务需要,对这个最基础的点击率预估模型进行优化。