本文作者:雪论、子兼
1 业务背景
超级风暴是一款多APP开屏联投的CPM定价保量广告产品,适合精准投放、品效联动等营销场景。资源视角,超级风暴整合了天猫、优酷、高德、UC等阿里生态开屏矩阵,覆盖范围广。媒体视角,开屏是APP的第一视角,具有稀缺性和曝光高的特点。广告主视角,超级风暴通过合约保量形式售卖,保障广告主的营销节奏、提高广告展示机会在数量和成本上的确定性。用户视角,超级风暴设有较高起投门槛,以品牌大客户为主,创意质量较高。
图1 业务背景
2 技术挑战
如图2所示,从请求引擎逻辑划分,超级风暴包括实时媒体和非实时媒体两类资源。对于实时媒体,用户唤起app时,则实时请求引擎,如果无缓存则不出广告,如果有缓存则引擎决策出哪一个;对于非实时媒体,用户唤起app时,则走端上逻辑,无缓存则不出广告,有缓存则直接曝光。这两类资源也存在相同点,即唤起10s后进行预加载请求,进而刷新缓存。
图2 开屏广告请求曝光逻辑
不难发现,开屏广告的关键在于预加载,叠加合约保量售卖形式,主要有以下两点技术挑战:
精准首唤:主要针对历史n(目前n=2)天有访问、当天首次访问app的情形。用户在第t天首次唤起,库存视角,是否有广告展现取决于有无历史预加载;效果视角,引擎会从缓存的广告中二次决策展现,因此历史预加载质量也很重要。
延迟曝光:主要针对历史n(目前n=2)天无访问、当天多次访问app的情形。预加载之后的二次请求才会带来真实曝光,同时非实时媒体在有缓存的情况下会直接曝光,不走引擎结算逻辑,对保量(包括缺量和超投)存在较大挑战。
3 优化路径
对于合约保量广告的投放分配问题,组内已经积累较多成熟算法,结合开屏预加载的特性,本文主要介绍三块工作,前两块解决「精准首唤」的问题,最后一块解决「延迟曝光」的问题。具体来说,工作1首先通过引擎改造将t+1/2预推与当天预推解耦,再通过PID场景适配提升首唤效果;工作2是对工作1的进一步优化,主要工作在于用模型预估请求分布代替规则统计曝光分布;工作3介绍通过防超投机制,解决在合约保量场景下延迟曝光带来的超投问题。
图3 预加载优化路径
3.1 区分日期的预加载pacing优化
解决精准首唤问题首先要区分t+1/2预推和当天预推情况。由于原开屏广告基本复用优酷贴片的引擎投放逻辑,因此要先对引擎进行改造。完成引擎改造之后,理论上分配、调控模块都具有一定优化空间,考虑到日志回流时间和业务优先级干预,则选择对t+1/2 pacing模块进行优化。
3.1.1 引擎链路改造
图4黑色字体部分是原引擎链路。对于开屏预加载请求,引擎会召回未来3天可投放的排期(含当天),结算对当天预推进行过滤、引擎对未来两天预推进行控量,OAP内部进行分配、排序,然后再交给引擎进行优先级排序、截断。显然,这样存在一个较大的问题,即OAP内部未使用到日期信息,对分配、调控模块保效影响较大。因此进行图4中红色字体部分改造,关键在于将key从ad改为ad+date,预推tt日志落盘是为了收集t+1/2预推实时完成量。
图4 引擎链路
3.1.2 PID场景适配
t+1/2预加载的优化目标是保证预推量的前提下提升预推效果,是一个单约束最优化问题,可以通过PrimalDual、Shale及其衍生算法建模x,这里不再赘述。在品牌合约广告场景下,通过线上实验观测,在库存售卖相对充足的情况下,Learning2Pace算法相对PrimalDual在完成率指标上更优,因此t+1/2预加载通过Learning2Pace进行建模,近线侧通过PID进行调控。
PID迭代如上公式所示,其中表示广告计划在第个时间片的目标预推量,则是实际预推量。结合t+1/2预推的实际情况,对PID进行了4点改进:
计算:使用比例替代绝对值,更易于收敛
初始阈值:由于目前预推日志是15min粒度,所以一天共有96个时间片,第一个时间片的阈值通过历史模型打分分布乘以分布占比得到,减少初期调整震荡
阈值调整步长:使用加法而非乘法,使得调控更加稳定
阈值上下界:Learning2Pace模型会综合考虑保量和效果,输出score值域在。同时,考虑到不同排期存在一定差异性,所以维护一张排期粒度最近24小时模型打分上下界表,压缩调控空间
3.1.3 效果评估
首先对Pacing调控策略进行评估。PID、线性插值等只是调控手段,目标是让实际曝光分布接近给定曝光分布,通过下面公式计算,优化后的PID调控曝光分布误差下降21%(1.51 -> 1.18)
然后对过滤请求流量进行分析。得益于OAP可以记录完整请求日志,包括过滤及未过滤的,从图5可以看出,未过滤流量预估效果(pctr为模型打分,xij为Learning2Pace输出)明显好于过滤流量。
图5 OAP请求日志
最后是线上效果观测。因为预推部分没有严格的预算分桶,设计两种评估口径:一是直接对比有无预推情况下多天的ctr,二是对比预推曝光部分的ctr提升乘以预推曝光占比。t+1/2预推线上分别观测8天,在无缺量&对两种口径提升取min的情况下,ctr分别取得7%、2.05%的相对提升。
3.2 基于预估请求分布的pacing优化
工作二是对工作一的深入优化,进一步解决精准首唤问题。无论是PID、线性插值还是RL等model based的pacing策略都是给定曝光分布寻找最优阈值,理论上当曝光分布与请求分布一致时pacing优化空间更大。数据分析发现,不同计划的请求分布存在较大差异,仅通过曝光数据+规则得到整体分布存在较大误差。同时,t+1/2预推pacing时间片是15分钟、无时间片/小时粒度结算控量,为通过模型预估请求分布带来可能性。
3.2.1 样本设计
与传统ctr预估、流量预估不同的是,计划粒度请求分布预估模型关键在于分布预估,即更加关注分布而不是单个值。图6展现进行分布预估的两种样本设计方式:6a)是固定分布预估,天粒度预估模型,样本量是计划数×时间片数,对天预估结果进行归一化;6b)是滚动分布预估,时间片粒度预估模型,样本量是计划数×时间片数×时间片数,对当前时间片预估结果进行归一化;实际建模时选择的是后者,因为6b)可以使用当天实时特征、线上使用取最大分区即可提升鲁棒性。同时,6b)只选择第一个时间片则会退化为6a)。
图6 请求分布预估 - 样本设计
3.2.2 特征设计
按照图6b)设计样本,样本的key是「logdate、ad_id、cur_time_id、pred_time_id」,因此特征设计主要从计划所在时空信息思考。计划视角包括在投计划和冷启计划;时间视角包括历史信息和当天信息(注意当天信息要小于cur_time_id,不能穿越),空间视角包括层次结构和微观人群信息。
图7 请求分布预估 - 特征设计
3.2.3 模型设计
GateDNN:如特征设计,dense特征主要包括当天特征、历史特征,id特征主要包括空间id、时间id;初版deep模型的结构如下公式所示,主要思考在于不同时间、空间id对应dense特征有不同贡献。
分布约束辅助loss:每一个当前时间片cur_time_id都会预测当天全部pred_time_id(96个)的请求分布,一天的请求分布固定为1,除了通过后处理归一化,也可以将它设计到辅助loss中。这里需要注意的是,为了保证ad_id、cur_time_id对应的全部pred_time_id都在一个batch内,可先将原始样本聚合,在计算loss时展开。
3.2.4 效果评估
离线侧,对请求分布预估模型进行评测。因为最终目标是提升ctr,pv较大的排期对ctr有更大的贡献,所以使用weight-mape指标进行评测。图8展示的是最近一个月的离线评测数据,v1是简单规则,使用计划×时间片历史分布,如果是冷启计划,则退化使用广告主、行业等粒度历史分布;v2是固定分布预估样本,只能使用历史特征,简单gbdt模型,相对v1在weight-mape指标上下降17.8%;v3样本升级为滚动分布预估,引入当天特征,同样是gbdt模型,相对v2在weight-mape可进一步下降29.1%;v4则是将gbdt升级为GateDNN,相对v3在weight-mape可进一步下降10.3%
图8 请求分布预估 - 模型评测
在线侧,对ctr效果进行评估。与3.1.3采用相同的评估方式,在线实验8天,ctr取得2.98%的提升。
3.3 延迟曝光优化
由于预加载之后的二次请求才会带来真实曝光,所有存在延迟曝光的现象。在合约曝光广告场景下,延迟曝光存在最大的问题就是超投,即实际曝光量大于预定量。通过潜在曝光预估+已观测曝光进行pacing调控,进而解决超投问题,这对模型预估精度和调控时效性存在一定要求。下面介绍在超级风暴场景下,如何通过机制防"超投"。
3.3.1 防"超投"机制设计
如图2所描述,共有2类请求会走到引擎,分别是预加载请求(包括实时和非实时媒体)和实时媒体曝光请求。如图9所示针对这两种请求有3道防超投机制,通过5min/小时/天曝光到量控预加载请求,通过天曝光到量控曝光请求,通过pacing阈值过滤进一步防止单点脉冲超投。同时,结算侧曝光统计包括非实时媒体曝光(不走引擎),叠加5min粒度预推控量,非实时媒体超投也能得到很好的解决。
图9 防超投机制
3.3.2 效果评估
在FY22双11,开屏库存基本售罄,统计发现超投流量占比不到1%(主要是小排期),充分说明以上机制可以较好地解决超投问题,进而充分利用库存。
4 总结
超级风暴是一款依托开屏资源的广告产品,预加载是其技术实现上的关键特性。通过合约保量的形式售卖,存在精准首唤、延迟曝光两大技术挑战。对于精准首唤问题,可以通过区分日期的预加载pacing解决,通过预估请求分布替代规则统计分布可进一步提升效果;对于延迟曝光,关键是超投问题,通过结算/算法机制可以得到较好的解决;通过上述工作,开屏预加载项目累积ctr相对提升超过+12%
5 后记
在预加载优化过程中,我们做了较多的数据分析、理论验证工作,虽然这些工作不能直接提效,却是预加载 or pacing中绕不开的问题,特此记录
5.1 结算控量对pacing的影响
目前pacing策略调控周期为5分钟,虽然结算回流的10分钟粒度日志曝光相对平滑,但是如图10所示,当以更细的1分钟粒度统计当天预加载请求的分布情况(为了方便观察,图中仅展现了2小时的分布情况),分钟粒度统计的请求分布以5分钟为周期呈脉冲状,且在小时初有突增现象。
图10 预加载请求数分钟分布
为了排除自然流量本身具有5分钟内不平滑的可能性,我们对比有5min结算控量的预加载请求分布和没有5min结算控量的实时媒体曝光请求分布。如图11所示,没有5min结算控量的实时媒体曝光请求分布相对平滑,而有5min结算控量的预加载请求分布则有明显衰减趋势。说明脉冲现象是由结算控量带来的,更直觉的解释是部分排期随着到量则无请求,进而导致请求量衰减。
图11 有&无5min结算控量下分布请求
那么上述现象对pacing有什么影响呢?假设调控策略为线性插值,它对(阈值,消耗速度)进行线性插值,消耗速度 = 周期内释放pv量/周期时间,但是由于5min结算控量逻辑存在,导致周期内观测释放pv量比理论可释放pv量小,从而使同阈值对应的观测消耗速度也比理论释放速度小。 那么在调控下个周期的阈值时,为了达到下个周期的目标速度,下个周期的实际调控阈值也会比理论值小。
用个具体例子说明,我们有历史调控数据如图12,假设下个周期的目标消耗速度为115,分别根据观测消耗速度&理论消耗速度计算下个周期阈值分别为0.275和0.30,那我们实际中会使用阈值0.275进行pacing,但是实际上阈值为0.30时,也能满足周期内需要释放的pv量,而且能做到平滑,提高ctr。
图12 pacing历史数据模拟
直接得到图12中第3列不受5min结算控量的理论消耗速度是比较困难的,但是我们可以通过其他方式去逼近理论消耗速度。目前消耗速度是基于每个调控周期(5分钟)内释放pv量计算的,这里我们可以只用前半个周期(前2分30秒)释放pv量去计算消耗速度(周期时间也相应变成半个周期)。因为释放是呈衰减状态的,所以前半个周期的释放速度是比全周期的释放速度更接近理论消耗速度的,从而能缓解结算控量的影响。
那么在开屏预加载场景为什么无效呢?因为结算是通过曝光量控预推请求,预推请求不等于曝光请求,而曝光请求没有脉冲现象。因此对结算通过曝光量控曝光请求的场景,可以一试。
5.2 非实时媒体曝光预估提效思考
在预加载场景,真实曝光 = 实时媒体曝光 + 非实时媒体曝光,前者走引擎链路,算法可通过分配调控策略决策;后者则由端上直接曝光。目前Pacing调控的目标量是真实曝光,初期想法是预估出非实时媒体曝光,算法直接对实时媒体曝光进行调控,本质是期望目标降低,阈值提高,进而提升ctr;进一步思考,历史消耗速度同样由真实曝光得到,也包含非实时媒体曝光。两者都需要减去非实时媒体曝光,最终对pacing效果不确定。总的来说,结算如果可以区分实时/非实时媒体曝光,也许可进一步打开预加载优化空间。
5.3 t+0区分预推请求与曝光请求提效思考
与3.1工作类似,虽然区分日期的引擎改造工作将t+1/2与t+0进行解耦,提升了首次唤起的效果。但在t+0,pacing调控阈值同时作用于预推请求和曝光请求,将两者解耦同时记录t+0预推tt日志,进而分别调控可明显提升效果。
6 致谢
开屏预加载项目的持续迭代及演进, 离不开组内同学的付出和协作团队同学的支持。感谢大朋、郭玮、一栖、歆妍等产品运营同学的建议与支持,感谢彧卿、板牙、地淌、林垚等工程结算同学的合作与支持,感谢橙筱、荣纯、空舟等同学的宝贵积累,感谢昭义、新陈、觉一、王侯等组内同学的帮助与支持,最后感谢主管天穿、玺羽、郑波的信任、推动及支持!