小广告
(欢迎大家关注我的公众号“一懂算法”,之后将在公众号上持续记录本人从非科班转到算法路上的学习心得、笔经面经、心得体会。未来的重点也会主要放在机器学习面试上!)
A Taxi Order Dispatch Model based On Combinatorial Optimization /基于组合优化的出租车订单调度模型
论文来源
- https://dl.acm.org/doi/pdf/10.1145/3097983.3098138
- KDD cup
- 滴滴团队
- 中文参考:https://baijiahao.baidu.com/s?id=1575765326502914&wfr=spider&for=pc
- 辅助资料:https://blog.csdn.net/DiDi_Tech/article/details/100806477
摘要
- 背景:打车软件很流行方便,其中调度系统尤为关键
- 传统方法及不足:传统的调度系统按顺序向乘客调度车辆,目的是最大化每个订单的司机接受率。但是这样会导致整体成交率(global success rate)低,降低用户体验
- 改进1:提出了新的调度系统,目的是最大化整体成交率,优化整体的旅行效率,提高用户体验。
- 改进2:提出了一种用户目的地预测算法,该算法基于用户过去的旅行记录,利用贝叶斯框架对其目的地分布进行建模。
- 结果:在北京区域的数据上基于A/B tests和SOTA模型进行了对比,整体成交率从80%提高到了84%。在用户等待时间和上车距离上也得到了很大提升。对于目的地预测算法,前三准确率从89%到了93%。
1 引言
调度部分
- GPS+4G发展的好,轨迹数据越来越多,提供了一个构建智能实时决策系统的机会,包括旅客查找、出租车需求预测、路径规划、派单算法。
- 调度算法很重要且核心。过去的算法主要是通过为每一单找距离最近或者行驶时间最短的司机。这些方法的缺点在于它们只考虑最适合当前这一单的司机,却不考虑这个司机是否更适合别的订单。(个人理解:比如说在乘客1的左右两边分别有A车和B车。乘客2也在乘客1的右边。假设A车和B车到乘客1的距离差不多,但是B车要近一点点,如果乘客1先打车的话,那么B车就很有可能就直接被派给乘客1了,然后乘客2就只能打到A车了,但是这样显然就太远了,没有更好的利用资源。理想的当然是乘客1上A车,乘客2上B车)因此这些方法不能保证所有订单的全局行驶时间最短。一些作者基于多代理架构提出了一种叫做NTuCab的新模型。他们为了最小化全局的等车时间或者接驾时间,他们将每一个代理视为一个计算单元。每个计算单元处理N个司乘匹配对,每个订单只分配给一个司机。如果匹配的司机不接受订单,则将订单分派给另一个司机。(没有很明白NTuCab模型)
- 上述方法的缺点在于调度时间长、成功率低,因为它们都没有优化全局成功率。滴滴的场景下,每秒的司乘匹配量很大,因此订单的全局成功率很重要。
- 本文提出了一种新的组合优化模型来解决滴滴出行的订单调度问题。在这个模型中,我们将一个订单分派给几个司机,目标是最大化这些订单的总成功率。当多个司机收到同一个订单时,谁接的快给谁。如果订单未被接受,它将进入下一轮配送,直到被接受或取消。
目的地预测部分
- 调度系统中有三要素:出发时间、起点和终点。通常,可以选取当前时间和司机位置作为出发时间和起点,这适用于大部分叫车场景。但是不同的人会去不同的地点,甚至同一个人,在不同的出发时间和起点的情况下,终点也可能不同。因此,要让用户每次都要把目的地的全程输出来很麻烦。所有如果APP能提前预测好用户要去哪儿的话,就很方便。目前大部分的方法使用所有用户的轨迹数据来训练模型,然后使用当前行程的信息,结合一些辅助信息,例如时间、交通条件等来预测预定的当前目的地。
- 一个非常经典的方法基于了多层感知机,以用户的初始轨迹信息以及驾驶员id、用户信息、出发时间等作为输入。经过训练后,它可以预测大部分行程。但是该模型不太依赖于problem specific information
that can be derived from the data(啥意思?)。它在很大程度上取决于旅程的初始连续轨迹数据,一旦这部分没了,那么预测精度就会大大降低。还有一种方法使用了驾驶员自己的历史行程数据来训练HMM模型。该模型把一天的时间分成几个主观部分,如早晨、中午和晚上,这种处理方式破坏了时间的连续性。 - 过去的这些方法并不适合于滴滴出行的目的地预测问题,因为滴滴出行需要到达用户打开APP后很快就出预测结果的效果,然而当前行程的轨迹数据并不能很快获取(这里指的是用户过去很长时间的轨迹数据呢还是指打开APP前那点很短的轨迹数据呢?)。此外,与大多数以前试图最小化预测目的地和实际目的地之间的距离的方法不同,我们的目标是确定用户想要去的确切目的地。事实上,即使预测的目的地是真实目的地的别名,乘客也可能把它当作不熟悉的目的地,然后重新输入目的地。因此我们的系统将用户的历史目的地当作候选集。每个人的个人历史行程统计差别都很大。拿2015年为例,对于至少使用过一次滴滴出行的用户来说,每个用户每年的出租车预约使用量约为二十次。但是分布不均匀,高频用户每天打开APP,低频用户一年打开APP不到十次。从这种稀疏的数据中获得准确的个人统计数据是一项重大挑战。
- 经过对滴滴数据的观测分析,研究提出了基于贝叶斯决策的目的地预测模型,该模型考虑了三元高斯分布下的出发经度、纬度和出发时间。利用个人行程数据进行训练,训练好的模型可以根据出发经度、纬度和出发时间计算用户历史目的地的概率,然后按概率排序给出一个预测排行。
2 派单系统
-
本研究的目标就是最大化派单成功率。
-
假设有N单,M个司机,那么可以把派单表示成一个矩阵:
( a 11 ⋯ a 1 M ⋮ a i j ⋮ a N 1 ⋯ a N M ) , where 1 ≤ i ≤ N , 1 ≤ j ≤ M and a i j = { 1 order i is dispatched to driver j 0 order i is not dispatched to driver j \begin{array}{l} \left(\begin{array}{ccc} a_{11} & \cdots & a_{1 M} \\ \vdots & a_{i j} & \vdots \\ a_{N 1} & \cdots & a_{N M} \end{array}\right), \text { where } 1 \leq i \leq N, 1 \leq j \leq M \\ \text { and } a_{i j}=\left\{\begin{array}{ll} 1 & \text { order } i \text { is dispatched to driver } j \\ 0 & \text { order } i \text { is not dispatched to driver } j \end{array}\right. \end{array} a11⋮aN1⋯aij⋯a1M⋮aNM , where 1≤i≤N,1≤j≤M and aij={10 order i is dispatched to driver j order i is not dispatched to driver j
在该场景下,假定每个司机一轮只能接收到一个订单,但是一个订单可以派给多个司机,该约束的数学形式为: ∀ j , ∑ i = 1 N a i j ≤ 1 \forall j, \sum_{i=1}^{N} a_{i j} \leq 1 ∀j,∑i=1Naij≤1 -
在滴滴的业务场景中,一个订单被分派给多个司机,每个司机根据自己的喜好决定是否接受。对于每个订单,是否被其中一个司机接受,直接取决于每个司机接受的概率。因此,订单调度的关键问题是估计每个司机接受订单的概率。如果我们可以估计出每个司机对每个订单的接单概率,那么我们就可以得出每个订单能够被司机接单的概率。因此我们将订单调度模型分为两个子模型:
- 一个模型预测司机行为,也就是司机接受每个订单的概率。
- 另一个模型使用接受概率来制定一个使目标收益最大化的优化问题,然后解决底层的优化问题。
2.1 司机行为预测模型
- 由于司机只有接收和拒绝两种行为,因此用0-1变量y来表示行为,1接收,0拒绝。并假设司机行为独立同分布。
- 利用
p
i
j
p_{ij}
pij来表示订单
o
i
o_i
oi被司机
d
i
d_i
di接收的概率。概率取决于很多因素,比如订单价值、行驶距离、方向等。这些信息可以编码为一个特征向量
x
i
j
\textbf{x}_{ij}
xij,对应订单
o
i
o_i
oi被司机
d
i
d_i
di。给定
x
i
j
\textbf{x}_{ij}
xij,则估计的接收概率如下:
p i j = p ( y = 1 ∣ x i j ) p_{ij}=p(y=1|\textbf{x}_{ij}) pij=p(y=1∣xij)
这是一个典型的二分类问题,可以利用历史订单-司机对产生的特征来进行训练。 - 研究中,他们尝试了LR和GBDT。不同城市分别训练。评价指标采用了准确率(ACC),AUC,召回率(Sensitivity),Specificity(所有负例中被预测为负的比例,和召回率相对应)。
- 结果如论文中表一所示,在他们的数据上,LR表现更好些,因此采用了LR模型:
p i j = p ( y = 1 ∣ o i , d j ) = 1 exp ( − w T x i j ) p_{i j}=p\left(y=1 \mid o_{i}, d_{j}\right)=\frac{1}{\exp \left(-\mathbf{w}^{\mathrm{T}} \mathbf{x}_{i j}\right)} pij=p(y=1∣oi,dj)=exp(−wTxij)1
疑问:难道不应该是下面的吗
p i j = p ( y = 1 ∣ o i , d j ) = 1 1 + exp ( − w T x i j ) p_{i j}=p\left(y=1 \mid o_{i}, d_{j}\right)=\frac{1}{1+\exp \left(-\mathbf{w}^{\mathrm{T}} \mathbf{x}_{i j}\right)} pij=p(y=1∣oi,dj)=1+exp(−wTxij)1 - 优化器选择:随机梯度下降(SGD)
- 特征选择(值得学习!):
- “订单-司机对”特征:接驾距离、每轮订单向司机的传播数量。
- 订单相关特征:订单距离和预估到达时间,目的地类型,路线上的交通状况,该目的地历史订单频率
- 司机端特征:长期行为(司机的历史接收率、司机的活跃区域、对不同广播距离的喜好?),短期兴趣(最近是否接收订单)
- 补充特征:周几、几点、附近订单和司机数量
2.2 组合优化方法
- 由于一个订单会被派发到多个司机,假设N单M个司机,则订单
o
i
o_i
oi被接收的概率为:
E i = 1 − ∏ j = 1 M ( 1 − p i j ) a i j E_{i}=1-\prod_{j=1}^{M}\left(1-p_{i j}\right)^{a_{i j}} Ei=1−j=1∏M(1−pij)aij
a i j = { 1 order i is dispatched to driver j 0 order i is not dispatched to driver j a_{i j}=\left\{\begin{array}{ll}1 & \text { order } i \text { is dispatched to driver } j \\ 0 & \text { order } i \text { is not dispatched to driver } j\end{array}\right. aij={10 order i is dispatched to driver j order i is not dispatched to driver j
其中 p i j p_{ij} pij的定义见2.1节.
则,成功率 E S R E_{SR} ESR可表示为:
E S R = ∑ i = 1 N [ 1 − ∏ j = 1 M ( 1 − p i j ) a i j ] N E_{S R}=\frac{\sum_{i=1}^{N}\left[1-\prod_{j=1}^{M}\left(1-p_{i j}\right)^{a_{i j}}\right]}{N} ESR=N∑i=1N[1−∏j=1M(1−pij)aij]
同样存在约束: ∀ j , ∑ i = 1 N a i j ≤ 1 \forall j, \sum_{i=1}^{N} a_{i j} \leq 1 ∀j,∑i=1Naij≤1,代表一个司机一次只能接收一单。那么派单的整体目标可以建模为:
{ max a i j E S R = ∑ i = 1 N [ 1 − ∏ j = 1 M ( 1 − p i j ) a i j ] N s.t. ∀ j , ∑ i = 1 N a i j ≤ 1 , a i j ∈ { 0 , 1 } . \left\{\begin{array}{l}\max _{a_{i j}} E_{S R}=\frac{\sum_{i=1}^{N}\left[1-\prod_{j=1}^{M}\left(1-p_{i j}\right)^{a_{i j}}\right]}{N} \\ \text { s.t. } \forall j, \sum_{i=1}^{N} a_{i j} \leq 1, a_{i j} \in\{0,1\} .\end{array}\right. {maxaijESR=N∑i=1N[1−∏j=1M(1−pij)aij] s.t. ∀j,∑i=1Naij≤1,aij∈{0,1}.
这是一个约束组合优化问题。 - 许多组合优化问题都是NP hard的,在多项式时间内无法解决。一种典型的方法是使用启发式算法来寻找近似解。常用的方法有爬山法、遗传算法、模拟退火算法等。考虑精度和性能的平衡,他们选择了爬山法。
- 爬山法在该问题上的应用过程如下(已知司机接收订单概率矩阵,大小:N单*M司机):
- 利用矩阵D(大小:M*1)来记录分给每个司机的订单编号,然后先用对该司机接单概率最大的订单编号进行初始化:对概率矩阵P的每一列,找最大值对应的位置即可
- 利用矩阵E(大小:N*1)来记录每一单能够被成功接收的概率:对于每一行采用2.2节的第一个公式。
- 遍历每个订单编号i:
- 统计没有被分配到订单i的司机编号,汇总为U
- 遍历U中的每个司机编号k:
- 如果把订单i派发给司机k能够增加E0(全局平均成功率),那就把订单i派给司机k(也就是将D[K]对应的值换成k)
- 更新订单i的成功率
- 更新全局平均成功率
3 目的地预测算法
通过对滴滴过往数据进行挖掘,发现了几个有趣的模式:
- 同一用户倾向于在相似的时间前往相同的目的地。具体的,出发时间是目的地预测的最重要因素,其次才是出发经纬度。有意思的是,可以利用工作日和节假日来将数据分为两组:工作日的目的地集中在家和工作场景,节假日则集中在购物商场和娱乐场所等。
- 同一用户倾向于去同一组地点,即使是周末的购物场所,除了偶尔的紧急情况,如医生预约,商务旅行等。
- 订单的发起位置也提供了很有用的信息。
- 其它的比如驾驶员信息、交通情况、驾驶速度等则与目的地预测的相关性不大。
基于上述规律,作者使用了使用贝叶斯规则对用户目的地的概率分布进行建模。
3.1 模型描述
- 首先定义相关符号描述:1)T:出发时间[0,24) 2) D:工作日还是节假日 3)Lng:纬度[-180,180] 4) Lat:经度 5) Y:用户的历史目的地集合{y1,y2…yn}
- 观察到D只有两个类别,所以作者利用D用来将用户的历史数据分成两个行为非常不同的聚类,对数据进行聚类预处理。
- 除此之外还利用历史订单的时间来作为时间因子给训练数据进行加权。(作者考虑篇幅,省略了细节)
- 作者所提方法的目标就是对用户目的地的概率分布进行建模。为了达到改目的,作者采用了贝叶斯公式来表示目的地
y
1
,
y
2
,
.
.
.
,
y
n
{y_1,y_2,...,y_n}
y1,y2,...,yn的条件概率:
p ( Y = y i ∣ X ) = p ( X ∣ Y = y i ) p ( Y = y i ) ∑ j = 1 n p ( X ∣ Y = y j ) p ( Y = y j ) p\left(Y=y_{i} \mid X\right)=\frac{p\left(X \mid Y=y_{i}\right) p\left(Y=y_{i}\right)}{\sum_{j=1}^{n} p\left(X \mid Y=y_{j}\right) p\left(Y=y_{j}\right)} p(Y=yi∣X)=∑j=1np(X∣Y=yj)p(Y=yj)p(X∣Y=yi)p(Y=yi)
其中 X = ( T , L n g , L a t ) X = (T,Lng,Lat) X=(T,Lng,Lat)表示出发时间、出发经度和纬度。 - 其中,
p
(
Y
=
y
i
)
p(Y=y_i)
p(Y=yi)可利用用户的历史行程数据来估计(用频率近似概率):
p ( Y = y i ) = freq ( y i ) ∑ j = 1 n freq ( y j ) p\left(Y=y_{i}\right)=\frac{\text { freq }\left(y_{i}\right)}{\sum_{j=1}^{n} \text { freq }\left(y_{j}\right)} p(Y=yi)=∑j=1n freq (yj) freq (yi) - 对于 p ( T , L n g , L a t ∣ Y = y i ) p(T,Lng,Lat|Y=y_i) p(T,Lng,Lat∣Y=yi)后续会有更详细的介绍,接下来先解决 p ( T ∣ Y = y i ) p(T|Y=y_i) p(T∣Y=yi),然后再解决(T,Lng,Lat)的联合概率分布。
3.2 给定目的地出发时间的条件分布 p ( T ∣ Y = y i ) p(T|Y=y_i) p(T∣Y=yi)
- 论文中图一展示了目的地为三里屯的的用户出发时间直方图。可以看出近似于高斯分布。观察了其它情形,也类似。所以采用了高斯分布来估计出发时间的条件概率:
T ∣ Y = y i ∼ N ( μ i , σ i 2 ) T \mid Y=y_{i} \sim N\left(\mu_{i}, \sigma_{i}^{2}\right) T∣Y=yi∼N(μi,σi2) - 考虑到时间T是0到23的循环值,因此不能按传统方法计算平均值和方差,比如 3:00, 15:00, 21:00的平均值应该是21:00,而不是(3+15+21)/3=13
- 上述问题的常用解决方法为:将所有循环变量转换成单位向量,并计算向量的平均值,然后将结果转换回原始循环表示。给定
t
1
,
t
2
,
.
.
.
,
t
m
t_1,t_2,...,t_m
t1,t2,...,tm,则
μ
\mu
μ可以表示为:
μ = 24 2 π ⋅ arctan [ 1 m ∑ k = 1 m sin ( 2 π 24 ⋅ t k ) , 1 m ∑ k = 1 m cos ( 2 π 24 ⋅ t k ) ] \mu=\frac{24}{2 \pi} \cdot \arctan \left[\frac{1}{m} \sum_{k=1}^{m} \sin \left(\frac{2 \pi}{24} \cdot t_{k}\right), \frac{1}{m} \sum_{k=1}^{m} \cos \left(\frac{2 \pi}{24} \cdot t_{k}\right)\right] μ=2π24⋅arctan[m1k=1∑msin(242π⋅tk),m1k=1∑mcos(242π⋅tk)]
上述方法简单且直观,但是在某些情形下会出现偏差甚至计算不出结果:比如0点、0点、3点的均值应该是1点,但是上述方法会得到00:58:33。当 ∑ k = 1 m sin ( 2 π 24 ⋅ t k ) = 0 \sum_{k=1}^{m} \sin \left(\frac{2 \pi}{24} \cdot t_{k}\right)=0 ∑k=1msin(242π⋅tk)=0或者 ∑ k = 1 m cos ( 2 π 24 ⋅ t k ) = 0 \sum_{k=1}^{m} \cos \left(\frac{2 \pi}{24} \cdot t_{k}\right)=0 ∑k=1mcos(242π⋅tk)=0时,则无法得到结果。 - 针对上述方法的缺点,作者提出了新的处理时间变量的方法。出发时间的均值可以通过求解以下约束二次优化问题获得:
{ min μ ∑ k = 1 m [ distance ( t k , μ ) ] 2 s.t. μ ∈ [ 0 , 24 ) \left\{\begin{array}{l}\min _{\mu} \sum_{k=1}^{m}\left[\operatorname{distance}\left(t_{k}, \mu\right)\right]^{2} \\ \text { s.t. } \mu \in[0,24)\end{array}\right. {minμ∑k=1m[distance(tk,μ)]2 s.t. μ∈[0,24)
简单说就是找到一个时刻距离所有时刻的时间差的和最小。其中, d i s t a n c e ( t 1 , t 2 ) distance(t_1,t_2) distance(t1,t2)表示循环变量 t 1 t_1 t1和 t 2 t_2 t2之间的距离,可表示为:
d i s t a n c e ( t 1 , t 2 ) = { ∣ t 1 − t 2 ∣ if ∣ t 1 − t 2 ∣ ≤ 12 24 − ∣ t 1 − t 2 ∣ if ∣ t 1 − t 2 ∣ > 12 distance \left(t_{1}, t_{2}\right)=\left\{\begin{array}{ll}\left|t_{1}-t_{2}\right| & \text { if }\left|t_{1}-t_{2}\right| \leq 12 \\ 24-\left|t_{1}-t_{2}\right| & \text { if }\left|t_{1}-t_{2}\right|>12\end{array}\right. distance(t1,t2)={∣t1−t2∣24−∣t1−t2∣ if ∣t1−t2∣≤12 if ∣t1−t2∣>12
或
distance ( t 1 , t 2 ) = − ∣ ( ∣ t 1 − t 2 ∣ − 12 ) ∣ + 12 \operatorname{distance}\left(t_{1}, t_{2}\right)=-\left|\left(\left|t_{1}-t_{2}\right|-12\right)\right|+12 distance(t1,t2)=−∣(∣t1−t2∣−12)∣+12
(意思就是两个时间相差不会超过12小时)
最终可以表示为:
{ min μ ∑ k = 1 m [ ∣ ( ∣ t k − μ ∣ − 12 ) ∣ − 12 ) ] 2 , s.t. μ ∈ [ 0 , 24 ) . \left\{\begin{array}{l} \left.\min _{\mu} \sum_{k=1}^{m}\left[\left|\left(\left|t_{k}-\mu\right|-12\right)\right|-12\right)\right]^{2}, \\ \text { s.t. } \mu \in[0,24) .\end{array}\right. {minμ∑k=1m[∣(∣tk−μ∣−12)∣−12)]2, s.t. μ∈[0,24).
方差可以表示为:
σ 2 = 1 m − 1 ∑ k = 1 m [ ∣ ( ∣ t k − μ ∣ − 12 ) ∣ − 12 ] 2 \sigma^{2}=\frac{1}{m-1} \sum_{k=1}^{m}\left[\left|\left(\left|t_{k}-\mu\right|-12\right)\right|-12\right]^{2} σ2=m−11k=1∑m[∣(∣tk−μ∣−12)∣−12]2
3.3 给定目的地下出发时间、出发经纬度的联合条件分布
- 大部分用户,利用出发时间就可以较为准确的预测出目的地,如论文中图2。
- 但是对于部分用户(老在相似时间段去不同地方),还是得结合更多的信息来进行更准确的预测,如论文中图3
- 结合时间和经纬度往往能很好的预测出目的地,如图4
- 经过研究分析,发现高斯三元分布能够很好的表示其联合分布:
L a t , L n g , T ∣ Y = y i ∼ N 3 ( μ i , Σ i ) Lat, Lng,T \mid Y=y_{i} \sim N_{3}\left(\boldsymbol{\mu}_{i}, \Sigma_{i}\right) Lat,Lng,T∣Y=yi∼N3(μi,Σi)
3.4 目的地预测的完整步骤
- 对每个用户,预估其每个候选目的地的均值和方差
- 计算
p
(
Y
=
y
i
)
p(Y=y_i)
p(Y=yi):
p ( Y = y i ) = freq ( y i ) ∑ j = 1 n freq ( y j ) p\left(Y=y_{i}\right)=\frac{\text { freq }\left(y_{i}\right)}{\sum_{j=1}^{n} \text { freq }\left(y_{j}\right)} p(Y=yi)=∑j=1n freq (yj) freq (yi)
然后利用3.3节中的三元高斯分布公式来计算 p ( T , L n g , L a t ∣ Y = y i ) p(T,Lng,Lat|Y=y_i) p(T,Lng,Lat∣Y=yi) - 利用贝叶斯公式计算
p
(
Y
=
y
i
∣
T
,
L
n
g
,
L
a
t
)
p\left(Y=y_{i} \mid T,Lng,Lat\right)
p(Y=yi∣T,Lng,Lat)
p ( Y = y i ∣ T , L n g , L a t ) = p ( T , L n g , L a t ∣ Y = y i ) p ( Y = y i ) ∑ j = 1 n p ( T , L n g , L a t ∣ Y = y j ) p ( Y = y j ) p\left(Y=y_{i} \mid T,Lng,Lat\right)=\frac{p\left(T,Lng,Lat \mid Y=y_{i}\right) p\left(Y=y_{i}\right)}{\sum_{j=1}^{n} p\left(T,Lng,Lat \mid Y=y_{j}\right) p\left(Y=y_{j}\right)} p(Y=yi∣T,Lng,Lat)=∑j=1np(T,Lng,Lat∣Y=yj)p(Y=yj)p(T,Lng,Lat∣Y=yi)p(Y=yi) - 利用 p ( Y = y i ∣ T , L n g , L a t ) p\left(Y=y_{i} \mid T,Lng,Lat\right) p(Y=yi∣T,Lng,Lat)对候选目的地进行排序,得到一个推荐列表。