用户出行需求预测
导读 本文将分享飞猪在用户出行需求预测方面的一些工作。主要内容包括:
全文目录:
-
背景与挑战
-
算法优化历程
-
思考与总结
-
问答环节
分享嘉宾|黄茂雷 阿里巴巴 机器学习算法工程师
编辑整理|吴雪松 小米
内容校对|李瑶
出品社区|DataFun
01/背景与挑战
1.背景介绍
在飞猪 APP 端、支付宝或者淘宝端,我们用到的交通相关的业务主要有三个:机票、火车票和汽车票。这里以机票为例,来展示一下各个子场景:
- 入口模块:主要为用户进行 TOP1 的需求预测,也就是 TOP1 推荐,让用户点进到各个子场景当中,起到一个引流的作用。
- 模糊搜索:主要为用户填上一个目的地、出发地以及一个时间段,在未来的某个时间段,他们可能会去哪里。
- 低价模块:主要为用户去推荐,或者预测,用户会对哪些 OD 感兴趣,因为这些是比较便宜的,有可能命中用户的心智。
- 瀑布流模块 & Listing模块:主要为了提升用户的浏览深度,给用户种草,激发用户出行。
2.特点与挑战
交通业务场景与传统的电商推荐是不一样的,因为交通旅行场景,有很大的场景特色。具体而言,用户出行周期主要分为四个阶段:
- 激发需求,用户为什么想要出去。如热门城市,或者节假日,如春节,国庆等固定的出行需求,或者当用户发现一个好的地方,想去出行。这一阶段,定义为种草,主要是平台去激发用户的出行需求。
- 行前阶段,用户准备去哪里玩,需要做的一些准备工作。比如订哪个酒店,交通方式是什么,用特价机票还是火车票,还有相应的门票等,这是行前阶段。
- 行中阶段,主要捕获用户的心智在于当前所在的地方,周边有没有好玩的,返回或者下一个目标交通如何到达,或者是门票如何购买。
- 行程之后,用户出行之后是反馈,然后再循环。
在用户出行周期中,主要面临四个挑战:
决策长周期性。在传统电商平台,用户每个月或者每周都会使用淘宝或者京东App进行购物,但是旅游的决策周期非常长,一年可能也就会出行几次,每两个月出行一次,或者一个月出行一次。
行为稀疏性。同上,电商App的用户行为就比较密集,但是在旅行场景,尤其是疫情期间,可能一年出行两次,用户的行为就比较稀疏。
行为时序性。其实是场景的优势,如果用户出行,先通过交通工具到一个地方,然后订酒店住宿,再乘坐交通工具到另一地方,用户先做什么后做什么,有明显的逻辑性。如何充分利用出行规律中的逻辑性是一个难点。
时空关联性。假设用户22 年的春节回了老家,那23 年的春节大概率也会回老家,这个时空关联性就比较强。如何捕捉时空关联性,也是要解决的一个问题。
定位挑战之后,业务的目标可以拆分为用户侧和商品侧。利用用户侧用户的基本属性、社交关系和旅行状态和商品侧做匹配,匹配目前主要是关注三个方面:
- 需求,用算法预测用户去哪里,或者预测用户下个阶段会去哪里。
- 效率,首页推荐要比用户搜索得到体感更好,减少了用户看到感兴趣OD的时间。
- 心智,不同的用户,有不同的心智和想法。在出行中,如何捕捉到不同用户的不同心智,也就是用户的潜在心理与需求,也是一个难点。
针对以上三个方面,接下来主要讲解整体的算法优化历程。
02/算法优化历程
1.架构
用户进入到一个飞猪推荐场景,会触发个性化。我们的实时用户中心、实时特征中心和交通信息池会根据这里面的信息去对该用户进行一个用户画像。用户画像主要包括用户的一些基础信息,以及用户的一些实时的或长期的、短期的历史行为信息。构建完用户画像之后,我们会利用集团的一些平台,如 iGraph、FPP、Summary、RTP等平台,来提供支持,去进行召回、 OD 信息完善和排序。
推荐预测算法整体上分为召回和排序两个阶段:
- 召回,主要有热门目的地、热门航向、Swing 用户的长期需求、重定向以及用户搜索。
- 排序,目前线上模型主要支持单任务学习模型和多任务学习模型。
- 单任务学习,使用特征融合或特征交叉的AutoInt 或者 WDL 模型。其中,用户历史点击行为序列的模型,主要是采用的 DIN 模型。
- 多任务学习模型,包括 ESMM、MMOE、PLE等模型。
整体来说,第一步是考虑特征交叉,再去考虑特征融合或者序列建模助力机制。图中的ODNET论文是我们在22年发的基于多任务学习的一篇论文,大家有兴趣可以看一下。
接下来分别具体介绍召回和排序这两个阶段的优化工作。
2.召回
先来看线上的情况。
- 用户A:西安--->重庆(黑色线连接)
他有一张西安到重庆的机票,如果利用传统的Swing算法计算相似度,会给用户推荐 西安--->成都,郑州--->重庆的机票。这是不符合常理的,通过捞日志,也会发现这些用户就没有点击。通过分析也可以知道,因为用户已经有一张西安到重庆的票了,再给他推相似的行程是没有意义的。用户接下可能会点的是重庆--->成都或者成都--->西藏的票。以上可以显示出来,当一个用户在旅行的行中,其行为具有明显的连续性。而如果平台没有感知到用户它已经在行中了,使用推荐算法预测的就不准确。
- 用户B & C:北京--->杭州
如果使用传统推荐算法召回,得到的是北京--->苏州、天津--->杭州,因为北京和天津比较近,杭州和苏州也比较近,而且城市相似度也比较高,所以此类行程会被推荐出来,但这也很不对。存在用户B点击的是从杭州--->北京的返程,而用户C 点的是从杭州--->苏州,杭州--->上海。为什么两个用户点击的不一样呢?通过特征分析可以发现,用户B来杭州,是为了出差,没有旅行的心智,所以直接就返程了。而用户C,从北京到杭州,目的是旅游,所以他下一步可能会从杭州再去下一个城市。
以上就是使用传统Swing召回算法存在的问题。一个用户,旅行会具有明显的连续性,就像西安--->重庆--->成都,然后再回西安,存在明显的连续性行为。
如何捕获用户的出行意图也是优化的一个方向,首先看一下传统推荐算法,上图左侧:用户1,买了一条蓝色的裤子,红色的鞋,还有一件灰色的衣服,这是用户 1 的购买行为;用户2, 也买了一条蓝色的裤子,红色的鞋,灰色的衣服。
当一位新用户进入平台,买了一条蓝色的裤子,灰色的衣服,当我们给用户推荐鞋的时候,推荐红色鞋子似乎是理所应当的。因为用户1和2在同时购买这两个物品裤子和衣服的同时,又购买了红色的鞋子,鞋子肯定和裤子及衣服搭配率比较高,这就是传统的Swing推荐算法。但在旅行场景,存在场景特色,也就是说用户不论是旅行、出差还是回家,有很明显的潜在目的。
针对于家乡、景点和公司,我们划分为八种需求:
- H2S,S2H:从家乡去一个景点,或者返程
- S2S:从景点去了下一个景点,比如从厦门去了三亚
- W2S,S2W:从景点回工作地,或者从工作地去景点
- W2W:工作地之间的转换
- H2W,W2H:从家到工作地,从工作地回家
如何融合这 8 种需求,具体而言,如上图右侧的异构图所示:其中对于用户1,虚线表示其离开了北京,假设用户离开了北京,到达了上海,然后从上海离开,到达厦门,最后从厦门离开,到达了三亚。如何把这种意图建模进去?比较关注的是用户的出发城市,对用户而言是什么样的意图,出发城市是家还是公司,到达城市对于用户来说又有怎样的意义,是景点、家还是公司。
在线上,使用用户实时特征系统去判断当前这个城市是否为用户的常驻地、家乡地、出生地或者热门景点去判断。
如图中右下侧公式红色部分,新增意图模块,其中:β 代表用户 u 的一个出行意图, γ 就代表用户 v 的一个出行意图。如果这两个出行意图能够命中,η 作为有意义方向加到这里面去。如果它没有意义,这一项都等于0。针对于使用算法的一个改进,相当于再加入一个用户出行,出发意图和到达意图都融合到公式里。
具体的case,假设线上推的 Trigger D,如果用户的目的地是上海,分两路召回,"回答"用户为什么去上海:
- Travel 旅游去上海,算法召回策略是青岛、三亚、昆明、重庆、成都一些比较相似的沿海城市,或者是比较热门的旅游城市。
- Work 工作去上海,算法会召回深圳、北京、杭州这些具有高工作代表性的城市。
- 另外,如果是Trigger OD,用户从郑州--->上海。为什么从郑州去上海?
- 如果对用户而言,郑州是家乡。而对于上海去,是Work,那算法推荐的应该是返程,上海--->郑州。
- 如果用户是去这个两个地方旅游的,就会给用户保持旅游的推荐的连续性,从上海--->厦门,或者从上海--->三亚。
上图下方展示了A/B test的结果,整体而言,相对于base,召回效率、uvctr & pvctr 效果都有较大提升。
3.排序
(1)模型1---LSGMNet
在进行排序模型的讲解之前,还是以线上的case为例,介绍一下我们为什么要这样做。
- 行前决策,假设暑假来了,用户想着怎么出去玩,首先是没有任何特定城市的明确需求。比如要考虑去南方城市,或者是华东城市。会选择华东哪一个城市呢?是杭州、苏州还是上海,还是最后去上海。以上的行前决策行为是非常重要的,决策过程在算法中相当于一个区域缩减行为,把目的地候选集一步一步地变小,最终得到一个比较准确的推荐,如何去建模行前决策是一个难点。
- 临近城市,也会影响用户的决策。假设从家里去青岛旅游,因为青岛、威海、蓬蓬莱这三个城市离得比较近,先去青岛,威海或者蓬莱,下一个去哪对我们来说意义不大。影响我们心智的无非是价格或是交通的便捷性,这就导致了邻近城市的推荐会出现相互的影响性。所以如何建模邻近城市的相互影响性也是十分必要的。
- 行动阶段,假设用户出发到了北京,但是最近从北京->重庆,或者从北京--->天津的人特别多,用户会不会受热门城市的影响,或者会不会也想从北京--->天津?
针对上述三种情况,将分成三个模块来进行讲解。
- 阶段性决策多任务学习模块
这个模块主要解决在行前阶段考虑去哪个地方玩的多阶段性,比如用户先去华南,或者先去华东,然后再去上海或是杭州,最后决定去杭州。建模时分为三个子任务:GeoHash2 ,GeoHash2和City 级别的子任务,最后再融合为 loss 训练。
- 保持 OD 模块的新颖性和空间依赖性
如果同时保留这两种是比较难的,这里主要是考虑全域的长时间行为序列,通过把 OD 提取出来,建模空间图和热门城市图。
a.关于空间图,如果两个城市在同一个GeoHash2 里面,因为GeoHash2的大小可以跨两个省级别。如果两个城市在GeoHash2 里面,就产生一条边,如果没有就不会产生边,这样就会生成一张空间图。
b.关于热门城市图,主要考虑热门城市和非热门城市。关于热门城市的定义,是通过把飞猪火车票,机票还有汽车票或者酒店的售卖情况去计算售卖量,通过售卖量进行规划,进而计算热门城市。同时也会将热门城市按照区域进行划分,比如按华东、华南等七大区域块进行划分。因为不同区域的人,想去的地方也不太一样,通过划分不同区域内的热门城市和非热门城市。举例,华中区域与华南区域的热门城市,会有 Alpha 产生一条边,非热门城市之间会有 Beta 产生一条边。
这样做的目的是为了保证整体的新颖性,可以捕获一些用户流量。
建完空间图和热门城市图之后,我们它会经过一两个阶模块去提取这些城市的一个隐备点表征,最终经过多头自注意力机制将特征表征进行融合,输出Contact 到当前 3 个子任务上面去。经过这 3 个子任务之后,再通过一个多头自注意力机制将 3 个子任务进行交互交叉的学习。
- 长短兴趣记忆模型
去捕获用户的长短期兴趣,最后进行 3 个 loss 的联合训练。
在离线,主要采用了两个数据集:
- Fliggy,飞猪线上收集的 10/01~11/01 将近一个月的数据,通过 ACC 的1,5,10,20,和Map值进行一个预估。
- Fliggy2,第一个数据集进行策略过滤,因为用户具有稀究性,一年可能点不了几次。过滤策略会将在一年之内点击或者购买大于 4 次的用户,作为高质量用户过滤得到。过滤完之后,再进行模型的训练。
将利用Fliggy2训练的模型推到线上,进行A/B测试,整体的 pvctr 和 uvctr都有4%左右的提升,上线将近 10 天,整体提升效果比较稳定。
(2)模型2---G-PDIN
这里以线下发现的现象作为引子去讲,为什么要这样做。
首先第一个用户,从杭州--->青岛,威海,杭州,青岛,这是他的行为序列;第二个用户,从北京--->重庆、丽江、大理、西藏,去了这些城市。
召回阶段的候选集,三亚、北京、杭州、威海、青海、西安和成都。候选集对两个用户是一样的。如何从候选集中给两位用户进行推荐呢?
- 针对用户1,要给他推威海、杭州或者三亚。
为什么要给他推威海?因为用户既然去威海,并且在去威海之前,去了青岛,存在明显的时空周期性。假设用户上一年去了青岛、威海,今年又去了青岛,下个阶段是不是也会去威海,具有明显的一个时空周期性。
为什么要推杭州?因为用户也有可能要返程,从杭州出发,最终返回杭州。
为什么要推三亚?因为三亚和青岛、威海,都是一些比较相似的海岛城市。体现出用户潜在目的是对沿海城市或者海滩城市比较感兴趣。为了保证推荐的公平性或者新颖性,就会给用户推荐一些沿海或者是沙滩城市。
- 针对用户2,给他推成都、青海、西安和北京。
为什么要推成都?用户去过重庆,肯定要给推成都。
为什么要推青海,通过分析用户行程。重庆、丽江、大理、西藏,这样的行程明显属于川藏线的旅游路线。用户去了西藏之后,按照大部分人的行为连续性,该用户下一站大概率会去青海,或者直接返回北京,返程行为。
以上就是线上解决的一些case。
下面详细讲解如何优化。
我们基于DIN模型设计了 G-PDIN 模型,改善的模块为右侧模型架构图中红色的部分,主要包括:局部兴趣捕捉模块、周期兴趣捕捉模块和潜在用户意图的捕捉模块,最后会和目标 item 进行特征计算。
接下来详细展开介绍这 3个模块。
- 注意力单元计算
传统的DIN模型会直接做一个特征Embedding 相乘再相加的注意力机制。G-PDIN 不同,是用一个基于元路径学习的方式。如上图左侧,灰点是用户,黄点是用户出发城市,紫色点为用户到达城市,通过建模异构图,并定义一些Mentfast,来捕获用户的长Trigger。
构建好图并定义好元路径之后,把上文中提到的空间图和热门城市图,也会经过一个 Graph SAGE 进行一个特征提取。特殊提取完之后,就可以得到出发地城市和到达地城市的表征信息。通过把这些表征信息做叉乘,就可以计算出 OD 的相似度。
如图所示,举例说明:User1 去了昆明、重庆和成都;User2 去了三亚、青岛和厦门。候选集给User1 推荐的大理,因为大理和昆明,重庆,成都无论在地理相关性上,还是在二部图上,都有很高的相关性。User2 推荐的是威海和大连,因为捕捉用户去三亚、青岛和厦门这些沿海城市,而且推荐的城市离青岛比较近。
- 用户潜在意图捕捉模型
借鉴了Hinton教授的胶囊网络,进行特征的聚类。把这种思想用到用户的点击序列当中,每个用户的点击序列,每一个城市Embedding之后,经过CapsuleNet胶囊网络+Attention,将这些城市聚为 n 类,代表着用户是否是归乡或者工作旅游。
上文提到的Swing改进算法所对应的 8 个意图,这里也会把 8 个意图进行聚类,再经过多头注意力机制,进行意图融合,将最终得到的Embedding concat 到其它的表征信息中,进行后面的训练。
- 周期性的行为捕捉模块
借鉴了 CNN 图像领域的空洞卷积的思想,对春节、国庆、中秋等一些节假日进行处理。在数据分析时,我们发现平均每个用户的点击行为不会超过两三次,所以把 2 或者 3 做一个step,进行节点跳跃,对节点进行信息聚合,再通过多头注意机制生成最终的 Emending 表征。通过这种方式去模拟用户周期新行为捕捉。
这三个模块做完之后进行 Contact,后面的模式就和 DIN 模型一样的了。
离线训练,是以 DIN 模型作为基线,在数据集上AUC 为0. 8。如果加入图注意机制,还有周期性、潜在意图捕捉模块,AUC提升到了0. 83,绝对值提升了 3 个点左右。线上进行了 10 天左右的A/B测试,整体来看无论在 pvctr 还是uvctr,都有一个点的提升。
03/思考与总结
最后,对过去的工作和未来的工作方向进行一个总结。
首先是对近期工作的思考:
- 在召回方面
主要是基于Swing模型开发了一个 IC (Intention Capture Swing)索引Recall, IC 索引就是去捕捉用户的潜在意图。
- 在排序方面
a.基于多任务学习,主要是一步一步添加了空间图,热门城市图,不同级别的子任务模块,还有 LSTM 模块和 GRU 模块。
b.基于DIN 模型,逐步去添加了一些局部兴趣提取,周期性提取,潜在意图捕捉,预训练的 GNN模型,去计算 OD 的相似度,
对于未来的工作方向,主要会考虑超长历史行为序列层次建模,时空序列整体建模,以及元学习和跨域学习。
具体而言,比如三亚/厦门的用户,在 09 年去了三亚, 20 年去了厦门, 21 年去了三亚, 22 年又去了厦门,那23年更应该给该用户推三亚,因为用户存在明显的周期性,而且用户序列比较长。如何建模这种序列,下一步的思考就是把这些序列建模成时空图,用时间和空间图去进行一个抽象建模。
另外,还会考虑元学习和跨域学习,做冷启动或者其他方面的策略。因为用户乘坐飞机的行为可能比较少,但是乘坐火车/高铁等场景的行为比较多,可以利用跨域学习追踪做一些冷启动的策略。
04/问答环节
Q1:G-PDIN模型是否已经发表论文?
A:论文还未发表,现在已经线上实践并离线评估,效果比较好,后续可能会写一下论文。
Q2:GAT 节点用了什么特征?
A:GAT模块特征用得比较少,只用了城市,城市所在GeoHash,是否为热门城市等,这些基本的属性特征,没有用POI 或者维经纬度的其它特征。
Q3:推荐热门航线是否能够带来明显贡献?
A:这个是能的。因为人们在旅行前,大多数是不知道去哪里,会被小红书等一些App的城市推荐影响心智。
Q4:请详细展开讲讲长序列模型?
A:我们做的主要是去模拟时空序列,通过对每一年、每一个月单独进行序列建模,然后分层次,像 2022年12个月 2022就是 1* 12,叠正一个矩阵,对矩阵做一个时空图的特征抽取。
Q5:出行意图模型是否有单独输出?
A:没有,因为这是一个端到端的交叉网络,训练时会直接输出Embedding,并把表征连接到用户的特征信息上。
Q6:时间信息是怎么用的?
A:如刚才所讲的,会叠成一个矩阵进行特征抽取。目前线上用的是这种方式,引用时间信息,通过矩阵或矩阵的敞口宽去代表一个时间信息。因为出行需求预测和传统的交通流量预测不太一样,交通流量预测每时每刻都不一样。但旅游行为数据比较稀疏,而且周期比较长,所以以月为单位,比较合理。如果以每秒或者每小时做切分,不太合理,会非常稀疏,得到的矩阵基本全都是0。
今天的分享就到这里,谢谢大家。