3. 样本格式规范:字段命名规则、数据类型定义、缺失值标记标准与时间戳格式
实时风控特征工程中,样本格式的规范性直接决定了特征计算引擎的解析效率与模型推理的稳定性。一个字段命名混乱、类型定义模糊、缺失值标记不统一、时间戳格式各异的样本流,会在上线后引发大量不可追溯的异常。本节从四个核心维度建立样本格式的硬性规范。
3.1 字段命名规则
字段命名需同时满足可读性、机器解析效率与跨团队协作需求。推荐采用 小写蛇形命名法(snake_case),并遵循以下分层规则:
- 业务前缀:使用 2-4 字符标识业务域,如
usr_(用户域)、trx_(交易域)、dev_(设备域)。 - 实体标识:紧随业务域后,使用名词性单词,如
usr_age、trx_amount。 - 派生后缀:对于衍生特征,使用
_avg、_max、_cnt、_ratio等明确后缀。 - 禁止字符:禁止使用空格、连字符(
-)、中文、特殊符号(@#$%),仅允许字母、数字和下划线。
| 示例字段名 | 含义 | 是否合规 |
|---|---|---|
usr_age |
用户年龄 | ✅ 合规 |
trx_amount_avg_30d |
近30天交易金额均值 | ✅ 合规 |
user-Age |
用户年龄(含连字符) | ❌ 不合规 |
设备指纹 |
设备指纹(中文) | ❌ 不合规 |
💡 命名长度建议:单字段名控制在 3-6 个单词以内(含前缀),总字符不超过 48 字节。过长的字段名会增加序列化开销与下游存储压力。
3.2 数据类型定义
实时风控场景下,数据类型必须显式声明,避免隐式转换带来的精度丢失或解析失败。以下为推荐的数据类型映射表:
| 风控语义类型 | 推荐数据类型 | 说明与约束 |
|---|---|---|
| 用户ID / 订单ID | STRING |
禁止使用数值类型,防止前导零丢失或大数精度问题 |
| 金额 / 分数 | DOUBLE 或 DECIMAL(18,4) |
避免使用 FLOAT,防止高精度场景下的舍入误差 |
| 年龄 / 次数 | INT32 |
非负整数,超出范围使用 INT64 |
| 设备类型 / 渠道码 | STRING 或 INT32(枚举映射) |
若使用枚举,需在元数据中维护映射表 |
| IP地址 | STRING |
IPv4/IPv6 统一以字符串存储,不转为整数 |
| 布尔标志 | BOOLEAN |
禁止使用 0/1 整数替代,除非上游系统强制约束 |
⚠️ 常见陷阱:在实时流处理框架(如 Flink、Spark Streaming)中,
FLOAT 与 DOUBLE 的序列化/反序列化行为在不同版本间可能存在差异。建议在特征管道入口处统一转换为 DECIMAL 或 STRING 后再参与计算。
3.3 缺失值标记标准
缺失值标记必须与正常业务值严格区分,避免将“0”或“空字符串”误判为缺失。推荐采用以下分层标记方案:
- 数值型字段:统一使用
null或NaN(取决于序列化协议)。禁止使用-1、0、9999等特殊数值替代缺失。 - 字符串型字段:统一使用空字符串
""表示有值但为空,使用null表示字段缺失。禁止混用"NULL"、"NA"、"unknown"等文本标记。 - 布尔型字段:缺失值必须使用
null,禁止使用false或0替代。 - 时间戳字段:缺失值使用
null或 Unix 纪元时间0(需在元数据中明确声明)。
📋 缺失值处理流程:在特征工程管道中,建议在样本解析阶段即完成缺失值标记的标准化,后续特征计算模块统一识别
null 并执行填充或剔除策略,避免在多个算子中重复处理特殊值。
3.4 时间戳格式
时间戳是实时风控中最关键的排序与窗口计算依据。格式不统一会导致窗口聚合错乱、事件时序颠倒。推荐采用以下规范:
- 统一单位:所有时间戳字段统一使用 Unix 毫秒时间戳(13 位整数)。禁止混用秒级(10 位)、微秒级(16 位)或纳秒级(19 位)时间戳。
- 时区约定:所有时间戳均视为 UTC+0 时区。业务展示时由前端或下游应用做时区转换,特征计算层不处理时区偏移。
- 字段命名:事件发生时间使用
event_time_ms,特征计算时间使用feature_time_ms,数据到达时间使用arrival_time_ms。 - 异常值处理:时间戳为
null、0或超出合理范围(如小于 1000000000000 或大于当前时间 + 1小时)的样本,应在特征计算前标记为无效样本并进入异常通道。
// 时间戳格式校验示例(伪代码)
function validateTimestamp(ts: Long): Boolean {
val minValid = 1000000000000L // 2001-09-09 UTC
val maxValid = System.currentTimeMillis() + 3600000L // 当前时间 + 1小时
return ts != null && ts >= minValid && ts <= maxValid
}
⏱ 时间戳对齐策略:当上游系统只能提供秒级时间戳时,在特征管道入口处统一乘以 1000 转换为毫秒级,并在元数据中记录转换操作,便于后续排查精度问题。
3.5 格式规范全景对照
以下表格将四个维度的规范要点汇总,便于团队在代码审查与数据接入时快速对照:
| 维度 | 核心规则 | 常见反例 | 校验方式 |
|---|---|---|---|
| 字段命名 | 小写蛇形 + 业务前缀 | userAge、trx-amount |
正则校验 ^[a-z][a-z0-9_]{2,47}$ |
| 数据类型 | 显式声明,禁止隐式转换 | ID 用 INT、金额用 FLOAT | Schema 注册表强制匹配 |
| 缺失值标记 | 统一使用 null |
-1、"NULL"、0 |
白名单校验 + 异常捕获 |
| 时间戳格式 | Unix 毫秒,UTC+0 | 秒级时间戳、含时区字符串 | 数值范围 + 正则校验 |
📌 上线前必检清单:
✅ 所有字段名是否通过正则
✅ 金额字段是否使用
✅ 缺失值是否全部替换为
✅ 时间戳是否为 13 位整数且时区统一为 UTC+0?
✅ 所有字段名是否通过正则
^[a-z][a-z0-9_]{2,47}$ 校验?✅ 金额字段是否使用
DOUBLE 或 DECIMAL 而非 FLOAT?✅ 缺失值是否全部替换为
null,无特殊数值残留?✅ 时间戳是否为 13 位整数且时区统一为 UTC+0?