趋近智
单变量漂移检测虽然有用,但常常无法捕捉特征之间关系的变化。多元漂移检测方法通过考虑整体数据分布来解决这个问题。将实现一种使用最大均值差异(MMD)检验的多元漂移检测机制。MMD是一种比较分布的有效非参数方法。将使用 alibi-detect 库,该库提供了多种漂移检测算法的便捷实现。
首先,请确保您已安装所需的库。如果没有,您可以使用 pip 进行安装:
pip install alibi-detect numpy pandas scikit-learn plotly
我们将使用 NumPy 进行数值运算,Pandas 用于可能的数据处理(尽管此处需求较少),Scikit-learn 用于生成合成数据,以及 Plotly 用于数据可视化。
import numpy as np
import plotly.graph_objects as go
from sklearn.datasets import make_blobs
from alibi_detect.cd import MMDDrift
print("库导入成功。")
为演示多元漂移,我们需要两个数据集:一个表示“正常”状态的参考数据集(例如,训练数据或来自初始稳定生产期的数据),以及一个表示可能发生漂移的新数据集。
让我们创建合成的五维数据。参考数据将包含两个聚类。漂移数据将有一个聚类发生偏移,这代表了底层数据生成过程的变化。
# 参考数据(表示稳定状态)
np.random.seed(0)
n_features = 5
n_samples_ref = 500
X_ref, _ = make_blobs(n_samples=n_samples_ref, n_features=n_features, centers=[np.zeros(n_features), np.ones(n_features)*1.5], cluster_std=0.5, random_state=0)
print(f"参考数据形状:{X_ref.shape}")
# 漂移数据(表示变化状态)
np.random.seed(1)
n_samples_drift = 500
# 略微移动其中一个中心并增加方差
centers_drift = [np.zeros(n_features) + 0.2, np.ones(n_features)*1.5 + 0.3]
X_drift, _ = make_blobs(n_samples=n_samples_drift, n_features=n_features, centers=centers_drift, cluster_std=0.6, random_state=1)
print(f"漂移数据形状:{X_drift.shape}")
现在,我们从 alibi-detect 实例化 MMDDrift 检测器。主要参数是:
X_ref:参考数据集。检测器从该数据中学习“正常”分布。p_val:统计检验的显著性水平。常见值为0.05。如果计算出的 p 值低于此阈值,则检测到漂移。backend:指定计算后端('tensorflow'、'pytorch' 或 'keops')。我们在此处使用 'tensorflow',如果您偏好 PyTorch,可以自行调整。请确保已安装 TensorFlow(pip install tensorflow)。preprocess_fn:可选参数,一个用于在漂移检测前预处理数据(例如缩放)的函数。为简单起见,此处我们跳过此步骤,但这在实际应用中很重要。# 配置MMD漂移检测器
p_threshold = 0.05 # 显著性水平
try:
# 需要安装 tensorflow
# pip install tensorflow
cd = MMDDrift(X_ref, backend='tensorflow', p_val=p_threshold)
print("MMDDrift 检测器初始化成功。")
except ImportError:
print("TensorFlow 后端不可用。请安装 tensorflow。")
cd = None
except Exception as e:
print(f"检测器初始化错误:{e}")
cd = None
检测器配置完成后,我们现在可以对新数据集(X_drift)进行漂移检测。predict 方法返回一个字典,其中包含:
data['is_drift']:如果检测到漂移则为1,否则为0。data['p_val']:MMD 检验计算出的 p 值。data['distance']:MMD 统计量(衡量分布之间距离的指标)。data['threshold']:基于参考数据排列和 p_val 计算的 MMD 统计量临界阈值。如果 distance > threshold,则检测到漂移。# 对新数据执行漂移检测
if cd:
preds = cd.predict(X_drift)
# 打印结果
print("\n漂移检测结果:")
print(f" 是否检测到漂移?{'是' if preds['data']['is_drift'] else '否'}")
print(f" p 值: {preds['data']['p_val']:.4f}")
print(f" MMD 距离: {preds['data']['distance']:.4f}")
print(f" 距离阈值: {preds['data']['threshold']:.4f}")
if preds['data']['is_drift']:
print("\n分析:检测到漂移!新数据的分布与参考数据存在统计学上的差异。")
else:
print("\n分析:未检测到明显漂移。")
else:
print("\n检测器初始化失败,跳过检测。")
您会看到检测到漂移,因为 p 值低于我们的 0.05 阈值,并且计算出的 MMD 距离超过了从参考数据排列中得出的阈值。
在实际系统中,数据是连续到达或分批到达的。让我们通过生成小批量数据来模拟这种情况,其中一些反映原始分布,另一些反映漂移分布,并观察 MMD 统计量的表现。
# 模拟数据随时间分批到达
n_batches = 20
batch_size = 100
drift_scores = []
p_values = []
detection_threshold = None # 存储来自检测器的阈值
time_steps = list(range(n_batches))
if cd:
detection_threshold = cd.threshold # 获取预先计算的阈值
for i in range(n_batches):
np.random.seed(i * 10) # 确保每批数据可重现
# 在10批数据后引入漂移
if i < 10:
# 从参考分布中采样
centers_batch = [np.zeros(n_features), np.ones(n_features)*1.5]
std_batch = 0.5
else:
# 从漂移分布中采样
centers_batch = centers_drift
std_batch = 0.6
X_batch, _ = make_blobs(n_samples=batch_size, n_features=n_features, centers=centers_batch, cluster_std=std_batch, random_state=i*10)
# 检查当前批次的漂移
batch_preds = cd.predict(X_batch)
drift_scores.append(batch_preds['data']['distance'])
p_values.append(batch_preds['data']['p_val'])
print(f"\n模拟了 {n_batches} 批数据。阈值:{detection_threshold:.4f}")
现在,让我们可视化每个批次的 MMD 距离(漂移分数)与检测阈值的对比。
传入数据批次与参考数据之间的 MMD 距离。在第 10 批数据之后,底层数据分布发生变化,导致 MMD 距离明显增加并越过预设的检测阈值(红色虚线),这表明发生了漂移。
正如预期,前 10 批数据(从原始分布中采样)的 MMD 距离保持较低水平,随后当数据开始来自漂移分布时,MMD 距离明显跳升到阈值之上。
本次实践练习说明了如何:
alibi-detect 中的 MMDDrift 检测器。MMD 是有效的,因为它在再生核希尔伯特空间(RKHS)中比较分布,使其能够捕捉复杂的非线性差异。然而,请注意:
alibi-detect 使用采样排列等优化方法来计算阈值。X_ref)对于准确估计零分布(无漂移)和设置可靠阈值非常重要。这个动手示例提供了一个起点。在生产系统中,您会将此类检测器集成到您的 MLOps 流水线中,当确认出现明显漂移时,触发警报或自动化操作(如模型再训练)。请记住根据您的特定用例调整数据生成、检测器参数和模拟逻辑。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造