2. 核心监控指标:完整性、准确性、一致性、时效性、唯一性

好,咱们直接进入正题。特征质量监控到底看什么?

我个人的习惯是,把这五个指标当作五个探针,分别插在特征生产管线的不同位置。它们各自盯着一个维度,合起来就能把特征的健康状况摸得清清楚楚。

说白了,这五个指标就是特征质量的「体检项」。缺了哪一个,你都可能在线上翻车。

2.1 完整性(Completeness)

完整性,就是看特征值有没有缺失。这个指标最直观,也最容易出问题。

我在项目中遇到过好几次,上游表结构改了,新字段没及时同步,结果下游模型拿到的特征全是 null。模型没报错,但预测结果直接漂移了。

核心监控逻辑:

  • 统计每个特征字段的 null 值比例
  • 对比历史基线,判断是否异常
  • 区分「允许缺失」和「必须完整」的特征

举个例子,用户年龄字段允许缺失,但用户 ID 不能为空。所以监控时要分字段设置阈值。

-- 完整性监控 SQL 示例
SELECT
  feature_name,
  COUNT(*) AS total_rows,
  SUM(CASE WHEN feature_value IS NULL THEN 1 ELSE 0 END) AS null_count,
  ROUND(SUM(CASE WHEN feature_value IS NULL THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) AS null_rate
FROM feature_store
WHERE dt = '2025-03-21'
GROUP BY feature_name
HAVING null_rate > 5.0;  -- 阈值可配置

我的经验:不要只监控 null 比例。有时候特征值变成了空字符串 '' 或者 'N/A',这些也算缺失。我建议把「语义缺失」也纳入完整性监控。

2.2 准确性(Accuracy)

准确性,就是特征值是否符合预期范围或格式。这个指标比完整性难搞,因为它需要「预期值」作为参照。

你想想看,一个年龄字段填了 200 岁,语法上没问题,但明显不合理。这就是准确性问题。

避坑指南:我曾经遇到过特征值分布整体偏移的情况。比如用户点击率从 0.3 突然跳到 0.8,每个值都在合法范围内,但整体分布变了。这种「隐性不准确」最容易被忽略。

我一般用两种方式监控准确性:

  • 规则校验:值域检查、格式正则、枚举值白名单
  • 分布校验:PSI(群体稳定性指标)、均值/方差突变检测
特征类型 准确性规则示例 异常阈值
年龄 0 <= age <= 120 超出范围 > 0.1%
性别 值必须为 M/F/U 非法值 > 0%
收入 0 <= income <= 10^7 超出范围 > 0.5%
CTR(点击率) PSI < 0.1 PSI >= 0.1 触发告警

2.3 一致性(Consistency)

一致性,指的是同一个特征在不同数据源或不同时间点的取值是否对齐。

嗯,这里要注意。很多团队只盯着单条特征的完整性,却忽略了跨系统的比对。我见过最典型的案例是:实时特征和离线特征算出来的用户活跃天数不一样,模型训练用离线,推理用实时,结果线上效果直接崩了。

一致性监控的三种场景:

  1. 源系统 vs 特征存储:原始日志里的值,和写入特征存储的值是否一致
  2. 实时 vs 离线:同一特征在实时管道和离线批处理中的计算结果是否对齐
  3. 前后版本:特征逻辑升级后,新旧版本输出是否一致(回放验证)

我个人习惯用「抽样比对」的方式做一致性校验。全量比对成本太高,抽样 + 哈希校验是个不错的折中方案。

# 一致性校验伪代码
def check_consistency(real_time_df, offline_df, sample_rate=0.01):
    # 按用户 ID 做 join,抽样比对
    sample_rt = real_time_df.sample(frac=sample_rate)
    merged = sample_rt.merge(offline_df, on='user_id', suffixes=('_rt', '_offline'))
    
    # 计算不一致比例
    mismatch = merged[merged['feature_rt'] != merged['feature_offline']]
    mismatch_rate = len(mismatch) / len(merged)
    
    return mismatch_rate

2.4 时效性(Timeliness)

时效性,就是特征从产生到可用的延迟。实时特征最怕的就是「迟到」。

为什么?因为模型在等特征,特征迟迟不来,要么用旧值凑合,要么直接报错。这两种情况都会影响模型效果。

我的做法:我会给每个特征打上「时效性标签」。比如用户实时行为特征要求延迟 < 5 秒,用户画像特征可以放宽到 1 小时。不同标签走不同的监控阈值。

时效性监控通常看两个指标:

  • P99 延迟:99% 的特征在多少毫秒内到达
  • 迟到率:超过约定延迟阈值的特征占比
特征等级 延迟要求 迟到率告警阈值
S 级(核心实时特征) < 100ms > 0.1%
A 级(重要特征) < 1s > 0.5%
B 级(普通特征) < 5s > 1%
C 级(离线特征) < 1h > 5%

2.5 唯一性(Uniqueness)

唯一性,就是看特征数据有没有重复。这个指标在实时流处理中特别重要。

你想想看,用户点击事件被重复消费了两次,特征值被更新了两次,模型拿到的特征就失真了。我遇到过因为 Kafka 重平衡导致数据重复消费,特征值翻了一倍,模型直接输出异常结果。

避坑指南:我曾经以为唯一性监控很简单,count(distinct) 一下就行。后来发现,在实时场景下,重复数据可能跨窗口、跨分区出现。单纯的 distinct 统计根本抓不住。我后来改用「事件 ID + 时间窗口」的滑动去重检测。

唯一性监控的核心手段:

  • 主键重复率:按特征主键(如 user_id + feature_name)统计重复比例
  • 事件去重率:按事件唯一 ID 统计重复消费比例
  • 窗口内重复检测:滑动窗口内同一事件出现多次即为异常
-- 唯一性监控 SQL 示例
SELECT
  window_start,
  feature_name,
  COUNT(*) AS total_events,
  COUNT(DISTINCT event_id) AS unique_events,
  ROUND((1 - COUNT(DISTINCT event_id) * 1.0 / COUNT(*)) * 100, 2) AS duplicate_rate
FROM feature_events
WHERE window_start >= NOW() - INTERVAL '5 minutes'
GROUP BY window_start, feature_name
HAVING duplicate_rate > 1.0;  -- 重复率超过 1% 告警

2.6 五维指标全景图

这五个指标不是孤立的。它们之间会互相影响。比如时效性差可能导致完整性下降(特征还没到就超时了),一致性问题可能引发准确性异常。

我习惯用一张图把这五个维度的关系串起来,方便团队理解。

特征质量五维监控指标全景图 特征质量 完整性 准确性 一致性 时效性 唯一性 五个指标互相影响:时效性差可能导致完整性下降,一致性问题可能引发准确性异常

总结一下:

  • 完整性:特征有没有缺失?—— null 比例监控
  • 准确性:特征值对不对?—— 规则 + 分布校验
  • 一致性:不同来源的值是否对齐?—— 跨系统比对
  • 时效性:特征到得及不及时?—— 延迟 + 迟到率监控
  • 唯一性:数据有没有重复?—— 去重检测