外观
多元协变量偏移
Multivariate Covariate Shift

几乎所有现实世界中的机器学习模型,都会因协变量偏移(covariate shift)而出现性能逐渐下降。
首先,所谓协变量偏移,是指特征的分布随时间发生变化,但输入与输出之间真实(自然)的关系保持不变。

这是一个严重的问题,因为模型是在一种分布上训练的,却要在生产环境(production)中对另一种分布进行预测。因此,尽早检测协变量偏移至关重要,这样模型才能持续保持良好表现。

检测协变量偏移最常用、最直观的方法之一,就是直接比较训练数据与生产环境中数据的特征分布。
这可以通过多种方式实现,例如:
- 比较它们的汇总统计量——均值、中位数等。
- 使用分布图进行可视化检查。
- 进行假设检验。
- 使用 Bhattacharyya 距离、KS 检验等来衡量训练分布与生产分布之间的距离。尽管这些方法通常有效,但最大的问题在于它们一次只能处理单个特征。然而在现实中,我们还可能观察到多元协变量偏移(Multivariate Covariate Shift,MCS)。它发生在:
- 各个特征自身的分布保持不变:
- P(X₁) 和 P(X₂) 各自保持不变。
- 但它们的联合分布发生变化:
- P(X₁, X₂) 发生变化。
- 从顶部和右侧的 KDE 图可以看出,两个特征(协变量)的分布几乎相同。362

- 但散点图显示,它们在训练集(蓝色)中的联合分布与生产环境(红色)中的联合分布并不相同。不难猜测,前面讨论的单变量协变量偏移检测方法会得出误导性的结果。例如,如下所示,测量某个训练特征与生产特征之间的 Bhattacharyya 距离会得到一个非常小的距离值,表明两者高度相似:
- 事实上,即便单个特征的分布相同,我们也可以通过实验确认,这会导致模型性能下降:假设真实输出 y = w_A·x_A + w_B·x_B + 噪声。


在大多数情况下,生产数据上的真实输出预测并不能立即获得。在上面的演示中,我们暂且假设已经以某种方式收集到了真实预测。如上所示,模型在生产环境中的性能下降了 20%,这幅度很大。在这里,如果我们认为协变量偏移绝不可能具有多元性质,就可能会完全排除协变量偏移的可能性。当然,在下图中,我们之所以能轻松识别出多元协变量偏移,是因为我们只看了两个特征。

但多元协变量偏移也可能发生在两个以上特征之间。与上面的双变量情形不同,在更高维度下无法进行可视化检查。
首先需要理解的是,多元协变量偏移是一个大问题,而且没有直接(或单一)的方法来处理它。下面,我会分享几个我自己常用、也见别人用过的处理多元协变量偏移的思路。
只要我们一次只检查两个(甚至三个)特征,就可以用可视化检查来发现协变量偏移。因此在这种情况下,有时很多人干脆就忽略了三个特征以上出现协变量偏移的可能性。

其理由是,超过三个特征后,出现以下情况的可能性相当小:
- P(X₁)、P(X₂)、P(X₃)、P(X₄)…… → 它们各自几乎都保持不变。
- 但它们的联合分布 P(X₁, X₂, X₃, X₄)…… 会发生变化。
因此,把多元协变量偏移分析限制在一次只看一个、两个和三个特征,可能算是一种合理的做法。但当然,这并不总是成立,这就引出了另一个思路:
这是我在某个项目中用过的另一个很酷且实用的想法。数据重构(data reconstruction),顾名思义,就是学习一个映射,先把数据投影到低维空间,再从低维空间重构出原始数据。

这正是自编码器(Autoencoders)所做的事情。它们是一类神经网络,能够学习把数据编码到一个低维空间中,然后再解码回原始数据空间。

其目标是最小化数据重构误差。这就好比让模型学习一个映射,该映射:
- 接收一些数据。
- 把数据投影到低维。
- 然后再把输入数据原样还给我们。
所以我们可以这样做:
- 在原始训练数据集上训练一个自编码器。这会得到用于重构该数据集的神经网络模型权重。
- 在新数据上使用这个模型来检查多元协变量偏移:
- 如果重构损失高,说明分布发生了变化。
- 如果重构损失低,说明分布几乎没变。

这种方法最棒的一点在于,它不需要带标签的数据集。本质上,自编码器的目标就是在没有标签的情况下重构数据集。这在真实世界的模型中相当有用,因为正如我们昨天讨论过的,在大多数情况下,生产数据上的真实输出预测永远无法立即获得,而总是需要一段时间。例如,我记得在 Mastercard 做交易欺诈检测模型时,持卡人的发卡行可能需要长达 45 到 50 天,才能把经过 Mastercard 网络的交易对应的欺诈标签发回来。这段时间可不短,是吧?但借助自编码器,我们仍然可以在无标签数据上检查数据重构误差。事实上,我们未必非得用自编码器,它只是这里的一个例子。其他数据重构技术同样可以使用,比如 PCA 就是其中之一。不过,在使用任何数据重构方法时,有一件事需要特别注意。前面我们讨论过:
- 如果重构损失高,说明分布发生了变化。
- 如果重构损失低,说明分布几乎没变。
但解读重构损失可能相当主观,并且也需要一些上下文。

例如,假设重构损失是 0.4,我们如何判断这是否显著?与许多人想的相反,机器学习模型中的协变量偏移是逐步发生的。换句话说,模型不太可能今天还表现很好,第二天就因为协变量偏移而开始表现不佳。

当然,性能骤降是有可能的,但极少是协变量偏移造成的。大多数时候,它是由其他问题引起的——比如出于某些合规原因,团队停止采集某个特征,结果你的模型再也无法使用它训练时所依赖的那个特征;又或者推理逻辑做了更新却没有经过充分测试;等等。而由于协变量偏移导致的性能下降是逐步发生的。在这个性能下降的阶段,我们必须在某个时点决定更新模型,以适应分布的变化。

虽然数据重构损失有助于决定是否更新模型,但单凭它本身传达的意义很有限。简而言之,我们需要一个基准重构损失值,以便与未来的重构损失做比较。所以我们可以这样做。假设我们决定每周评审一次模型。在用收集到的数据训练完模型之后:

- 我们使用训练后第一周收集到的新数据,来确定基准重构得分。
- 我们用这个基准得分来比较之后每周的损失。

重构损失与基准得分之间出现较大差异,就说明出现了协变量偏移。简单又直观,对吧?上述重构指标再结合模型性能,就成了判断协变量偏移是否已经出现的一种可靠方式。当然,正如前面所说,真实标签有时无法立即获得,因此在生产环境中确定性能可能会比较困难。为了应对这一点,所有机器学习团队都会持续不断地从最终用户那里收集反馈,以了解模型表现是否良好。

这在推荐系统中尤为常见:
- 这条广告与你相关吗?
- 这条新视频与你相关吗?
- 以及其他更多问题。
这些都属于模型日志记录阶段的一部分,我们在该阶段跟踪模型在生产环境中的表现。这有助于我们决定是否应该更新模型。
