流量调控

流量调控业务就是通过算法/策略/系统的设计和优化,构建平衡平台利益和长期价值的流量分发系统。

为什么要做流量调控

目的1:促进发布,增大内容池

  • 新内容获得的曝光越多,作者创作积极性越高。

  • 反映在发布渗透率、人均发布量。

目的2:挖掘优质内容

  • 做探索,让每篇新内容都能获得足够曝光。

  • 挖掘的能力反映在高热内容占比。

目的3:辅助商业化

  • 以流量调控技术为手段,达到低成本撬动商家优质资源,实现平台、商家、用户三方共赢

  • 帮助商家“甩货”,控制由库存积压、商品过期等原因导致的成本损失

  • 广告变现

流量调控的手段

  • 在推荐链路中,干涉召回、重排等环节

  • 在指定时间段内,提升指定商品集合的某种行为类型次数绝对值,如: 曝光pv绝对值、点击量绝对值

  • 支持两种调控类型

    • 保量:规定时间段内,单位时间(如,每天)的流量至少为设定值,实际流量可以超过设定值

    • 逼近:规定时间段内,单位时间(如,每天)的流量逼近设定值,不会大幅超过设定值

流量调控系统的参考评价指标

  1. 作者侧指标(反映作者的发布积极性)

    • 发布渗透率=当日发布人数/日活人数

    • 人均发布量=当日发布内容数/日活人数

  2. 用户侧指标

    • 调控内容指标:调控内容的点击率、交互率等

    • 大盘指标:消费时长、日活、月活

  3. 内容侧指标

    • 高热内容占比(衡量系统挖掘优质内容的能力)

    • 调控目标达成度

PaiRec流量调控解决方案

solution

方案优势:

  • 扶持效果好:“流量调控”是基于PaiRec推荐系统架构而开发的流量干预功能,在不扰乱推荐系统整体推荐逻辑的基础上对所选物品池进行精准流量干预。

  • 效果可量化:与传统的“加权”方式相比,“流量调控”功能以物品池的曝光次数、曝光次数占比等可量化的指标为调控的目标,更容易实现定量扶持;

  • 易于管理:“流量调控”以任务为功能单元实现业务诉求,针对不同种类的流量干预需求可以建立不同的“流量调控”任务,这种方式便于灵活管理,您可以随时新建或结束一个任务。

  • 操作简单:您只需要新建并配置任务目标等信息,系统将根据您的配置自动干预流量的分发,不需要您持续观察和监测;

流量调控系统交互流程

framework

【PaiRec】调控算法需要三个输入:

  1. item属于哪些调控计划

  2. 每个调控计划目前为止的累计流量(占比)

  3. 每个调控计划当前时刻的设定目标

对于第一个输入(item属于哪些调控计划):

  1. 调用SDK,从Meta Server获取所有在线的调控计划及目标的meta信息;

  2. 查询Hologres,获取item的属性数据;

  3. 遍历调控计划,根据调控计划的物品筛选条件以及item属性判断物品从属的调控计划集合;

对于第二个输入(每个调控计划目前为止的累计流量/占比)

  1. 调用SDK,获取每个计划 (或计划内物品) 的累计流量;

  2. 若调控目标为流量占比,同时通过SDK从DB中获取“限制物品集”的整体累计流量,计算流量占比;

  3. 各计划的实时累计流量为flink任务通过http服务实时写入DB

    • flink job通过http服务获取当前在线调控计划的meta信息;

    • 通过调控计划的meta信息判断item属于哪些调控计划;

    • 统计每个调控计划当天到目前为止的累计流量,并通过http服务写入DB

对于对三个输入(每个调控计划当前时刻的设定目标)

  1. 对于调控目标为流量占比的计划,每个时刻的目标记为设定的目标(daily or hourly)

  2. 其他类型的调控目标,在MaxCompute上做好计划的小时级/30分钟级流量预估,并等比例设定每个时刻的调控目标

  3. DataWorks上获取调控计划meta信息;设定目标;通过http服务更新到meta server

流量调控算法

PID 调控算法

PID 是比例(P)、积分(I)、微分(D) 控制算法,是一种基于反馈控制原理的控制算法,用于控制和调节系统的输出。 它的基本原理是通过比较系统的实际输出与期望输出之间的误差,根据控制算法计算出相应的控制量,从而调节系统输出。 它可以有效地控制系统的输出,使其朝着指定的期望输出进行调节。

PID 控制算法的主要步骤如下:先计算系统的误差,然后根据控制算法计算出相应的控制量,最后将控制量应用到系统中,从而改变系统的输出,使其朝着期望输出进行调节。

PID

PID算法在\(t\)时刻的输出为:

\[ u(t)=K_P \left( e(t) + \frac{1}{T_I}\int_0^t e(t)dt + T_D\frac{de(t)}{dt} \right) \]

其中,\(K_P\)为比例增益;\(T_I\)为积分时间常数;\(T_D\)为微分时间常数;\(u(t)\)为控制量(控制器输出); \(e(t)\)为被控量与给定值的偏差。

为了便于实现,需要将上式变成差分方程。假设 \(T\) 为采样周期,\(k\) 为采样序号,我们作如下近似:

\[\begin{split} \begin{cases} \int_0^t e(t)dt & \approx \sum_{i=0}^k Te(i) \\ \frac{de(t)}{dt} & \approx \frac{e(k)-e(k-1)}{T} \\ \end{cases} \end{split}\]

将近似表达式代入PID公式,得

\[ u(k)=K_Pe(k) + \frac{K_PT}{T_I}\sum_{n=0}^ke(n) + \frac{K_PT_D}{T}(e(k)-e(k-1)) \]

其中,积分系数:\(\frac{K_PT}{T_I}\) 可以用\(K_I\)表示; 微分系数:\(\frac{K_PT_D}{T}\) 可以用\(K_D\)表示;

这样PID公式可以改写为:

\[ u(k) = K_Pe(k) + K_I \sum_{n=0}^k e(n) + K_D(e(k)-e(k-1)) \]

PID 控制算法的三个参数(\(K_P\)\(K_I\)\(K_D\))的变化可以改变系统的控制性能。

  • \(K_P\) 参数控制系统的响应速度,能迅速反映误差,从而减小误差,但比例控制不能消除稳态误差,\(K_P\)的加大会引起系统的不稳定;

  • \(K_I\) 参数控制系统的抗扰性,只要系统存在误差,积分控制作用就不断地积累,输出控制量以消除误差。因此只要有足够的时间,积分控制将能完全消除误差,但是积分作用太强会使系统超调加大,甚至使系统出现振荡;

  • \(K_D\) 参数控制系统的稳定性,可以减小超调量,克服振荡,使系统的稳定性提高,同时加快系统的动态响应速度,减小调整时间,从而改善系统的动态性能。

PID算法的调参方法请参考:《 流量调控PID算法调参指南 》。

流量平滑

任何流量调控算法或策略或多或少都会对大盘的短期业务指标造成一定的负面影响(除非推荐算法本身还有很大的提升空间)。 这里我们假设原有的推荐算法是一个完美的算法,它推出的物品集合以及物品之间的排序都是最优的,任何变动都会造成短期业务指标的下跌。

PID算法只能保证调控目标的达成,但本身并没有办法把对大盘业务指标的负面影响控制在一定范围内。 因此,在PID算法之上还需要加入各种流量平滑的策略和机制,来尽可能减少调控带来的负面影响。

我们采用的流量平滑策略包括但不限于:

  1. 个性化调控。根据用户对调控物品的偏好程度调控,尽可能把调控流量分配给确实需要的用户。

  2. 动态拆解阶段性调控目标值。渐进式达成全天的目标,在时间上平滑。根据预估流量,非线性地设置每个时刻的调控目标。

  3. 打散约束。每个请求仅能承载有限数量的调控上提物品,并且曝光位置不能过于集中。

  4. 目标松弛变量。针对流量占比型任务,不需要每时每刻都干预系统使其逼近目标,而是利用一旦不干预就慢慢恢复自然状态的原理,在时间上仅在必要的时候才干预系统。

    • 例如,鞋类的自然流量占比超过目标值40%,流量调控过程中流量降低到目标值40%以下时,不是立马就开始给鞋类提权,而是在可控范围内停止干预,无为而治;一段时间后流量会慢慢恢复到40%。

    • 类似于汽车的ABS防抱死制动系统,采用”点刹”,而不是全程制动。

调控公式

为了使得PID算法的调参经验能够更好地在不同场景间迁移,我们没有采用常规的对排序分进行加权/降权的方式,而是采用了直接调整排序位置的策略。

假设展示位置调整量为 \(\Delta rank\),那么

  • \(new\_rank=old\_rank-\Delta rank\)

  • sort by \(new\_rank\) (可能是负值)

\(\Delta rank\) 的计算公式如下:

\[\begin{split}\Delta rank(t, i)= \begin{cases} \alpha_t \cdot (1+\gamma tanh(\beta w_t)) \cdot e^{score_i/max\_score}, & \text{if $\alpha_t>0$, uplift} \\ \alpha_t \cdot \left[ 1/({1+e^{10-r_i \eta\cdot (1-tanh(w_t))}}) \right], & \text{if $\alpha_t<0$, pull down} \end{cases} \end{split}\]

其中,\(t\) 对应一个调控目标;\(i\) 对应一个item;\(score_i\)是item \(i\) 的模型得分;\(max\_score\)是得分最高的item的模型分;

\(r_i\) 是按照模型分降序排列得到的rank位置;\(\alpha_t\) 的PID算法输出的调控信号;

\(w_t\)是调控目标 \(t\) 的权重,反应当前用户对当前调控目标商品合集的总体偏好程度,其计算公式如下:

\[w_t=\frac{\sum_{i \in t} score_i \cdot e^{-0.01r_i}}{\sum_i score_i \cdot e^{-0.01r_i}}\]

最终的调控位置偏移值的计算:

\[\Delta final\_rank(i)=\sum_t \Delta rank(t, i)\]

eq

阶段性细粒度拆解调控目标

阶段性拆解目标指调控任务在执行过程中,每个时刻 \(t\) 需要去逼近的目标,是一个关于时间以及daily总目标\(T\)的函数 \(f(t, T)\)

PID调控算法中最重要的计算差分的环节就需要计算当前时间的累计流量与目标流量的差值。然而,我们只会设置一段时间(如,每天)的总目标 \(T\), 总目标是这段时间累计需要达成的目标,在调控过程中的任意时刻直接去逼近总目标是有问题的,会使得算法急于达成目标,影响大盘效果。 比如,试图在一天刚开始不久时就达成一整天的目标是不合理的。

每个时刻算法只需要去逼近总目标的一部分就行了,那么该如何为当前时刻设置一个合理的目标值呢?

  • 线性分解:总目标在时间上均匀切分。

    • 优点:实现简单;

    • 缺点:与流量的自然分布不匹配;存在部分时间段调控比较激进,部分时间段调控比较慵懒的问题;

\[f(t, T)=\frac{t-t_{min}}{t_{max}-t_{min}}\cdot T\]
  • 非线性分解:总目标在时间上不均匀切分。

    • 尽量去匹配流量随时间的自然分布

\[f(t, T)=\frac{\hat{C}_t}{\sum_i \hat{C}_i}\cdot T\]

其中,\(\hat{C}_t\) 是预估的当天从零点到 \(t\) 时刻的累计流量。 如何预估各个时刻的累计流量参考下一小节。

流量预估模型

调控系统十分依赖输入的流量调控目标,如果输入给调控系统的流量调控目标不合理,会极大的提升调控的难度。 因此,在进行流量调控前,需要得到合理的流量调控目标。

目的:

  • 辅助判断调控目标是否合理

    • 过高的目标可能会导致目标无法达成;同时也会造成大盘指标下降,以及对内容产生拔苗助长的效应

    • 调控任务的 自然流量在大盘的占比 vs 目标流量在大盘的占比

      • if 目标流量在大盘的占比/自然流量在大盘的占比 > threshold, then 判断目标不合理

  • 细粒度拆解调控目标,得到每个时间段的子目标

    • 流量调控目标需要在时间上做到平滑,步调太大会影响大盘指标和用户体验

    • 大盘流量在时间上并不是均匀分布;e.g. 深夜流量少

    • 内容流量在时间上也不具有一致性;e.g. 成人用品的流量基本都集中在夜里

步骤:

  1. 以(半)小时为单位,构建模型预估每个item (or item pool)在每个时间段的自然流量 \(\hat{C}_t\)

  2. 以(半)小时为单位,计算每个时间段的预估自然流量占比 \(ratio_h=\frac{\hat{C}_h}{\sum_t \hat{C}_t}\)

  3. 计算每(半)个小时流量调控目标:\(target_h=ratio_h \cdot SetPoint\)

  4. 在每个时间段内部采用线性分解的方法得到每分钟的拆解目标值

提示

这里的流量不一定是指曝光流量,也可能指IPV,或者GMV等。

用户手册

参见

请查看 《 流量调控用户手册 》。