4. 数据收集与预处理:坏样本标注、缺失值处理、异常值检测、数据标准化
数据质量决定了归因分析的天花板。在真实业务场景中,原始数据往往包含大量“坏样本”——缺失、异常、重复、标注错误的记录。本章将系统讲解坏样本的识别与修复流程,确保后续归因模型建立在干净、可靠的数据基础之上。
核心原则:坏样本处理不是一次性任务,而是贯穿数据生命周期的迭代过程。建议在每次模型迭代前重新执行本章流程,避免“垃圾进,垃圾出”。
4.1 坏样本的定义与分类
坏样本(Bad Samples)指在数据收集、传输或存储过程中产生的、无法真实反映业务规律的样本。根据问题性质,可分为以下四类:
| 类别 | 定义 | 典型场景 | 影响程度 |
|---|---|---|---|
| 缺失样本 | 关键字段值为空或不可用 | 用户未填写年龄、设备型号未上报 | 中 |
| 异常样本 | 数值或分布显著偏离正常范围 | 点击量突增100倍、转化率超过100% | 高 |
| 重复样本 | 完全或部分字段相同的多条记录 | 同一事件被SDK重复上报 | 低-中 |
| 标注错误样本 | 标签或归因结果与事实不符 | 渠道来源被错误归因、用户ID混淆 | 极高 |
注意:标注错误样本在归因分析中危害最大。一个错误的归因标签会污染整个渠道效果评估,导致预算分配决策失误。建议在数据预处理阶段优先处理此类样本。
4.2 坏样本标注策略
坏样本标注是预处理的第一步,目的是为每条数据打上“是否坏样本”及“坏样本类型”的标签。常用的标注方法包括:
- 规则标注:基于业务经验定义硬性规则,如“转化率 > 1”标记为异常、“用户ID为空”标记为缺失。
- 统计标注:使用均值±3σ、IQR(四分位距)等统计方法自动识别离群点。
- 模型标注:训练孤立森林(Isolation Forest)、LOF(Local Outlier Factor)等无监督模型检测异常。
- 人工标注:对高价值或高不确定性样本进行人工审核,常用于标注错误样本的修正。
以下是一个基于规则的坏样本标注示例(Python伪代码):
def label_bad_sample(row):
# 规则1:缺失检测
if pd.isnull(row['user_id']) or pd.isnull(row['event_time']):
return 'missing'
# 规则2:异常检测(转化率超过100%)
if row['conversion_rate'] > 1.0:
return 'outlier'
# 规则3:重复检测(基于事件ID去重)
if row['event_id'] in seen_event_ids:
return 'duplicate'
# 规则4:标注错误(渠道来源与IP归属地矛盾)
if row['channel'] == 'organic' and row['ip_geo'] == 'paid_ad_region':
return 'mislabel'
return 'normal'
4.3 缺失值处理
缺失值处理需根据缺失比例、字段重要性、缺失机制(MCAR/MAR/MNAR)选择策略。以下是常用方法对比:
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 删除法 | 缺失比例 < 5%,且随机缺失 | 简单、不影响分布 | 样本量减少,可能引入偏差 |
| 均值/中位数填充 | 数值型字段,缺失比例 < 20% | 计算快、保持均值 | 降低方差,扭曲相关性 |
| 众数填充 | 分类型字段 | 保持类别分布 | 可能引入偏态 |
| 前向/后向填充 | 时间序列数据 | 利用时序连续性 | 不适用于非时序数据 |
| KNN插值 | 缺失比例 < 30%,有相似样本 | 利用多维信息 | 计算量大,需调K值 |
| 模型预测填充 | 缺失比例高,字段重要 | 精度高 | 可能过拟合,需谨慎 |
实战建议:在归因分析中,
user_id、event_time、channel 三个字段的缺失值应优先处理。若缺失比例超过50%,建议直接删除该字段或重新采集数据。
4.4 异常值检测
异常值检测是坏样本识别的核心环节。归因数据中的异常值通常表现为:点击量突增、转化率异常、归因窗口期超长等。以下是三种主流检测方法:
- Z-Score方法:适用于近似正态分布的数据。Z-Score绝对值大于3的样本标记为异常。
- IQR方法:适用于偏态分布。定义 Q1 - 1.5×IQR 和 Q3 + 1.5×IQR 为正常范围,超出则标记为异常。
- 孤立森林(Isolation Forest):适用于高维数据。通过随机切割特征空间,异常点更容易被孤立。
以下是一个使用IQR方法检测异常值的代码示例:
def detect_outliers_iqr(data, column):
Q1 = data[column].quantile(0.25)
Q3 = data[column].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers = data[(data[column] < lower_bound) | (data[column] > upper_bound)]
return outliers.index.tolist()
# 示例:检测点击量字段的异常值
click_outliers = detect_outliers_iqr(df, 'click_count')
print(f"检测到 {len(click_outliers)} 个异常点击样本")
4.5 数据标准化
数据标准化(Normalization/Standardization)是将不同量纲的特征缩放到同一尺度,避免归因模型中数值较大的特征主导权重。常用的标准化方法包括:
| 方法 | 公式 | 输出范围 | 适用场景 |
|---|---|---|---|
| Z-Score标准化 | z = (x - μ) / σ | 无固定范围,均值为0,标准差为1 | 数据近似正态分布,需保留异常值信息 |
| Min-Max归一化 | x' = (x - min) / (max - min) | [0, 1] | 数据有明确边界,如转化率、点击率 |
| Robust标准化 | x' = (x - median) / IQR | 无固定范围,对异常值鲁棒 | 数据包含较多异常值 |
| MaxAbs归一化 | x' = x / |max| | [-1, 1] | 稀疏数据或已中心化的数据 |
实战建议:在归因分析中,建议对连续型特征(如点击量、曝光量、花费)使用Z-Score标准化,对比例型特征(如转化率、点击率)使用Min-Max归一化。标准化应在训练集上计算参数,再应用到测试集,避免数据泄露。
4.6 完整预处理流程
将以上步骤整合为一个完整的预处理流水线,建议按以下顺序执行:
- 数据加载与初步探查:读取原始数据,查看字段类型、缺失比例、基本统计量。
- 坏样本标注:基于规则或模型标记坏样本类型。
- 缺失值处理:根据缺失比例和字段重要性选择删除或填充策略。
- 异常值检测与处理:使用IQR或孤立森林检测异常,根据业务判断是否删除或修正。
- 重复样本去重:基于事件ID或关键字段组合进行去重。
- 数据标准化:对连续型特征进行标准化,对分类型特征进行编码。
- 质量验证:检查预处理后的数据分布、样本量、字段完整性,确保无信息泄露。
重要提醒:预处理步骤的顺序不可随意调换。例如,先标准化再处理异常值会导致异常值被“压缩”到正常范围,难以识别。建议严格按照上述顺序执行。
通过本章的学习,你已经掌握了坏样本标注、缺失值处理、异常值检测和数据标准化的核心方法。这些预处理技术是归因分析的基础,直接影响后续模型的效果和业务决策的准确性。在实际项目中,建议将预处理流程封装为可复用的Pipeline,以便在不同数据集上快速应用。