打造哈啰自动化增?算法闭环(上)
导读:本次分享的主题是哈啰打造自动化增长算法闭环的实践,上篇将主要介绍哈啰C端算法场景和挑战及哈啰主动增长算法。
哈啰C端算法场景和挑战
文章图片
首先看一下哈啰的C端算法大概有哪些场景。哈啰C端算法最终的目的是要服务于我们出行业务的增长,同时也要扶持我们生活服务相关的业务。目前在端内流量类型有很多,包括我们常规的banner、弹窗,还有一些组件。端外我们会对打车顺风车大力投放广告,主要是在公共的广告平台,包括在一些运营商的系统上投广告。还有一些免费流量,主要是指在微信和抖音这样的公域和私域流量。另外,有一块特色就是我们线下的门店以及两轮车,我们可以把它看成一些智能的硬件,或者说一些智慧的门店,通过我们的AloT平台接入到公司系统中,也是一个重要的流量来源。
这些不同的流量类型和我们现在的各种业务交叉起来,就会发现哈啰的C端场景太多了,而对哈啰这样一个中等规模的公司来讲,就出现了场景众多和开发的人力十分有限的矛盾。同时我们自己团队也会有一些技术追求,如果只支持业务,不仅对我们没有成长,而且效果也未必会达到最好。所以业务支撑和技术深耕间也是一个矛盾。
文章图片
既然搜广推有这么多服务场景和矛盾,我们在最初半年的实践过程中,不断形成如何解决这个矛盾的方法论,基本的思想就是不要重复造轮子。我们在提高算法开发效率的同时,各个域将行业最新经典的技术和自主创新相结合。
最初我们支撑业务还是用一些最简单的定制的模型,包括Tree模型和 CTR预估中的一些经典的模型,业务也只是从体量最大的出行业务开始,其中对两轮这部分它的收入运营我们进行一个业务策略的高度抽象。
在2021年,我们开始按照一个新的方法论打造整个算法体系。首先我们要有统一的C端算法体系。C端算法体系无论是搜广推,还是我们说的营销以及其他的流量分发等,它的基础技术是高度同质的,是有可能做统一的。
另外我们在计算的过程中,想把哈啰增长引擎给打造出来。我们底层的机器学习平台是我们自主研发的贾维斯AI平台,所有算法同学都在上面工作。上层的话,我们在算法铺量的过程中打造了搜推引擎和营销引擎,对少部分的场景,也就是对两轮收入运营开始做自动化运营的实践。自动化运营,就是要对策略要做一个高度抽象。而策略也是分不同层级的,我们会参考OKR拆解的方法,把策略从一个目标级的策略,拆解到KR级的策略,再拆解到Task级的策略。因为用户运营的工作是相对标准化的,所以这个流程是完全可以自动化的拆解下来。
文章图片
关于打造统一的C端算法体系,让各个域不要重复造轮子,让我们来看一张图。最左边一块是哈啰所有的流量,最右边一块是哈啰所有投放的内容,包括一些营销内容,以及我们传统的社区,还有一些我们的电商商品和本地生活的一些服务商品的内容。
这些商品从流量侧看,我们要提升流量效率,这个就是eCPM。从业务侧的视角看,我们要提升它的用户增量以及收入,也就是GMV,而用户增长主要看ROI。这几个域都会用同一套的技术体系,也就是业界常用的多路召回和Rank算法。我们这里面的各个模块和业界会稍有不同,有些领域比如说Rank中我们会重点建设因果推断及L2R的技术。在多路召回中,我们会建设Graph Embedding,以及一些知识库搜索这样的召回体系。
我们会把基于流量的算法叫被动增长算法,因为不需要我们额外造一些资源位,打扰用户做一些推送。而我们将用户增长和收入增长定义为主动的增长算法。
哈啰主动增?算法
4w2h
文章图片
主动增长算法是我们对一个用户希望进行一些营销动作,也就是狭义的营销算法。整个营销它是一个链路,用的是一套4w2h的体系。第一,你要选择什么样的人来做投放,就是精准定向。第二,你投放的内容是什么,就是我们的素材,包括文案、图片、卖点等等。第三,你要选择什么时机,选择什么素材来投放,这在我们这块叫做智能触达,包括push也是放在这一块。第四,投放给一个用户的营销,基本上会通过活动的形式,或者说任务的形式等等,任务是可以自动化的生成。当然最重要的一块是我们的补贴,因为大部分的营销它要是有一定的实实在在的开销,才能把用户给最终吸引过来,所以要有补贴,补贴在出行和本地生活领域是一个很核心的事情。
精准定向
文章图片
精准定向,在哈啰这边它有两种模式。一种是从一个大的池子中挑选出少部分的精准用户,我们这叫行业包。还有一种是LookAlike,给一个种子人群,根据相似度扩大它的规模,在我们这边的主流方法是行业包。因为和广告领域不同,我们的用户池子其实是已知的,主要是哈啰注册的5亿用户,然后在池子中捞一部分人对各个不同的业务进行一些拉新促活。
最简单的方式其实是有监督,但有监督会有很多的问题。比如说第一个问题,高潜的用户会很快耗尽。像很多新业务,如果是用有监督的方式,如果这个池子比较小,可能一两个月池子就被耗尽了,接下来就没有高潜用户可以营销。另外,我们有很多动作是拉新,新用户明显特征是比较稀疏的,可能样本也比较少。但是最大的问题是在精准定向这个领域,它是没有真正的负样本的,比如一个用户的营销不起作用,不一定是他对这个业务不感兴趣,有可能他是对营销不感兴趣。因为人的心理特别复杂,大部分人看到一个营销动作,本能其实不会有太大的反应。
我们的负样本并不是一个真正负样本,应该叫未知样本。所以这里的解决办法就要用到半监督的方式。即从未知的样本中,识别出真正的负样本,我们会使用PU- Learning技术,最终的效果是在同等ROI的基础上,把我们拉新的潜客规模扩大2-10倍。同时像特征少的问题,基本上会用交叉业务的特征,比如打车和酒店就是一个高度相关的业务,他们之间特征就有很多可以复用。另外两轮是我们用户基数最大的一个业务,很多业务线在拉新建设的时候,都会复用两轮的特征。
文章图片
接下来我们来看PU- Learning是怎么做的。一开始我们用的是最传统的TSA算法,也就是间谍样本技术。我们首先会在正样本中挑选出一些,假装它是一个负样本,混在未知样本的池子里,相当于人为提高一个正负样本区分的难度,然后在未知样本和正样本中选出来一些间谍样本,假装它是一个负样本,和正样本在一块训练一个分类模型,而这个分类模型我们是希望尽量把负样本中的未知间谍样本,也就是那部分正样本和真正的负样本给区分开来。
一旦分类器建立之后,我们就用第一步的分类器来给所有样本打一个分,把其中分低的作为真正的负样本。然后再建第二个样本池子,在这样反复的迭代过程中,直到我们把间谍样本完全识别出来,做到一个收敛情况。通过这种方法,我们就能把未知样本中真正的负样本给识别出来。
后面我们又做了一些改进,因为传统TSA算法会有几个问题。第一个问题是你正负样本划分的阈值,它其实是一刀切的,并不是一个合理的值。所以我们用EM算法把分布给聚类起来,学到了它真正的正负样本的阈值。这其实也是对正样本进行了数据增强,因为正样本在我们这边非常少。而另一个改进点,我们一开始用的 PU- Learning基准模型其实是GBM, GBM套着GBM,时间长了一定会实现信息茧房效应。所以我们在第一步和第二步的模型后面进行了一个区分,第二步模型改成DeepFM,通过GBM和DeepFM的交叉迭代的学习,减少信息茧房的问题。
文章图片
刚刚讲的是第一种方式——行业包,即在一个大的池子中捞出一部分精准人群。另一种方式是LookAlike,这是更传统的一种方式。我们用的技术是Graph Embedding,通过用户之间的行为或者某种关联给用户作为点,用户有行为关联的建立一个边,最后把用户的Embedding给学习出来,从而通过这种向量,用相似度的计算能把用户的人群扩大。
Graph Embedding现在已经相对成熟,但是在哈啰的主要挑战是这个图怎么构建。因为它和传统电商不同,最重要的是识别出强的行为,怎么把用户之间的边给连接起来。
文章图片
第一种我们会用时空,真实用户在出行中的时空空间上的关联给它建立图,比如说同一个地块,同一个时间段,两个不同的用户发生了同类行为,如给单车开关锁,这样它就能连一个边,但这种行为还不够强。我们参考了电商领域的行为构建方式,我们在想是不是我们整个APP所有的事件,所有的物料的行为都可以用来建图,于是我们在首页进行了探索。
这里有一个图,比如说上面的icon,中间的banner,还有下面的种种其他的营销物料,其实在不同资源位置以及每一个物料,它都有一个物料ID,同时它也是某个业务推出来的物料,这三者的结合就能唯一确定一个item是什么东西。用户在我们整个首页点的所有item的一个序列,通过这种序列也可以来构造用户之间的边。
我们的技术模型选用的是EGES,因为哈啰还是一种偏工具的APP,而且行为确实没有像电商的购买行为这么强,所以SideInfo对我们来讲就会更加重要。
文章图片
【打造哈啰自动化增?算法闭环(上)】同时哈啰的用户量还是很大的,当然我们选的是近几天活跃的用户作为我们的向量池子来扩展,非活跃用户的话也就给刨掉了。如果是全量的话,几亿的用户算下来计算的性能耗不起。当时的向量引擎选的是Milvus,一开始我们也实验过其他向量引擎,但对比下来Milvus的性能是最好的。我们在几千万用户以及几十维向量这样的规模下,可以做到小时级别的全量用户的向量化。Milvus线上的查询也能达到近实时查询的程度,最终的实验效果通过向量的相似度进行量级的放大。我们可以扩大人群的规模10-1000倍不等,同时保证ROI相比人工策略一直是提升的。当然放大规模越大,提升幅度也会越小。
文章图片
我们在构图的过程中用的是用户的时间序列,但目前还没有把一些非信息流的页面的事件,或者说各个业务私域的一些事件序列给拉排进来。这需要更统一的数据埋点体系的建设,也会是今年的一个重点。
智能补贴
文章图片
有了定向的人群之后,我们就需要知道怎么做补贴。补贴可以认为是这几个领域中对我们最核心的一个域。补贴这个域,基本上因果推断已经逐渐成为技术主流。一开始我们用的是CTR 预估的方法,来看一个用户喜不喜欢点券之类的东西。但实际上用户并不是只有点和不喜欢点这两类,而是有四类,包括营销敏感、自然转化、无动于衷和反作用类。因为部分用户其实你不营销,他自己喜欢这个业务可能也会来,营销并没有带来增量的作用。还有部分用户对营销比较反感,营销之后他反而不来了,影响他的留存和活跃等等。
举个具体的例子,假设我们有两类用户各1万个人,卖一个商品是10元,券是8折券,现在想给这两拨人来决定到底给谁发8折的券。比如说原本情况下B类用户发券了之后的购买率是1.5%,不发券是1.4%,但实际上发券这个动作带来的增量的购买率只有0.1%,A类用户反而带来的增量购买率更大,是0.5%。所以并不是说 B类用户的购买率高,更应该给他发券,而是A类用户发券带来的增量效应更大,才更应该给他发券。
那B类用户到底应不应该发券呢?其实还可以看收益的增量。如果把我们发过券之后,打折带来的损失以及我们购买率提升带来的增益,合起来算的话,B类用户甚至还是亏的。不发券能挣1400块钱,但是发券之后因为打了折,反而只能挣1200块钱。所以对B类用户就不应该发券,只用对A类用户进行发券。
文章图片
所以对因果效应的建模是我们的一个重点,我们用的是Uplift model。第一版我们建了两种Uplift model,它适用的场景不同。第一种是基于Tree构建的,原始的Uplift Tree相当于是做一个增量转化率的预估。增量转化为什么选Tree,第一它是对Uplift进行直接建模的,而不是说建两个不同的模型,它的建模精度会比较好。另外Tree的可解释性是相对强的,我们知道Tree基本上是通过分裂准则来模拟目标最大化的一个过程。我们可以对比一下普通的分裂准则和Uplift Tree的分裂准则有什么区别,普通分裂准则就是信息增益最大化,Uplift Tree最原始的方式是通过分布散度最大,来让我们的干预组和被干预组,所谓干预组也就是发券组,这两个组的分布差异最大,从而达到Uplift最大的效果。下面是一个示意图,通过Uplift Tree的分裂,我们最终可以把人群真正区分成4类不同类型的人群,最后只对营销敏感的这部分人群进行真正的营销,而其他三类并不需要营销。
当然这个原始的Uplift Tree,它是针对转化率做增量的,而我们现实的业务中大部分场景目标是收益,而不是转化率。所以我们进行一个改进,把分裂准则改进成一种新的方式来做收益的最大化。
假设分裂前数据集是θ,我们就可以计算分裂前的收益是多少,也就是发券组和不发券组人均效益进行一个差,然后乘以一个平方,它其实是对欧氏距离分布散度最大化的一个扩展的改进。然后是根据某个特征对当前节点进行分裂,得到一个分裂后的因果效应,分裂前和分裂后的因果效应的差,其实就代替了我们之前的信息增益的最大化。通过分裂前和分裂后因果效应差值的最大化,来作为我们的一个分裂准则,就这样不断选择新的特征,这是第一层的分裂。第二层就选另一个特征接着分裂,不断选择这种迭代递归的过程,最终整个构建出来。这就是一个TreeLift的过程。
文章图片
TreeLift的难点是怎么构造样本,因为现实中不存在平行时空,我们不可能对一个人同时发券又不发券。那怎么样让模型学习发券相比不发券的增量收益呢?我们想到是用群体来代替个体,如果是两个同质的群体,其实可以学习发券群体和不发券群体之间的增量收益。这就通过构造随机实验的方式,也是现在Uplift领域的一个主流方法。最终的效果,我们在自有的数据集和业界的公开数据集及传统的经典方法做了一个对比,发现它的Uplift曲线是最大的,相比我们自己的响应模型,在场景下的收益大概有4.7%的提升。
文章图片
另一个是我们的DeepLift的模型,DeepLift模型是我们在DragonNet的基础上进行改进的。DragonNet有几个优点,它不需要用随机实验,随机实验的构造成本是很高的,你的模型后面基本上没有办法做自动的更新。我们用DragonNet通过向量化模拟了一个随机实验,同样它又构造了一个倾向分的子网络,能够做一个样本筛选,可以把因果无关的一些特征变量筛掉,而大量的特征其实和因果并没有关系。我们在DragonNet基础上做了一些改进,第一是增加了模型的复杂度,第二是改变它的loss,更加的贴近业务。因为原始的DragonNet其实和原始的Uplift Tree一样,并没有以收益为目标,而是以转化率为目标。因此我们各种loss增加了新的G的网络,以及改变了它基础的loss的方式。我们DeepLift模型的网络结构可以看右边,DeepLift我们更多使用在一些需要自动更新的场景。
智能文案
文章图片
知道了什么人,也知道补贴多少钱,这个素材本身对用户的冲击力是更直接的。我们通过智能文案对整体的点击率,不同样式的点击率,包括banner、push、弹窗等等,形成了30%-100%不等。营销领域的文案普遍都是比较短、比较正式的那种文字,和电商title、视频的标题不太一样。另外相对于内容领域,我们的语料并没有那么充足,所以一开始它的文案生成用的是模板的方式,在模版中加上一些动态词包。但在今年已经改造成了模板加上语句通顺度的识别这样的方式,大量扩充我们的文案候选集,增加多样性,减少用户的疲劳。
另外在有监督模型基础上,我们增加了EE的模块,因为文案的多样性,还有新文案,新素材的快速实验是特别重要的。具体EE的算法,我们用的是最朴素的Epsilon-Greedy算法。
智能广告外投
文章图片
刚才讲的几种营销方法都是针对免费流量的,或者说主要针对我们端内的一些资源。而很多像端外,比如说像巨量引擎、广点通这些,我们需要做智能的广告外投。以前相当于我是作为一个广告平台,来收广告主的钱,而现在我作为一个广告主,要在平台上投放,怎么样才能投的效果更好呢?
比如说我们场景主要是在四轮拉新,四轮拉新其实还有很多问题,第一个就是特征少的问题,广告计划的马太效应很严重,甚至配置可能一模一样的计划,有的计划消耗很高,大部分的计划消耗很低。所以大量消耗很低的计划,如果数据又不多,你想提前识别这个计划在未来表现的效果不好,给他做提前下线,而减少对未来的开销的损失。那怎么做呢?就是要在底层做用户完单预估,这个计划里面的部分用户已经发生了转化,通过这部分的用户完单预估来推算整个计划的质量。另外计划本身它有一些投放的效果反馈,虽然大部分计划它的投放量还没有那么大。通过这两个模型,我们能做到劣质计划的预判,对它进行提前的关停。而对优质计划我们能够做自动的补预算,最终我们想实现通过自动投放,把整个广告的预算、计划、素材,还有定向条件等各个维度全部自动化。
文章图片
广告计划的预估主要在特征这一块,它的特征比较特殊。第一,ID类的特征特别多。广告计划的计划广告组以及下面的素材是一层一层的,有很强的语义关系,同一个组下面的广告计划基本上都是一个类型。这些ID类型有很多语义相似性,我们需要用w2v进行提前embedding。同时它的数值特征和广告参数配置特征又比较少,所以这里需要通过大量的交叉来扩展这个特征的表达。之后我们用一个传统的FM模型进行宽深的预估。我们这里预估用的是多分类,而不是二分类。当时我们对比了回归和多分类的效果,发现回归的难度,特别在广告计划缺数据的情况下,是非常难的,还是多分类的效果会比较好一点。
文章图片
广告计划的投放,它更多是离线的投放,每天会对计划做一次调整,并不是实时的干预广告平台的竞价引擎。实施干预我们主要通过RTA和RTB的方式,用的技术也是因果推断技术。我们把用户分为五类,对已经转换的用户直接通过规则屏蔽掉,不需要把已有的用户再拉新一遍。剩下的用户根据对我们平台意向程度的不同,分成uplift几档,然后识别出不同用户质量分,通过各大广告平台提供的API来干预它的竞价引擎。最终我们通过这两种方式,在打车的乘客以及顺风车的车主上,投放成本会有显著的降低。
下篇将介绍哈啰被动增长算法和哈啰增长引擎的实践,敬请关注。
(本文作者:贾立)
阅读哈啰技术更多干货合集
前端 | 后端 | 移动端 | 算法 | 项目管理
文章图片
本文系哈啰技术团队出品,未经许可,不得进行商业性转载或者使用。非商业目的转载或使用本文内容,敬请注明“内容转载自哈啰技术团队”。
推荐阅读
- 校企融合,打造金融科技应用人才高地
- 如何打造一个TB级微服务海量日志监控平台
- Python实现半自动化网络管理与日常工作
- 七朋打造共建共享价值互联网平台
- 集简云 x 海硅企服(助力企业快速满足系统互联需求,轻松实现自动化业务流程!)
- UI 自动化找元素太难(AIRtest 框架你值得拥有!)
- #yyds干货盘点# Selenium Web端自动化从入门到实践
- 测试用例|如何统一接口测试的功能、自动化和性能测试用例
- Springboot docker jenkins 自动化部署并上传镜像
- 巧用云函数打造微信网页授权公用服务