【计算广告】在线分配算法之 —— HWM(High water mark)介绍

2024-05-24 21:18

本文主要是介绍【计算广告】在线分配算法之 —— HWM(High water mark)介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

该算法是雅虎工程师提出的一个解决合约制广告或者说GD(担保式投放)投放系统在线分配问题的贪心算法,思路很直接,下面是本人对照其论文整理的思路,里面有自己的理解。

论文题目:Ad Serving Using a Compact Allocation Plan

google一下即可得到。

===========================================================================================

摘要:

在线广告有很大一部分是通过担保式合约来售卖的。这类广告的特点是:广告系统要保证广告主要求的定向条件的曝光量,有时间限制,超过时间没有完成可能会赔偿。这对广告系统意味着,当一次曝光机会到来时,可能会有多个广告主的单子满足曝光要求,广告系统需要决定这次曝光该展示哪一个合约,并且保证其他所有合约也完成。这个问题有两个挑战:(1)问题的数量级,可能会有百万级别的广告主合约和百万级别的流量;(2)不可预见性,合约通常是提前签订,因此需要预估流量。同时在分配流量时,也无法得知当天总流量的分布。我们这里提出了一种对担保式投放系统的分配方案。
我们提出了一个结局担保式投放系统分配问题的解决方案。分配方案离线计算,可以被广告投放系统有效使用。每一个合约的分配方案只需要O(1)空间。整个分配算法是无状态,可以方便地在分布式系统中使用。

简介:

GD(Guarantee delivery,担保式投送)广告投放系统中的核心问题是匹配supply和demand。当用户展示发生时,广告服务器需要在秒级延迟下选择出合适的合约,使得所有的合约都被满足。这是第一需求,也是核心需求。与此同时,还有很多次级需求,比如平滑,即广告不能在一瞬间展示完,应该均匀分布在合约期内。这个问题的难点在于一个是计算量很大,另一个是在做online决策时,并不知道这一刻流量的整体分布,只能基于历史数据做预测。
先看两种比较直观的思路:一种是基于完成度,一种是基于服务率。
完成度:广告服务器在选择合约时是基于每一个合约的历史展示情况来决定的。比如,如果来一个展示,有两个合约满足,一个合约马上就完成了,另一个还差很多,那么肯定优先展示差很多的那个,即按照完成率来定。这个思路很简单,但是会有一些问题:第一,这里需要给出完成度的确切定义,什么样的合约是快完成了,什么样的合约是还差很多。可能最直观的定义是,每一个合约都均匀显示在合约期内,比如30天展示30万次的合约,那么每天需要展示1万次。这可以让展示非常平滑,但是却忽略了一个事实,即实际的流量是变化的,工作日的流量会少于周末,晚上的流量会少于白天的。而且每一天都可能发生定向的流量骤降的情况,这就需要算法能够动态调整展示的概率。第二,由于需要记录每一个合约的完成度,整个系统是有状态的,这对于分布式系统有一些挑战,但是不是不可解,通过消息队列来处理曝光打点可以解决。
服务率:这种方案不需要考虑每一订单的完成度,而是离线计算出每一个订单的服务率。每来一个展示,就把符合条件的合约按照概率展示即可。这种方案的问题在于:第一,计算服务率肯定是需要流量预测的,那么对预测的准确性要求很高;第二,整个计算的过程是一个分配求解的过程,求解的规模很大。
那么,这里我们提出了一个结合上述两种思路的two-step的解决方案——HWM。第一,我们引入了一个离线计算分配方案的轻量级算法,分配方案是无状态的且是基于服务率的。第二我们提出了一个反馈模型,可以根据最近的历史数据来调整流量预测带来的误差。


问题定义:


图一
考虑上图的例子。有三个广告主的合约和六个流量节点。每一个都被标注了定向条件。如果每一个流量符合某一个合约,那么他们之间会有一条线相连。对于200k{male}的demand,我们可以把{male,ca,age=5}的100k流量给他,那么200k{ca}的demand就无法满足了,除非我们只把{male,ca,age=5}的100k流量给{ca}的demand。这里我们其实已经感受到了分配问题的含义。再强调一下现实问题中的挑战,每一个demand和supply的节点都成百万,而且标签的数目也相当大,远比这个例子复杂得多。
设I是预测的supply集合,J是合约集合。那么分配问题可以定义成一个二部图G。图中任一边e代表流量满足合约j。每一个supply节点被si标记,代表该节点的展示量,同理每一个demand节点被dj标记,代表合约约定的展示量。那么解决这个分配问题其实是找到xij,xij表示每一个supply节点i分配给合约j的占比。xij必须满足:


图二
另外,虽然不是强制,但是上述问题最好能考虑到平滑特性。
整体架构:

图三
离线部分,输入流量预测和合约,生成分配方案。在线部分根据分配方案来决定展示哪一个合约。离线部分,当然可以去解之前的分配方案,得到每一个xij,很直接。但是在在线部分,就需要把整个二部图载入内存,代价很大(xij意味着所有的边都需要载入)。所以关键点就是得到xij,但是不需要存储。我们的方案是通过一个aj来代替xij。aj代表每一个符合条件的supply展示合约j的概率。所有符合条件的supply节点的aj都是相同的。数学依据在另一篇论文。这样的方案,在线模块就只需要加载合约以及每一个合约的aj值即可。

算法:

HWM的离线算法会生成每一个合约的服务率,服务率的大小取决于合约的紧急程度。算法会把每一个demand连同符合条件的supply标记。设对于合约j,所有满足条件的supply节点的流量和为Sj,然后按照Sj/dj升序排序(原文是按照Sj排序,在另一篇论文里是按照Sj/dj排序,个人认为后者更合理,具体见附录),这个值越小,意味着这个合约优先级越展示。按照这个值对合约升序排序,得到一个叫allocation order的排序结果。接着计算服务率,算法如下:


图四
第一步:设ri为每一个supply节点的剩余流量,si为预测流量,那么最开始,ri=si;
第二步:对于所有的合约j,先按照allocation order排序,再求解aj。这个式子的含义是,把所有合约j满足的supply节点拿出来,对每一个supply节点都求出min{ri,si*aj}值,然后求和,使得和等于dj。如果没有解,那么aj=1;再更新每一个ri。
这个式子什么含义呢?
aj代表合约应该被展示的概率,si*aj代表supply节点i应该给合约j的量,但是可能这时i节点已经没有这么多量了,这时i节点应该给j的量就是ri,所以对每一个节点i,取的是最小值。对所有符合条件的节点i都求出展示量并且求和,就是节点j可以得到的展示量,这个值应该等于合约量dj。至此,一个合约的aj求出来了,然后再更新supply的ri值。下一次迭代。
现在来直观地理解一下这个算法:首先按照allocation order排序,那么最紧急的合约已经被排到了第一位。然后根据Sj/dj算出aj。aj表示你每一个服务条件的supply节点给我的量的比例。因为这是第一个demand点,所以不存在流量不够的情况。那么对于后面的demand节点,就可能存在某些supply节点量不够的情况,这时只能用ri代替,那么其他节点就需要多出量,所以这时得到的aj肯定是大于Sj/dj的。当然也可能所有的supply节点都不够,那么就把aj设为1。

图五

看上面的例子,排序结果是2-1-3。先算2,a2=200/200 = 1,更新第三个supply节点的ri=0;再算1,由于第三个节点ri=0,所以只能用前两个节点,a1=200/800 = 1/4;a3留给读者。
至此离线算法结束,我们已经为每一个合约都赋予了一个服务率aj。
下面是在线部分。
第一步:给定一个展示i,设J={c1,c2,。。。,c|J|}为所有符合条件的合约集合,并且按照allocation order升序排序;
第二步:设l是[1, |J|]中的最大值,A = a1+...al <= 1,但是a1+...a(l+1) > 1,那么令a(l+1) = 1 - A;
第三步:对于1 <= j <= l,每一个合约j的服务率就是aj,而j=l+1的服务率是上面计算得到的a(l+1)。然后按照这个服务率作为这些合约的概率,从中选出此次展示的合约。
注意,这里假设是aj求和大于1的情况,如果小于1,则意味着有些流量是浪费的。
看之前的例子:
如果展示{CA,age=5}到达,那么l=1,则合约1总是被选中;
如果展示{Male,age=5}到达,那么l=2,1/4的概率分给合约1,5/8的概率分给合约3,1/8的流量会不会被分配。这些流量可以被其他变现途径利用。
至此,HWM算法就介绍结束了。原文的评估部分没有继续探讨了,有兴趣的可以自行查阅。

小结:

GD系统的挑战:
1.计算量大;
2.依赖预测的准确性;
HWM的思路:
1.2-step;
2.用aj代替了xij,较少内存消耗;

附录:这是另一篇shale算法论文中对HWM的描述,其中allocation order的一句被定义为Sj/dj,与本文不同,个人认为shale论文的定义更合理。

这篇关于【计算广告】在线分配算法之 —— HWM(High water mark)介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/999552

相关文章

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式

redis过期key的删除策略介绍

《redis过期key的删除策略介绍》:本文主要介绍redis过期key的删除策略,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录第一种策略:被动删除第二种策略:定期删除第三种策略:强制删除关于big key的清理UNLINK命令FLUSHALL/FLUSHDB命

Android实现在线预览office文档的示例详解

《Android实现在线预览office文档的示例详解》在移动端展示在线Office文档(如Word、Excel、PPT)是一项常见需求,这篇文章为大家重点介绍了两种方案的实现方法,希望对大家有一定的... 目录一、项目概述二、相关技术知识三、实现思路3.1 方案一:WebView + Office Onl

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

Pytest多环境切换的常见方法介绍

《Pytest多环境切换的常见方法介绍》Pytest作为自动化测试的主力框架,如何实现本地、测试、预发、生产环境的灵活切换,本文总结了通过pytest框架实现自由环境切换的几种方法,大家可以根据需要进... 目录1.pytest-base-url2.hooks函数3.yml和fixture结论你是否也遇到过

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

MySQL中慢SQL优化的不同方式介绍

《MySQL中慢SQL优化的不同方式介绍》慢SQL的优化,主要从两个方面考虑,SQL语句本身的优化,以及数据库设计的优化,下面小编就来给大家介绍一下有哪些方式可以优化慢SQL吧... 目录避免不必要的列分页优化索引优化JOIN 的优化排序优化UNION 优化慢 SQL 的优化,主要从两个方面考虑,SQL 语