3、数据预处理与特征工程:数据清洗、缺失值处理、标准化与归一化、类别编码、特征选择与提取
在监督学习项目中,模型性能的上限往往不取决于算法本身,而取决于输入数据的质量与特征表达。业界流传的“Garbage In, Garbage Out”正是对这一事实的精准概括。数据预处理与特征工程是将原始、杂乱、不完整的业务数据转化为可用于模型训练的规范数据集的关键环节。本章将系统讲解数据清洗、缺失值处理、标准化与归一化、类别编码以及特征选择与提取的核心原理、操作流程与实战要点,帮助学习者建立一套完整、可落地的数据准备方法论。
上图展示了从原始数据到模型训练的标准预处理链路。在实际项目中,这一链路并非单向通行,而是需要根据模型评估结果反复迭代调整。例如,特征选择的结果可能促使我们重新审视数据清洗策略,而模型在验证集上的表现不佳也可能反向推动我们构造新的特征。下面我们将逐一拆解每个环节的具体操作与决策依据。
3.1 数据清洗:去除噪声与不一致
核心原理
数据清洗旨在检测并修正数据集中存在的错误、不一致、重复记录以及异常值。原始数据通常来源于多个业务系统,可能存在格式不统一(如日期格式“2024/01/01”与“2024-01-01”并存)、单位不一致(如身高分别以cm和m记录)、明显的录入错误(如年龄为200岁)等问题。若不加以处理,这些噪声会直接干扰模型学习真实规律,导致模型偏差或方差增大。
判断方法与操作流程
数据清洗的典型操作流程包括以下四个步骤:
- 重复值检测:通过计算记录间的相似度(如基于关键字段的哈希值或编辑距离)识别完全重复或近似重复的记录。对于完全重复记录可直接删除;对于近似重复,需结合业务规则判断保留哪一条。
- 异常值识别:常用方法包括基于统计的3σ原则(数据超出均值±3倍标准差视为异常)、基于四分位距(IQR)的箱线图法(超出Q1-1.5×IQR或Q3+1.5×IQR的点为异常),以及基于业务逻辑的规则校验(如年龄必须在0-120之间)。
- 格式统一化:将日期、时间、货币、电话号码等字段转换为统一格式。例如,将所有日期统一为“YYYY-MM-DD”,将所有金额统一为“分”或“元”并保留两位小数。
- 逻辑一致性校验:检查字段之间的逻辑关系。例如,订单金额应等于商品单价乘以数量,若不等则说明存在数据错误,需要追溯源系统或按规则修正。
某电商平台在构建用户购买力预测模型时,发现订单表中存在以下问题:①约2%的订单记录完全重复;②部分订单的“订单金额”字段为负数(可能是退款记录未标记);③“用户年龄”字段存在大于100岁的异常值。处理策略为:对重复订单按“订单ID+商品ID”去重;将负金额订单单独标记为“退款”类型,不参与购买力预测;对年龄大于100岁的记录,结合注册时间与身份证号校验,无法校验的按缺失值处理。清洗后,数据集规模从120万条降至115万条,模型训练时间缩短了8%,AUC提升了0.03。
3.2 缺失值处理:策略选择与实施
核心原理
缺失值是指数据集中某些字段的值为空。缺失值的产生原因包括:用户未填写、系统采集故障、数据合并时字段不匹配等。处理缺失值的关键在于理解缺失机制:完全随机缺失(MCAR)、随机缺失(MAR)和非随机缺失(MNAR)。不同机制下,处理策略的选择会显著影响模型的无偏性。
处理策略对比
| 策略 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 直接删除 | 缺失比例极低(<5%)且为MCAR | 简单、不引入偏差 | 丢失信息,可能减少样本量 |
| 均值/中位数/众数填充 | 数值型或类别型数据,缺失比例中等 | 计算简单、快速 | 降低方差,可能引入偏差 |
| 插补法(线性插值、KNN插补) | 时间序列或具有相似样本的数据 | 利用数据内在结构,更准确 | 计算开销大,可能过拟合 |
| 模型预测填充 | 缺失字段与其他字段相关性较强 | 精度高,利用全部信息 | 实现复杂,需防止数据泄露 |
| 标记缺失 | 缺失本身具有业务含义(如“未填写”表示“无”) | 保留信息,模型可学习缺失模式 | 增加特征维度 |
操作流程
处理缺失值的推荐流程为:①统计每个字段的缺失比例;②分析缺失机制(可通过比较有缺失与无缺失样本在其他字段上的分布差异);③根据业务场景和缺失比例选择策略;④实施填充并记录填充逻辑,以便在模型部署时复用。
3.3 标准化与归一化:尺度统一
核心原理
标准化(Standardization)与归一化(Normalization)都是对数值型特征进行尺度变换的方法。标准化将数据转换为均值为0、标准差为1的分布,公式为 \( z = (x - \mu) / \sigma \)。归一化通常指将数据缩放到[0,1]区间,公式为 \( x' = (x - min) / (max - min) \)。两者的核心目的都是消除不同特征之间量纲和数量级差异,避免数值范围大的特征在距离计算或梯度下降中主导模型训练。
选择依据
- 标准化:适用于数据近似服从正态分布的场景,或算法假设数据服从高斯分布(如线性回归、逻辑回归、SVM、PCA)。标准化对异常值不敏感(因为使用了均值与标准差)。
- 归一化:适用于数据分布未知或非正态分布的场景,或算法不假设数据分布(如KNN、K-Means、神经网络)。但归一化对异常值非常敏感,因为min和max会被极端值拉偏。
- 鲁棒缩放(RobustScaler):使用中位数和四分位距进行缩放,对异常值具有较好的鲁棒性,适合含有较多异常值的数据集。
# 使用scikit-learn进行标准化与归一化
from sklearn.preprocessing import StandardScaler, MinMaxScaler
import numpy as np
X = np.array([[1000, 0.01],
[2000, 0.02],
[3000, 0.03]])
# 标准化
scaler = StandardScaler()
X_std = scaler.fit_transform(X)
print("标准化结果:\n", X_std)
# 归一化
minmax = MinMaxScaler()
X_mm = minmax.fit_transform(X)
print("归一化结果:\n", X_mm)
3.4 类别编码:将文本转化为数值
核心原理
绝大多数机器学习算法只能处理数值型输入,因此需要将类别型特征(如颜色、城市、职业)转换为数值表示。编码方式的选择直接影响模型对类别间关系的理解。无序类别(如颜色)与有序类别(如学历:高中<本科<硕士)需要不同的编码策略。
常用编码方法
| 编码方法 | 适用场景 | 示例 | 注意事项 |
|---|---|---|---|
| 标签编码(Label Encoding) | 有序类别特征 | 学历:高中=0,本科=1,硕士=2 | 若用于无序类别,会引入虚假的序关系 |
| 独热编码(One-Hot Encoding) | 无序类别特征,类别数量较少(<20) | 颜色:红=[1,0,0],绿=[0,1,0],蓝=[0,0,1] | 类别过多会导致维度爆炸,需配合特征选择 |
| 频率编码(Frequency Encoding) | 类别数量多,且类别频率与目标变量相关 | 城市:北京出现1000次,编码为0.2 | 可能引入数据泄露,需在训练集内计算频率 |
| 目标编码(Target Encoding) | 类别数量多,且与目标变量有强关联 | 职业:平均薪资作为编码值 | 极易过拟合,需使用交叉验证或平滑处理 |
操作流程与案例
在金融风控场景中,对“职业”字段进行编码时,若使用独热编码会产生数百个稀疏列,导致模型训练缓慢且泛化能力下降。此时可采用目标编码:计算每个职业下违约率的平滑估计值(结合先验概率与样本量),作为该职业的编码值。具体公式为:\( \text{编码值} = \frac{n_i \times \text{mean}_i + m \times \text{prior}}{n_i + m} \),其中 \( n_i \) 为该职业样本数,\( \text{mean}_i \) 为该职业违约率,\( \text{prior} \) 为全局违约率,\( m \) 为平滑参数(通常取10-20)。通过5折交叉验证计算编码值,可有效避免过拟合。
3.5 特征选择与提取:降维与增强
核心原理
特征选择是从原始特征集合中挑选出对模型预测最有贡献的子集,而特征提取则是通过变换(如线性组合)生成新的、更具表达力的特征。两者的目的都是降低维度、减少过拟合风险、提升模型训练速度与可解释性。
特征选择三大类方法
- 过滤法(Filter):独立于模型,基于统计指标(如皮尔逊相关系数、卡方检验、互信息)对每个特征打分,设定阈值筛选。计算效率高,但忽略了特征间的交互作用。
- 包裹法(Wrapper):将模型性能作为特征子集的评价标准,通过递归特征消除(RFE)或前向/后向搜索寻找最优子集。效果较好,但计算开销大,易过拟合。
- 嵌入法(Embedded):在模型训练过程中自动进行特征选择,如L1正则化(Lasso)会将不重要的特征系数压缩为0,树模型(随机森林、XGBoost)可输出特征重要性分数。兼顾效率与效果,是工业界最常用的方法。
特征提取常用技术
主成分分析(PCA)是最经典的特征提取方法,通过正交变换将原始特征投影到新的坐标系中,使得新特征(主成分)按方差大小排序。PCA适用于特征间存在较强线性相关性的场景,但生成的主成分可解释性较差。线性判别分析(LDA)则利用类别标签信息,寻找最大化类间距离、最小化类内距离的投影方向,适用于分类任务。
背景与约束:某消费金融公司构建信贷违约预测模型,原始数据集包含200个特征,样本量5万条,正样本(违约)占比仅3%。约束条件:模型需具备较好的可解释性以通过监管审查,且推理时间需控制在50ms以内。
初始现象:直接使用全部特征训练逻辑回归模型,AUC为0.72,但训练时间长达15分钟,且特征系数存在大量非零值,难以解释。
分析判断:200个特征中存在大量冗余(如“用户申请金额”与“用户授信额度”相关性高达0.95),且部分特征缺失率超过60%。
操作步骤:①首先删除缺失率>60%的特征(共删除45个);②使用互信息法进行过滤,保留与目标变量互信息排名前100的特征;③在剩余特征上使用带L1正则化的逻辑回归进行嵌入法选择,最终保留32个非零系数特征;④对保留特征进行相关性分析,合并高度相关的特征组(如将“近3个月查询次数”与“近6个月查询次数”合并为“平均每月查询次数”)。
结果对比:最终特征维度降至28个,AUC提升至0.78,训练时间缩短至2分钟,推理时间降至8ms。特征系数全部非零且方向符合业务逻辑(如“收入负债比”系数为正,表示负债越高违约风险越大)。
风险与代价:特征选择过程中使用了L1正则化,导致部分弱相关但业务上重要的特征被剔除。为弥补这一不足,团队与业务部门确认后,手动保留了“近3个月逾期次数”这一特征,尽管其系数在L1正则化下被压缩为0。
复盘经验:特征选择不能完全依赖自动化方法,必须结合业务知识进行人工校验。同时,特征选择应在交叉验证的框架内进行,避免在全体数据上选择特征后再划分训练集/测试集,否则会造成数据泄露。