数据驱动增长 895% 背后的理论与实践

桔妹导读:在营销增长领域,我们一直在思考工程技术侧可以做什么来赋能业务,尤其在完成0-1的基础设施建设之后,技术的发力点在哪里;我们不想去做陷入细节的、不确定的平台优化,这会带来不确定的业务收益,不明显的ROI,尤其在业务的爆发式增长期,在资源相对有限的情况下我们认为瞄准业务痛点,技术驱动的“快速赋能”是首当其冲的事情。我们基于纯工程手段实现了bandit中的Epsilon-Greedy算法,并让Epsilon-Greedy和我们的投放系统深度融合。

1. 

背景

滴滴城市运输与服务部内容投放系统(CMS)是业务投放物料(文案、图片、链接、流媒体等)到客户端的管控平台,支撑了600+资源位的日常投放,投放的维度包括城市、人群、围栏、频次等,多个投放竞争同一个资源位是普遍存在的现象,毕竟资源位是有限的,维度不同的投放之间不构成竞争关系,比如2个投放一个投北京另一个投上海,或者同一个城市但配置的2个人群没有交集、不同的围栏等;但是随着投放的增加,任意2个投放之间发生竞争是常见的事情,甚至在一些线上场景中,同一个资源位有多达100多的投放,并且70%的投放由于城市、人群等条件冲突没有曝光机会,这里有一个问题,谁的投放优先?

一番argue之后,业务会获得一个优先级的排行,于是在我们的系统里面多了一个优先级配置项;功能层面看,一切都没有什么问题;数据层面看,我们发现80%的资源位ctr不足5%,资源位利用率整体不高,作为平台方,我们很自然的想到,资源位就在那,要尽可能让每次曝光都有价值,一场技术发起的Data-Driven计划开始~

2. 

结果

先说结果,我们在4月14号下午在某资源位上线了我们的优化后的服务,下面是点击率曲线,周环比数据从13号的1.35%增长到20号的13.43%,增长895%

点击uv从13号的211增长到20号的1659,增长686%

硅谷Growth Hacker之父Sean Ellis也表示了祝贺。

优化的核心思路就是让所有投放都有曝光机会,按照一个比例去采样,获取一个整体投放的ctr排行来替代原有的优先级,熟悉算法的朋友可能注意到了,这就是经典的bandit场景,但是CMS要考虑的因素非常多,后面我们将一步一步展开,这里先放一个设计图,读者可以在看完文章以后再回来。

Chapter 1 发现问题

首先需要找到优化价值比较高的资源位,这样才能看到明显的对比效果,我们需要量化投放的质量,这里我想过很多指标,实验后最终选择了一个简单暴力的。

首先要想明白一个问题,什么样的投放需要去治理?很容易想到是ctr低的,但是除了ctr之外还有别的因素吗?比如两个资源位的ctr都是2%,一个是200/10000,另一个是2/100,先优化谁?显然是200/10000,因为他的曝光有10000,价值更大,于是我们得到了结论,我们要找点击率差但是曝光大的,也就是和点击成反比,和曝光成正比。

最终我们可以得到和曝光uv的平方成正比,和点击uv成反比。基于这个公式我们得到的数字往往很大,无法观测,这个时候我们需要把值域缩到百分制以内,我们使用的是最常见的min-max归一化。

现在还差一步,归一以后一些数据存在非常小的差距,比如50.000001和50.000002这种情况,如果保留2位小数根本看不出来gap,这里我们使用sigmoid利用曲线让数据之间的间隙柔和一些。

显然最后数值x越大代表治理的收益越大,100-x则可以作为质量分,分数越大质量越好,找到合适的资源位以后和业务确认一下,可以开始后面的优化计划。

Chapter 2 采样

我们每天从hive定时同步资源位曝光点击数据到mysql,获取目标资源位的历史曝光PV,取10%左右的流量作为实验流量,90%作为正式流量,将这10%的实验流量均分给所有投放(前文提到70%的投放连曝光机会都没有,并不意味着这70%的投放ctr不好),比如资源位A日常流量是10w,配置了10个投放,则拿1w流量来实验,再平分给每个投放也就是每个投放需要曝光采样1000次。这就是我们的采样计划,它被放置在cms条件过滤链(pipeline)的末尾,当某个用户访问这个资源位并且经过城市、人群、围栏等条件筛选就会去进入到采样环节。可能你注意到了,每个用户经过过滤链以后,筛选剩下的投放序列都不一样,假设配置了投放[0,1,2,3,4,5,6,7,8,9],用户A经过过滤链看到[0,3,5,7],用户B看到[8,9],如果不加干扰,根据之前的优先级,用户A将看到[0,3,5,7]最前面的0号投放,用户B将看到[8,9]最前面的8号投放。当过滤结束以后,我们会对请求进行随机采样,使用的是最简单的1-100随机数,小于10的会进入采样环节,否则继续走老逻辑,如果采样完成也将继续走老逻辑。后置的采样逻辑将不会对投放产生任何侵入影响。

下面说下最核心的采样环节,我们最早一版的想法是同步采样,先采投放0、再采投放1,一个一个等待,这样会带来一个问题就是采样流量的浪费,我们使用了一个更柔性的设计,如下图,假设有5个投放需要采样,每个采50次,初始化任务task0、task1、task2、task3、task4,此时流量A经过过滤带着序列[0,2,3]过来,按优先级默认展示0,此时task_0的采样计数+1,下一个流量[0,1,3,4],按优先级默认展示0,task_0的采样计数再+1,下一个流量[2,3,4],对应task_2计数+1,一段时间后,task_0已经满了,此时流量[0,2,4]来了,由于task_0已经采样完毕,所以退而求其次选择让task_2曝光。

采样完成以后,就可以实现自动干预,假设用户A经过过滤得到了序列[0,3,5],按照优先级将默认曝光0号投放,但是我们发现5号投放ctr更高,最终用户将看到5号投放。

Chapter 3 人工干预

显然业务需要干预一些顺序,比如虽然某个投放效率不好,但是由于某些因素不得不放在前面,这里我们设计了人工干预的能力,人工干预是基于拖拽的,当你把某个投放拖到某个位置往往有几种语义,比如我要把某投放放到第2位的绝对位置上,或者我要把某投放放到另一个投放之前、之后等,我们的页面会去让你选择具体的意图,最终这个人工干预序列会和前面的ctr序列merge到一起。

目前的数据是T+1的,这意味着业务今天配置的投放系统不知道应该放在什么位置,这里我们需要回到原始人工定义的优先级的语义,业务会在系统配置优先级,比如4个投放的优先级分别是500、450、430、420,此时插入的投放优先级是440,它代表业务希望将数据放到所有投放的中间位置,我们会参考这个优先级在之前优先级的相对位置,放到新的序列的对应位置。

业内一些投放系统使用了类似的bandit思想,但主要是扁平的对比,因此可以基于userid分组的方式,简单的切分流量,相比而言我们的CMS采样更复杂,要考虑更高维度、多条件的组合下均匀采样,这种情况下我们给出了上面的均匀采样方案。

此外我们还在redis hotkey的问题上做了优化,很多计算会在memory中batch操作以后再去读写redis,这种情况下会对精度带来一些波动,但是不重要,因为我们连10%采样比例和质量分都是拍的,能相对体现用户的接受程度就好。最重要的是去思考数据背后的语义,你会发现从质量分到采样比例、到优先级我们并没有纠结数字是什么,而是这个数字背后的意义是什么。

最后十分推荐亚里士多德的《形而上学》,这本书会告诉你该做什么,而不是机械地去执行,探讨业务背后本质。非常感谢Sean Ellis先生,2年前我和Sean的沟通中他提到实验才是用户增长最有效的一环,他见过硅谷很多科技公司使用AI去做增长,但这不是本质,增长的本质就是实验。Sean的团队最近设计了世界上第一款增长模拟引擎GoPractice,有兴趣的朋友可以去看看。

这套思路的落地可以让我们看清实验可以不局限于单纯的AB。

本文作者

团队招聘

Prado系统是基于业务场景构建的营销增长平台,系统具备用户流量管理,运营活动管理,任务中心管理、营销数据应用和评估等功能,服务于两轮车、代驾、货运、跑腿、出租车业务线,日常运营中将营销能力植根于业务建设,积极打磨中台的会员权益服务、投放平台、渠道管理、组件能力、开放能力、智能营销能力等,以数据驱动为核心,持续优化营销工具,助力业务持续增长。在Prado你将参与高并发、复杂营销链路架构设计;你将和顶级团队一起打造全新的营销增长解决方案。

滴滴Prado营销增长团队长期招聘高级Java研发工程师,可投递简历至[email protected],邮件主题请命名为[你的姓名-Prado]

扫码了解更多岗位

延伸阅读

内容编辑 | Hokka Teeo

联系我们 | [email protected]


猜你喜欢

转载自blog.csdn.net/DiDi_Tech/article/details/117050102