它想解决什么问题?
为了让搜索页快速打开,平台展示的机票价格通常来自缓存。于是可能出现这样的情况:搜索页显示 885 元,用户点进详情页后才发现低价舱已经售完,实际价格变成了 900 元。
传统排序模型主要判断用户会不会点击或购买,并默认当前价格是可靠的。这样一来,看起来最便宜、实际却很可能涨价的航班,反而容易被排到前面。
PCANet 想解决的是:
排序时不仅要考虑用户喜不喜欢,还要判断价格靠不靠谱,以及这个用户是否介意涨价。
它是怎么做的?
PCANet 包含两个核心模块。
第一个模块负责预测涨价风险。它会观察价格缓存时长、近期查询热度、低价舱余量和库存需求等实时信号,估计从搜索到下单期间可能出现的价格变化。
模型还加入了一些基本业务常识:缓存时间越长、查询需求越旺,涨价风险通常越高;剩余座位越多,涨价风险通常越低。这相当于给模型划定合理的学习方向,避免它从复杂数据中学出违反常识的关系。
第二个模块负责判断用户对涨价有多敏感。同样涨 50 元,休闲游客可能立即放弃,而商务旅客可能更在意起飞时间。模型会查看用户过去遇到类似价格变化时是继续购买还是离开,从而理解他的价格承受能力。
最后,模型把“航班涨价风险”和“用户价格敏感度”结合起来。如果某趟航班很可能涨价,而当前用户又非常介意涨价,就适当降低它的排序;如果用户并不敏感,也不会因为存在风险就简单地过滤掉这趟航班。
背后的理论与公式
第一步是明确什么叫“涨价”。设搜索页展示价为 $p_s$,进入下单页后的实际价格为 $p_b$,涨价幅度定义为:
\[\Delta p^+=\max(0,p_b-p_s)\]如果实际价格没有上涨,$\Delta p^+=0$;如果从 885 元涨到 900 元,$\Delta p^+=15$。这样处理是为了让模型集中学习会破坏用户体验的涨价,而不是把涨价和降价相互抵消。
接下来,模型根据缓存时长、查询热度和剩余库存等实时特征 $x$ 预测涨价风险 $r=f(x)$。以缓存时长为例,缓存时间越长,价格发生变化的风险通常越高。为了把这种关系写入模型,可以让相关网络权重保持非负:
\[z^{(l+1)}=\phi\bigl(W^{(l)}z^{(l)}+b^{(l)}\bigr), \qquad W^{(l)}\ge0\]如果激活函数 $\phi$ 本身单调不减,那么输出对输入的偏导为:
\[\frac{\partial z^{(L)}}{\partial x} =\prod_{l=0}^{L-1}\phi'\bigl(a^{(l)}\bigr)W^{(l)}\ge0\]等式右侧的激活函数导数和网络权重都非负,所以最终偏导也不会小于 0。这就保证了缓存时长或查询热度增加时,模型预测的风险不会下降。对于剩余座位这类方向相反的特征,则设置反向单调约束,使余票增加时预测风险不会上升。
但仅有涨价风险还不够,因为不同用户对同样的涨幅反应不同。模型会用当前风险 $r$ 去匹配用户过去的价格相关行为 $e_t$:
\[\alpha_t=\frac{\exp(g(r,e_t))}{\sum_k\exp(g(r,e_k))},\qquad h_{\text{sens}}=\sum_t\alpha_t e_t\]如果用户过去某次经历的涨价幅度与当前情况相似,它就会获得更大的 $\alpha_t$。由历史行为汇总得到的 $h_{\text{sens}}$,可以进一步转成用户敏感度 $a_u$。最终排序校准可以简化表示为:
\[s'=s_{\text{base}}-\lambda r a_u\]$s_{\text{base}}$ 是原排序模型给出的分数,$\lambda$ 控制价格风险的影响强度。只有当涨价风险 $r$ 和用户敏感度 $a_u$ 同时较高时,扣分项 $\lambda r a_u$ 才会明显变大。如果航班可能涨价但用户并不敏感,或者用户敏感但航班价格很稳定,模型都不会过度降权。这就是 PCANet 能够实现个性化价格校准的原因。
一句话类比
PCANet 像一位懂用户的机票导购:
“这张票现在虽然便宜,但库存很少,点进去很可能涨价;这个用户以前一遇到涨价就退出,所以不适合把它放在最前面。”
效果
论文使用约 20 亿条样本训练。在飞猪国际机票的两周线上实验中,转化率相对提升约 2.4%,在线推理延迟保持在 30 毫秒以内。