3、数据预处理与特征工程:数据清洗、缺失值处理、标准化与归一化、类别编码、特征选择与提取

在监督学习项目中,模型性能的上限往往不取决于算法本身,而取决于输入数据的质量与特征表达。业界流传的“Garbage In, Garbage Out”正是对这一事实的精准概括。数据预处理与特征工程是将原始、杂乱、不完整的业务数据转化为可用于模型训练的规范数据集的关键环节。本章将系统讲解数据清洗、缺失值处理、标准化与归一化、类别编码以及特征选择与提取的核心原理、操作流程与实战要点,帮助学习者建立一套完整、可落地的数据准备方法论。

数据预处理与特征工程核心链路 原始数据 缺失/重复/异常/文本 数据清洗 去重/异常值/格式统一 缺失值处理 删除/均值/插补/模型预测 标准化/归一化/类别编码 数值缩放/One-Hot/标签编码 特征选择与提取 过滤/包裹/嵌入/PCA 高质量训练数据集 供监督学习模型使用 模型训练与评估 分类/回归/异常检测 迭代优化

上图展示了从原始数据到模型训练的标准预处理链路。在实际项目中,这一链路并非单向通行,而是需要根据模型评估结果反复迭代调整。例如,特征选择的结果可能促使我们重新审视数据清洗策略,而模型在验证集上的表现不佳也可能反向推动我们构造新的特征。下面我们将逐一拆解每个环节的具体操作与决策依据。

3.1 数据清洗:去除噪声与不一致

核心原理

数据清洗旨在检测并修正数据集中存在的错误、不一致、重复记录以及异常值。原始数据通常来源于多个业务系统,可能存在格式不统一(如日期格式“2024/01/01”与“2024-01-01”并存)、单位不一致(如身高分别以cm和m记录)、明显的录入错误(如年龄为200岁)等问题。若不加以处理,这些噪声会直接干扰模型学习真实规律,导致模型偏差或方差增大。

判断方法与操作流程

数据清洗的典型操作流程包括以下四个步骤:

  1. 重复值检测:通过计算记录间的相似度(如基于关键字段的哈希值或编辑距离)识别完全重复或近似重复的记录。对于完全重复记录可直接删除;对于近似重复,需结合业务规则判断保留哪一条。
  2. 异常值识别:常用方法包括基于统计的3σ原则(数据超出均值±3倍标准差视为异常)、基于四分位距(IQR)的箱线图法(超出Q1-1.5×IQR或Q3+1.5×IQR的点为异常),以及基于业务逻辑的规则校验(如年龄必须在0-120之间)。
  3. 格式统一化:将日期、时间、货币、电话号码等字段转换为统一格式。例如,将所有日期统一为“YYYY-MM-DD”,将所有金额统一为“分”或“元”并保留两位小数。
  4. 逻辑一致性校验:检查字段之间的逻辑关系。例如,订单金额应等于商品单价乘以数量,若不等则说明存在数据错误,需要追溯源系统或按规则修正。
实战场景:电商订单数据清洗
某电商平台在构建用户购买力预测模型时,发现订单表中存在以下问题:①约2%的订单记录完全重复;②部分订单的“订单金额”字段为负数(可能是退款记录未标记);③“用户年龄”字段存在大于100岁的异常值。处理策略为:对重复订单按“订单ID+商品ID”去重;将负金额订单单独标记为“退款”类型,不参与购买力预测;对年龄大于100岁的记录,结合注册时间与身份证号校验,无法校验的按缺失值处理。清洗后,数据集规模从120万条降至115万条,模型训练时间缩短了8%,AUC提升了0.03。
风险提示:异常值不一定是错误值。例如,在异常检测场景中,异常值恰恰是我们要预测的目标。因此,在清洗阶段应先将异常值标记出来,而不是直接删除,待明确业务含义后再决定处理方式。

3.2 缺失值处理:策略选择与实施

核心原理

缺失值是指数据集中某些字段的值为空。缺失值的产生原因包括:用户未填写、系统采集故障、数据合并时字段不匹配等。处理缺失值的关键在于理解缺失机制:完全随机缺失(MCAR)、随机缺失(MAR)和非随机缺失(MNAR)。不同机制下,处理策略的选择会显著影响模型的无偏性。

处理策略对比

策略适用场景优点缺点
直接删除缺失比例极低(<5%)且为MCAR简单、不引入偏差丢失信息,可能减少样本量
均值/中位数/众数填充数值型或类别型数据,缺失比例中等计算简单、快速降低方差,可能引入偏差
插补法(线性插值、KNN插补)时间序列或具有相似样本的数据利用数据内在结构,更准确计算开销大,可能过拟合
模型预测填充缺失字段与其他字段相关性较强精度高,利用全部信息实现复杂,需防止数据泄露
标记缺失缺失本身具有业务含义(如“未填写”表示“无”)保留信息,模型可学习缺失模式增加特征维度

操作流程

处理缺失值的推荐流程为:①统计每个字段的缺失比例;②分析缺失机制(可通过比较有缺失与无缺失样本在其他字段上的分布差异);③根据业务场景和缺失比例选择策略;④实施填充并记录填充逻辑,以便在模型部署时复用。

经验提醒:在训练集与测试集上必须使用相同的填充参数(如训练集计算出的均值),否则会导致数据泄露或预测不一致。建议将填充器(Imputer)定义为可序列化对象,随模型一同保存。

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)
常见误区:在训练集上fit标准化器后,必须使用同一个已fit的scaler对测试集或新样本进行transform,而不是重新fit。否则会导致训练集与测试集的数据分布不一致,破坏模型泛化能力。

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。
复盘经验:特征选择不能完全依赖自动化方法,必须结合业务知识进行人工校验。同时,特征选择应在交叉验证的框架内进行,避免在全体数据上选择特征后再划分训练集/测试集,否则会造成数据泄露。
总结复盘:数据预处理与特征工程是监督学习项目中投入产出比最高的环节。一个清晰、可复现的预处理流程不仅能提升模型性能,还能显著降低模型上线后的维护成本。建议团队将预处理逻辑封装为独立的Python模块或Pipeline,并记录每一步操作的参数与依据,确保模型可追溯、可复现。在实际项目中,建议遵循“先清洗、再处理缺失、后缩放编码、最后特征选择”的顺序,并在每个环节设置质量检查点,确保数据质量可控。