3. 特征分布监控体系:连续特征统计量监控、离散特征频次监控、特征缺失率监控
批次偏移(Batch Drift)的早期发现依赖于对模型输入特征分布的持续监控。本章构建的监控体系覆盖三类核心特征:连续特征、离散特征和缺失率。通过统计量、频次和缺失比例的变化,可以快速定位数据分布是否发生偏移。
3.1 监控体系总览
特征分布监控体系分为三个层次,每个层次对应不同的特征类型和监控指标:
| 监控层次 | 特征类型 | 核心指标 | 偏移判定依据 |
|---|---|---|---|
| 连续特征统计量 | 数值型(如年龄、金额、温度) | 均值、方差、分位数(P25/P50/P75) | 统计量变化超过阈值(如均值偏移 > 3σ) |
| 离散特征频次 | 类别型(如城市、渠道、标签) | 各取值频次、占比、熵 | 频次分布差异(如 JS 散度 > 0.1) |
| 特征缺失率 | 所有特征 | 缺失比例、缺失模式 | 缺失率突变(如从 1% 升至 10%) |
实践建议:监控频率应与模型推理频率匹配。对于实时推理模型,建议每 1 小时或每 1000 条样本计算一次统计量;对于批量推理模型,建议每次批量任务完成后立即计算。
3.2 连续特征统计量监控
连续特征是模型数值输入的主体。监控其统计量可以捕捉到数据分布的集中趋势、离散程度和形状变化。
3.2.1 监控指标详解
- 均值(Mean):反映特征的整体水平。均值突变通常意味着数据采集源或业务规则发生变化。
- 方差(Variance):反映特征的波动程度。方差增大可能表示数据噪声增加或分布变得分散。
- 分位数(Quantiles):P25、P50(中位数)、P75 可以描述分布的形状和尾部行为。分位数偏移比均值更鲁棒,尤其适合非正态分布。
3.2.2 监控流程
- 基线计算:使用训练集或验证集计算每个连续特征的均值、方差和分位数,作为参考基线。
- 滑动窗口统计:对线上数据按时间窗口(如最近 1 小时或最近 1000 条)重新计算上述统计量。
- 差异计算:计算当前统计量与基线之间的绝对差异或相对差异。
- 阈值判定:若差异超过预设阈值(如均值偏移 > 3 倍基线标准差),则触发告警。
示例代码:连续特征统计量监控
import numpy as np
import pandas as pd
def monitor_continuous_feature(baseline_stats, current_data, feature_name, threshold=3.0):
"""
监控单个连续特征的统计量偏移
:param baseline_stats: dict, 包含 'mean', 'std', 'p25', 'p50', 'p75'
:param current_data: array-like, 当前窗口数据
:param feature_name: str, 特征名
:param threshold: float, 标准差倍数阈值
:return: dict, 监控结果
"""
current_mean = np.mean(current_data)
current_std = np.std(current_data)
current_p25 = np.percentile(current_data, 25)
current_p50 = np.percentile(current_data, 50)
current_p75 = np.percentile(current_data, 75)
# 计算均值偏移(以基线标准差为单位)
mean_drift = abs(current_mean - baseline_stats['mean']) / baseline_stats['std']
result = {
'feature': feature_name,
'baseline_mean': baseline_stats['mean'],
'current_mean': current_mean,
'mean_drift_sigma': mean_drift,
'is_drifted': mean_drift > threshold,
'p50_drift': abs(current_p50 - baseline_stats['p50']) / baseline_stats['std']
}
return result
3.3 离散特征频次监控
离散特征(类别特征)的分布变化往往比连续特征更隐蔽,但影响同样严重。频次监控可以检测到新类别出现、旧类别消失或类别占比发生显著变化。
3.3.1 监控指标
- 频次(Frequency):每个类别取值的出现次数。
- 占比(Proportion):每个类别取值在总样本中的比例。
- 熵(Entropy):衡量分布均匀程度。熵值变化可能表示类别分布趋于集中或分散。
- JS 散度(Jensen-Shannon Divergence):衡量当前分布与基线分布的差异,取值范围 [0, 1],值越大表示偏移越严重。
3.3.2 监控流程
- 基线频次表:从训练集或验证集构建每个离散特征的频次分布表。
- 当前频次统计:对线上数据按窗口统计每个类别的频次。
- 新类别检测:检查当前数据中是否出现基线中不存在的类别(未知类别)。
- 分布差异计算:使用 JS 散度或卡方检验量化分布差异。
- 阈值判定:若 JS 散度 > 0.1 或出现未知类别,则触发告警。
注意:离散特征频次监控对低频类别(如出现次数 < 5 的类别)不敏感。建议对低频类别进行合并或单独标记,避免因采样波动导致误报。
3.4 特征缺失率监控
特征缺失率是批次偏移的早期信号之一。缺失率突变通常意味着上游数据管道出现问题,如字段被删除、采集失败或传输中断。
3.4.1 监控指标
- 缺失率(Missing Rate):缺失值数量 / 总样本数量。
- 缺失模式(Missing Pattern):多个特征同时缺失的模式,如“特征 A 和特征 B 同时缺失”的比例。
- 缺失率变化量:当前缺失率与基线缺失率的绝对差值。
3.4.2 监控流程
- 基线缺失率:计算训练集或验证集中每个特征的缺失率。
- 当前缺失率计算:对线上数据按窗口计算每个特征的缺失率。
- 缺失率差异计算:计算当前缺失率与基线缺失率的差值。
- 阈值判定:若缺失率差值超过阈值(如绝对值 > 0.05 或相对变化 > 50%),则触发告警。
示例代码:特征缺失率监控
def monitor_missing_rate(baseline_missing_rate, current_data, feature_name, abs_threshold=0.05):
"""
监控单个特征的缺失率偏移
:param baseline_missing_rate: float, 基线缺失率
:param current_data: array-like, 当前窗口数据(含 NaN)
:param feature_name: str, 特征名
:param abs_threshold: float, 绝对差值阈值
:return: dict, 监控结果
"""
current_missing_rate = np.mean(pd.isna(current_data))
missing_rate_diff = current_missing_rate - baseline_missing_rate
result = {
'feature': feature_name,
'baseline_missing_rate': baseline_missing_rate,
'current_missing_rate': current_missing_rate,
'missing_rate_diff': missing_rate_diff,
'is_drifted': abs(missing_rate_diff) > abs_threshold
}
return result
3.5 特征分布监控体系架构
下图展示了特征分布监控体系的整体架构,包括数据采集、统计计算、偏移判定和告警输出四个核心模块。
3.6 监控指标对比与选择
不同监控指标对偏移的敏感度和适用场景不同。下表总结了各指标的优缺点:
| 指标 | 适用特征类型 | 优点 | 缺点 |
|---|---|---|---|
| 均值 | 连续 | 计算简单,直观 | 对异常值敏感,不适用于非对称分布 |
| 方差 | 连续 | 反映离散程度变化 | 对样本量敏感,小窗口下不稳定 |
| 分位数 | 连续 | 鲁棒性强,不受异常值影响 | 计算开销略高,需要排序 |
| 频次/占比 | 离散 | 直接反映类别分布 | 对低频类别不敏感 |
| JS 散度 | 离散 | 对称且归一化,易于设定阈值 | 对零频次类别需要平滑处理 |
| 缺失率 | 所有 | 简单直接,早期信号 | 无法区分随机缺失和非随机缺失 |
3.7 监控体系部署要点
- 基线更新策略:基线应定期更新(如每周一次),以适应业务周期性变化。更新时需人工审核,避免将偏移数据纳入基线。
- 多窗口监控:同时使用短窗口(如 1 小时)和长窗口(如 24 小时)进行监控。短窗口用于快速发现突变,长窗口用于发现缓慢漂移。
- 告警分级:根据偏移严重程度设置不同告警级别。轻度偏移(如均值偏移 2-3σ)发送通知,重度偏移(如缺失率 > 20%)触发紧急响应。
- 可视化看板:将监控指标以时间序列图的形式展示在 Grafana 或类似看板上,便于人工巡检。
最佳实践:建议将连续特征统计量监控、离散特征频次监控和特征缺失率监控整合到同一个监控管道中,统一输出告警。这样可以避免多个监控系统之间的信息孤岛,提高排查效率。