3. 交易数据模型设计:原始交易日志字段定义、用户画像与设备指纹、标签体系设计(正常/异常)

交易数据模型是异常检测系统的数据基石。一个完整的数据模型需要覆盖三个层次:原始交易日志(描述“发生了什么”)、用户画像与设备指纹(描述“谁在操作”)、标签体系(描述“结果是什么”)。本章将逐层定义字段结构,并给出 Flink 作业可直接引用的数据模型。

3.1 原始交易日志字段定义

原始交易日志是风控系统最上游的数据源,通常由支付网关、收单系统或核心账务系统实时推送。每条日志记录一笔交易的完整上下文。下表定义了标准化的 20 个核心字段:

字段名 类型 长度/精度 说明 示例值
transaction_id String 64 全局唯一交易流水号 TXN2025032112345678
user_id String 32 用户登录 ID 或会员号 U10008642
account_id String 32 交易发起账户号 ACC6228480012345678
trans_type String 16 交易类型:消费/转账/提现/充值 CONSUME
amount Decimal 18,2 交易金额(元) 4999.00
currency String 3 币种 ISO 代码 CNY
trans_time Timestamp — 交易发生时间(UTC+8) 2025-03-21 14:30:00
merchant_id String 16 商户编号 M10086
terminal_type String 16 终端类型:WEB/APP/POS/API APP
ip_address String 45 客户端 IP(支持 IPv6) 192.168.1.100
device_id String 128 设备指纹 ID DF_A1B2C3D4E5F6
location_lat Double — GPS 纬度 39.9042
location_lng Double — GPS 经度 116.4074
channel String 16 渠道编码:支付宝/微信/银联/银行卡 ALIPAY
risk_score Integer — 上游风控预评分(0-100) 35
is_first_transaction Boolean — 是否该用户首笔交易 false
order_id String 64 关联订单号 ORD20250321001
product_category String 32 商品类目 电子产品
remark String 256 备注/扩展信息(JSON) {"coupon":"DISCOUNT50"}
etl_timestamp Timestamp — 数据入湖时间 2025-03-21 14:30:05
Flink 建模提示: 在 Flink SQL 中建议将 trans_time 定义为 TIMESTAMP(3) 并声明为事件时间属性(WATERMARK FOR trans_time AS trans_time - INTERVAL '5' SECOND),以便后续做滑动窗口聚合与延迟数据容忍。

3.2 用户画像与设备指纹

仅靠单笔日志字段无法识别团伙欺诈或账户盗用。必须引入用户画像(描述用户长期行为特征)和设备指纹(描述设备环境与关联关系)。这两类数据通常存储在 HBase/Redis 中,Flink 通过异步 I/O 或维表 JOIN 实时关联。

3.2.1 用户画像核心维度

维度类别 字段 类型 说明
基础属性 user_reg_time Timestamp 注册时间
user_level Integer 会员等级(1-5)
real_name_verified Boolean 是否实名认证
行为统计 avg_daily_amount_7d Decimal 近7天日均交易金额
trans_count_1h Integer 过去1小时交易笔数
city_set_30d String 近30天常驻城市列表(JSON)
风险标签 blacklist_flag Boolean 是否命中黑名单
risk_tag_list String 风控标签列表(逗号分隔)

3.2.2 设备指纹关键字段

字段 类型 说明
device_id String 设备唯一标识(通过 canvas/webgl/IMEI 等生成)
os_type String 操作系统:iOS / Android / Windows / macOS
browser_fingerprint String 浏览器指纹哈希
screen_resolution String 屏幕分辨率
is_rooted_or_jailbroken Boolean 是否越狱/root
associated_user_count Integer 该设备关联过的用户数
first_seen_time Timestamp 设备首次出现时间
设备指纹关联风险: 若 associated_user_count > 5 且 is_rooted_or_jailbroken = true,该设备极可能是“猫池”或模拟器设备,应直接提升交易风险等级。

3.3 标签体系设计:正常 / 异常

标签体系是监督学习与规则评估的“标准答案”。我们将标签分为三个层级:最终标签(业务决策结果)、过程标签(中间判定)、细分类别(异常类型)。

3.3.1 标签定义表

标签层级 标签字段 取值 含义
最终标签 final_label 0 / 1 0=正常,1=异常(最终审核结果)
label_source RULE / MODEL / MANUAL 标签来源:规则/模型/人工
过程标签 rule_hit_list String 命中规则 ID 列表(逗号分隔)
model_score Double [0,1] 模型输出异常概率
manual_review_result PASS / REJECT / REVIEW 人工审核结果
review_comment String 审核备注
细分类别 abnormal_type String 异常大类:FRAUD / MONEY_LAUNDERING / ACCOUNT_TAKEOVER / CREDIT_CARD_SCAM / OTHERS
fraud_subtype String 欺诈子类:PHISHING / SOCIAL_ENGINEERING / BRUTE_FORCE
ml_subtype String 洗钱子类:SMURFING / STRUCTURING / TRADE_BASED
ato_subtype String 盗号子类:CREDENTIAL_STUFFING / SESSION_HIJACK
severity LOW / MEDIUM / HIGH / CRITICAL 异常严重等级

3.3.2 标签生成流程

标签并非一次性写入,而是经过多阶段管道逐步丰富:

  1. 规则引擎打标:Flink CEP 或 Drools 规则命中后,写入 rule_hit_list 与 model_score(初始值 0.0)。
  2. 模型推理:XGBoost/DeepFM 模型输出 model_score,若 > 0.7 则临时标记为异常。
  3. 人工审核:高风险交易进入人工审核队列,审核员填写 manual_review_result 与 abnormal_type。
  4. 最终标签生成:综合规则、模型、人工结果,由仲裁逻辑输出 final_label。
标签一致性注意: 在 Flink 流处理中,final_label 可能延迟到达(人工审核耗时数分钟)。建议设计“标签版本号”字段,Flink 作业以 upsert 模式更新标签,避免覆盖早期人工标注。

3.4 数据模型整体架构

下图展示了原始日志、用户画像、设备指纹、标签体系四层数据在 Flink 实时风控架构中的关联关系:

交易数据模型整体架构 交易数据模型四层架构 原始交易日志层 transaction_id, user_id, amount, trans_time, ip_address, device_id, location, channel … JOIN user_id 用户画像层 avg_daily_amount_7d, trans_count_1h, blacklist_flag … JOIN device_id 设备指纹层 os_type, is_rooted, associated_user_count … 规则引擎 + 模型推理 标签体系层 final_label (0/1) | abnormal_type | severity | label_source 输出到 Kafka / 数据库 异常交易样本(带标签)

3.5 Flink 数据模型代码示例

在 Flink 中,我们使用 Java POJO 或 Flink SQL 的 CREATE TABLE 语句来定义数据模型。以下是一个完整的交易事件 POJO 示例:

// TransactionEvent.java — 原始交易日志 POJO
public class TransactionEvent implements Serializable {
    public String transactionId;
    public String userId;
    public String accountId;
    public String transType;
    public BigDecimal amount;
    public String currency;
    public Long transTime;          // 事件时间(毫秒时间戳)
    public String merchantId;
    public String terminalType;
    public String ipAddress;
    public String deviceId;
    public Double locationLat;
    public Double locationLng;
    public String channel;
    public Integer riskScore;
    public Boolean isFirstTransaction;
    public String orderId;
    public String productCategory;
    public String remark;
    public Long etlTimestamp;

    // 无参构造器(Flink 要求)
    public TransactionEvent() {}

    // 全参构造器、getter/setter 省略(实际生产使用 Lombok @Data)
}

// TransactionLabel.java — 标签 POJO
public class TransactionLabel implements Serializable {
    public String transactionId;
    public Integer finalLabel;          // 0:正常 1:异常
    public String labelSource;          // RULE/MODEL/MANUAL
    public String ruleHitList;
    public Double modelScore;
    public String manualReviewResult;
    public String abnormalType;
    public String severity;
    public Long labelUpdateTime;
}
Flink SQL 建表语句(Kafka 源表):
CREATE TABLE transaction_log (
  transaction_id STRING,
  user_id STRING,
  amount DECIMAL(18,2),
  trans_time TIMESTAMP(3) METADATA FROM 'timestamp',
  WATERMARK FOR trans_time AS trans_time - INTERVAL '5' SECOND,
  proctime AS PROCTIME()
) WITH (
  'connector' = 'kafka',
  'topic' = 'raw_transaction',
  'format' = 'json'
);

3.6 数据模型设计检查清单

  • 完整性:是否覆盖了交易标识、用户、金额、时间、位置、设备、渠道、标签等全部必要维度?
  • 可扩展性:remark 字段是否预留 JSON 扩展空间?标签体系是否支持新增异常子类?
  • 时间语义:是否明确区分事件时间(trans_time)与处理时间(etl_timestamp)?
  • 关联效率:用户画像与设备指纹是否设计了 JOIN KEY(user_id / device_id)?是否考虑异步 I/O 或广播维表?
  • 标签版本:是否包含 label_update_time 或版本号,以支持标签的流式更新?