2. 数据质量维度:完整性、准确性、一致性、时效性、唯一性、有效性
聊特征数据质量,咱们得先有个统一的“度量衡”。
你想想看,如果连什么是“好数据”都定义不清楚,那监控体系就是空中楼阁。业内通常把这六个维度作为核心框架:完整性、准确性、一致性、时效性、唯一性、有效性。我做了这么多年数据治理,坦白讲,能把这三个维度吃透的项目,数据质量都不会差到哪去。
核心观点: 这六个维度不是孤立存在的。一个特征可能同时违反多个维度规则,比如“用户年龄=200岁”既违反了有效性,也违反了准确性。监控时要注意交叉分析。
2.1 完整性:别让特征“缺胳膊少腿”
完整性,说白了就是检查特征值有没有缺失。这是最基础、也最容易出问题的一环。
我记得刚带团队时,有个同学跑完模型发现AUC暴跌,查了半天——原来是上游特征表某个分区数据没刷过来,导致一半样本的特征全是NULL。嗯,这种坑踩过一次就长记性了。
我的习惯: 完整性监控不能只看“是否为NULL”。对于字符串类型,空串 ''、空白字符 ' '、占位符 'NULL'、'N/A' 都应该纳入缺失判定。我一般会建一个缺失值等价类表,统一清洗。
完整性监控的常见规则:
- 字段级缺失率: 单特征缺失值占比,超过阈值(如5%)触发告警。
- 行级完整性: 关键特征组合(如用户ID+时间戳)不能同时缺失。
- 跨表完整性: 主表与维表关联后,维表字段不应大面积为空。
2.2 准确性:数据得“说真话”
准确性衡量的是特征值与其真实值的接近程度。这维度最难搞,因为很多时候你根本不知道“真实值”是什么。
我在项目中遇到过最典型的场景:用户填写的出生年份是“1900”。从格式上看没问题,但显然不准确。怎么办?只能靠业务规则和统计分布来卡。
| 准确性检测方法 | 适用场景 | 示例 |
|---|---|---|
| 业务规则校验 | 有明确取值范围 | 年龄 0-120,金额 ≥ 0 |
| 统计分布检测 | 数值型特征 | 均值±3σ 之外的离群点 |
| 交叉验证 | 多源数据可对比 | 订单金额 vs 支付流水金额 |
| 历史基线对比 | 时序稳定的特征 | 日活用户数波动超过20% |
避坑指南: 我曾经在监控准确性时,直接用了3σ原则剔除“异常值”。结果把双十一大促的真实高流量全给过滤了。后来我学乖了——准确性规则必须区分“业务异常”和“数据异常”,大促、活动期间要动态调整阈值。
2.3 一致性:不同地方说的得是同一回事
一致性关注的是同一份数据在不同系统、不同表、不同时间点之间是否矛盾。
举个例子:用户画像系统里存的是“性别=1(男)”,但交易系统里同一用户的性别是“女”。你说模型该信谁?
我个人的经验是,一致性问题是数据仓库里最常见的“慢性病”。它不像缺失值那么显眼,但长期积累下来,模型效果会莫名其妙地变差。
一致性监控的典型场景:
- 跨系统一致性: 在线库与离线数仓的同名字段值是否一致。
- 派生一致性: 总金额 = 子订单金额之和,这个等式必须成立。
- 时间一致性: 事件发生时间 ≤ 数据入库时间,不能出现“未来数据”。
2.4 时效性:数据要“趁热吃”
时效性衡量的是数据从产生到可被使用的时间延迟。说白了,数据是不是够“新鲜”。
实时特征和离线特征对时效性的要求天差地别。比如风控场景,延迟5分钟可能就错过了一笔欺诈交易;而月度经营分析,T+1甚至T+7都能接受。
关键指标: 我一般会监控三个时间戳——event_time(业务发生时间)、ingest_time(数据接入时间)、feature_time(特征计算时间)。计算 ingest_time - event_time 得到端到端延迟,超过SLA就告警。
2.5 唯一性:别让重复数据“浑水摸鱼”
唯一性要求每个实体在数据集中只出现一次。对于主键、业务ID这类特征,重复是致命的。
你想想看,如果同一个用户ID在训练集里出现两次,模型就会对这个样本“加倍重视”,相当于人为引入了偏差。
唯一性监控的常见规则:
- 主键唯一性: 表的主键或联合主键不能重复。
- 业务键唯一性: 如订单ID、设备ID,在指定时间窗口内不能重复。
- 特征组合唯一性: 对于宽表,某些特征组合(如用户+日期)应保持唯一。
小技巧: 我习惯在ETL脚本里加一个 COUNT(DISTINCT id) == COUNT(id) 的断言。如果不等,直接让任务失败,而不是带着脏数据往下跑。这叫“快速失败”,比事后排查高效得多。
2.6 有效性:数据得“守规矩”
有效性检查的是数据是否符合预定义的格式、类型、取值范围。它和准确性有点像,但更偏“格式层面”。
举个例子:手机号字段里出现了“abc123”,这明显无效;但手机号“13800138000”格式正确,是不是真实号码?那是准确性的事。
有效性监控的常见规则:
| 规则类型 | 说明 | 代码示例(PySpark) |
|---|---|---|
| 数据类型校验 | 字段类型与Schema一致 | df.schema["age"].dataType == IntegerType() |
| 枚举值校验 | 值必须在允许列表中 | df.filter(~col("status").isin(["A","B","C"])) |
| 正则校验 | 格式必须匹配正则 | df.filter(~col("email").rlike("^\\S+@\\S+\\.\\S+$")) |
| 范围校验 | 数值在[min, max]内 | df.filter((col("score") < 0) | (col("score") > 100)) |
避坑指南: 我曾经遇到一个坑——上游把字段类型从 int 改成了 string,但下游模型还在按数值类型处理。结果模型直接崩了。所以有效性监控一定要包含Schema兼容性检查,尤其是跨团队协作时。
2.7 六个维度怎么落地?
讲完理论,说说实操。我个人习惯把这六个维度分成三个优先级:
- P0(必须监控): 完整性、唯一性。这两项出问题,模型基本没法用。
- P1(强烈建议): 准确性、有效性。影响模型效果,但有时可以容忍。
- P2(按需监控): 一致性、时效性。取决于业务场景,实时系统必须监控,离线批处理可以放宽。
最后说一句:不要试图一次性监控所有维度。我见过不少团队,一上来就搞了上百条质量规则,结果告警满天飞,运维同学直接躺平。我的建议是——从P0开始,跑通一个维度再扩展下一个。稳扎稳打,比什么都强。