在大模型训练过程中,异常值处理是特征工程中不可忽视的关键环节。最近在处理一个推荐系统数据集时,我踩了一个典型的坑:直接使用Z-score方法删除异常值导致了严重的数据偏差。
问题重现
原始数据包含用户点击时间戳,其中存在大量异常值(如2010年的时间戳)。使用标准的Z-score方法(阈值3)删除后,发现训练集和验证集分布严重不一致,模型性能急剧下降。
多种方法对比
import numpy as np
import pandas as pd
from scipy import stats
# 生成测试数据
np.random.seed(42)
data = np.random.normal(100, 15, 1000)
data[::100] = [200, 300, 400] # 添加异常值
# 方法1: Z-score (失败案例)
Z_scores = np.abs(stats.zscore(data))
filtered_data1 = data[Z_scores < 3]
print(f"Z-score方法删除后数据量: {len(filtered_data1)}")
# 方法2: IQR方法 (推荐)
Q1, Q3 = np.percentile(data, [25, 75])
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
filtered_data2 = data[(data >= lower_bound) & (data <= upper_bound)]
print(f"IQR方法删除后数据量: {len(filtered_data2)}")
# 方法3: 基于分布的截断法
clipped_data = np.clip(data, np.percentile(data, 1), np.percentile(data, 99))
结论
对于大模型训练数据,建议优先使用IQR方法或分位数截断法,避免简单Z-score导致的数据失真。在特征工程阶段,必须进行跨数据集的分布验证。
实际项目中,我最终采用了混合策略:先用IQR去除极端异常值,再用分位数截断保留更多有效信息。

讨论