3. 坏样本数据采集:数据源分类、采集频率与数据质量初筛

坏样本归因分析的第一步,也是最容易被低估的一步,是数据采集。如果采集阶段就混入了系统性偏差或低质量数据,后续所有的特征工程和归因结论都会建立在沙丘之上。本章聚焦数据源的三大分类、采集频率与时效性的权衡策略,以及数据质量初筛的核心方法。

3.1 数据源分类:三大来源与特征对比

在工业级归因系统中,坏样本的数据来源通常分为三类:内部日志、外部三方数据和埋点数据。三类数据在采集方式、覆盖范围、可信度和延迟上存在显著差异。

数据源类型 典型示例 采集方式 覆盖范围 可信度 采集延迟
内部日志 服务器访问日志、数据库慢查询日志、应用错误日志 服务端自动记录 全量用户行为 高(内部可控) 秒级~分钟级
外部三方数据 设备指纹、IP 信誉库、黑名单、风控评分 API 调用 / 文件同步 仅覆盖调用方 中(依赖供应商) 分钟级~天级
埋点数据 页面点击流、曝光事件、自定义事件 客户端 SDK 上报 前端用户交互 中(易受网络/设备影响) 秒级~小时级
实践建议:坏样本归因中,内部日志通常作为“黄金基线”用于交叉验证;埋点数据对用户行为还原最细,但需注意上报丢失和延迟;外部三方数据适合补充设备级和网络级特征,但需关注数据新鲜度。

3.2 数据源采集架构总览

下图展示了三类数据源在典型归因系统中的采集路径与汇聚关系。内部日志通过 Flume/Filebeat 采集,埋点数据通过 SDK → Kafka 管道,外部三方数据通过定时任务或 API 网关接入,最终统一进入数据湖或实时数仓。

坏样本数据源采集架构 坏样本数据源采集架构 内部日志 服务器 / 应用日志 埋点数据 客户端 SDK 上报 外部三方数据 API / 文件同步 Flume / Filebeat Kafka 管道 定时任务 / API 网关 数据湖 / 实时数仓 统一存储与清洗 坏样本特征工程

3.3 采集频率与时效性

不同数据源对采集频率和时效性的要求差异巨大。错误的选择会导致特征滞后或系统过载。下表总结了常见场景下的推荐配置:

数据源 推荐采集频率 时效性要求 典型延迟 适用场景
服务器错误日志 实时(流式) 秒级 < 5 秒 实时风控、故障检测
用户点击埋点 实时(流式) 秒级~分钟级 < 30 秒 用户行为归因
设备指纹 按需 + 缓存 分钟级 < 5 分钟 设备维度特征
IP 信誉库 每日全量 + 增量 天级 1 天 网络环境评估
黑名单 / 灰名单 每日全量 天级 1 天 离线批量归因
常见陷阱:不要对所有数据源统一使用“实时采集”。外部三方数据(如 IP 库)的更新频率通常为天级,实时调用只会增加延迟和成本,不会提升特征质量。建议按数据源的自然更新周期设置采集频率。

3.4 数据质量初筛:四维检查清单

在数据进入特征工程管线之前,必须执行一次快速的质量初筛。初筛不是深度清洗,而是快速过滤明显不可用的数据。推荐从以下四个维度展开:

  1. 完整性检查:关键字段(如用户 ID、时间戳、事件类型)是否存在大量空值?空值率超过 30% 的字段应标记为“低质量”。
  2. 一致性检查:同一实体的字段间是否存在逻辑矛盾?例如“注册时间 > 当前时间”或“订单金额为负数”。
  3. 时效性检查:数据时间戳是否在合理范围内?是否存在大量“未来时间戳”或“过期超过 7 天”的数据?
  4. 唯一性检查:主键或业务键是否存在重复?重复率超过 5% 的数据源需要排查采集逻辑。

3.5 数据质量初筛流程

下图展示了从原始数据到可入特征工程管线的完整初筛流程。每个检查环节都对应一个明确的“通过/拒绝”决策点。

数据质量初筛流程 数据质量初筛流程 原始数据流入 ① 完整性检查:空值率 < 30% ② 一致性检查:无逻辑矛盾 ③ 时效性检查:时间戳合理 ④ 唯一性检查:重复率 < 5% ✅ 进入特征工程 ❌ 拒绝 / 标记 不通过

3.6 初筛阶段的代码示例

以下 Python 代码展示了如何对采集到的日志数据执行四维初筛。实际生产环境中,建议将检查逻辑封装为独立的 Data Quality Checker 模块。

import pandas as pd
import numpy as np
from datetime import datetime, timedelta

def quality_initial_screen(df: pd.DataFrame, 
                           key_col: str = 'user_id',
                           time_col: str = 'event_time',
                           null_threshold: float = 0.3,
                           dup_threshold: float = 0.05,
                           max_time_lag_days: int = 7) -> dict:
    """
    数据质量初筛:返回各维度检查结果与整体判定。
    """
    result = {}
    total = len(df)
    
    # 1. 完整性检查
    null_ratio = df[key_col].isnull().mean()
    result['null_ratio'] = round(null_ratio, 4)
    result['null_pass'] = null_ratio < null_threshold
    
    # 2. 一致性检查:时间戳不应为未来
    now = datetime.now()
    future_count = (df[time_col] > now).sum()
    result['future_time_count'] = future_count
    result['consistency_pass'] = future_count == 0
    
    # 3. 时效性检查:数据不应过于陈旧
    cutoff = now - timedelta(days=max_time_lag_days)
    stale_count = (df[time_col] < cutoff).sum()
    result['stale_count'] = stale_count
    result['freshness_pass'] = stale_count / total < 0.1
    
    # 4. 唯一性检查
    dup_ratio = df[key_col].duplicated().mean()
    result['dup_ratio'] = round(dup_ratio, 4)
    result['dup_pass'] = dup_ratio < dup_threshold
    
    # 综合判定
    result['overall_pass'] = all([
        result['null_pass'],
        result['consistency_pass'],
        result['freshness_pass'],
        result['dup_pass']
    ])
    
    return result

# 使用示例
sample_df = pd.DataFrame({
    'user_id': ['u1', 'u2', None, 'u4', 'u1'],
    'event_time': [
        datetime(2025, 3, 1, 10, 0),
        datetime(2025, 3, 2, 12, 0),
        datetime(2025, 3, 1, 14, 0),
        datetime(2025, 3, 3, 8, 0),
        datetime(2025, 3, 1, 10, 0)
    ]
})
report = quality_initial_screen(sample_df)
print(report)
输出解读:上述示例中,由于存在空值(user_id 缺失)和重复键(u1 出现两次),overall_pass 将返回 False。此时该批次数据应被标记为“待人工审核”或“退回采集层修复”,而非直接进入特征工程。

3.7 本章小结

  • 数据源分类:内部日志(高可信)、埋点数据(细粒度)、外部三方(补充维度),三者需协同使用。
  • 采集频率:按数据源的自然更新周期设置,避免“一刀切”实时采集导致资源浪费。
  • 质量初筛:完整性、一致性、时效性、唯一性四维检查,是坏样本归因的第一道防线。
  • 工程落地:初筛逻辑应自动化、可配置,并输出明确的通过/拒绝信号。