3、数据清洗与预处理:处理缺失值、异常值检测与修正、数据标准化与归一化方法
采购品类成本预测的准确性,高度依赖于输入数据的质量。原始采购数据通常包含缺失值、异常值以及量纲不一致的问题。本章将系统讲解数据清洗与预处理的三大核心步骤,确保后续模型能够基于高质量、标准化的数据进行训练与预测。
3.1 缺失值处理
采购数据中的缺失值可能源于系统故障、人工录入遗漏或数据同步延迟。常见的处理策略包括删除、填充与插值。
| 策略 | 适用场景 | 方法示例 | 注意事项 |
|---|---|---|---|
| 删除 | 缺失比例极低(<5%)且随机分布 | 删除含缺失值的行或列 | 避免删除过多导致样本量不足 |
| 统计填充 | 数值型字段,数据分布稳定 | 均值、中位数、众数填充 | 均值易受异常值影响,优先使用中位数 |
| 前向/后向填充 | 时间序列数据(如月度采购金额) | 使用上一个或下一个有效值填充 | 适用于趋势平稳的序列 |
| 插值法 | 连续型时间序列,趋势明显 | 线性插值、多项式插值 | 需确保时间间隔均匀 |
| 模型预测填充 | 缺失值与其他特征强相关 | KNN、回归模型预测缺失值 | 计算成本较高,适用于关键字段 |
采购实践建议:对于“供应商报价”字段的缺失,优先使用同类物料的历史均价填充;对于“交货周期”字段的缺失,建议使用同供应商同品类的众数填充,避免使用全局均值导致偏差。
3.2 异常值检测与修正
异常值会严重扭曲成本趋势,导致预测模型产生系统性偏差。采购数据中的异常值通常表现为价格突变、数量异常或成本占比失衡。
3.2.1 常用检测方法
- Z-Score 法:适用于正态分布数据,通常将 |Z| > 3 的观测值视为异常。
- IQR 四分位距法:适用于偏态分布,将低于 Q1 - 1.5×IQR 或高于 Q3 + 1.5×IQR 的值标记为异常。
- 孤立森林:适用于高维数据,通过随机切割特征空间识别孤立点。
- 业务规则法:基于采购经验设定阈值,如单价超过历史均值的 3 倍。
关键指标对比:
| 方法 | 数据分布要求 | 计算复杂度 | 可解释性 |
|---|---|---|---|
| Z-Score | 正态分布 | 低 | 高 |
| IQR | 无要求 | 低 | 高 |
| 孤立森林 | 无要求 | 中 | 中 |
| 业务规则 | 依赖专家经验 | 低 | 极高 |
3.2.2 修正策略
检测到异常值后,不应简单删除,而应根据业务含义进行修正:
- 截尾处理:将异常值替换为阈值上限或下限(如 99% 分位数)。
- 局部替换:使用异常点前后各 3 个正常值的均值进行替换。
- 标记保留:对于因特殊事件(如原材料暴涨)导致的真实异常,保留并添加标记列供模型学习。
# Python 示例:IQR 法检测与截尾修正
import numpy as np
import pandas as pd
def iqr_cap(series, factor=1.5):
Q1 = series.quantile(0.25)
Q3 = series.quantile(0.75)
IQR = Q3 - Q1
lower = Q1 - factor * IQR
upper = Q3 + factor * IQR
return series.clip(lower, upper)
# 对采购单价列进行异常值修正
df['unit_price_clean'] = iqr_cap(df['unit_price'])
注意:不要对同一批数据反复进行异常值检测与修正,否则会过度平滑真实波动,掩盖成本趋势中的关键拐点。
3.3 数据标准化与归一化
采购数据中,不同特征(如采购金额、数量、供应商评分)的量纲差异巨大。标准化与归一化能够消除量纲影响,使模型在训练时对各特征一视同仁。
3.3.1 核心方法对比
| 方法 | 公式 | 输出范围 | 适用场景 |
|---|---|---|---|
| Min-Max 归一化 | X' = (X - X_min) / (X_max - X_min) | [0, 1] | 数据有明确边界,如评分、百分比 |
| Z-Score 标准化 | X' = (X - μ) / σ | 无固定范围,均值为0,标准差为1 | 数据近似正态分布,存在异常值 |
| Robust 标准化 | X' = (X - Median) / IQR | 无固定范围 | 数据包含较多异常值 |
| MaxAbs 归一化 | X' = X / |X_max| | [-1, 1] | 稀疏数据或已中心化的数据 |
3.3.2 选择建议
- 线性模型(如线性回归、逻辑回归):优先使用 Z-Score 标准化,有助于加速收敛。
- 距离模型(如 KNN、K-Means):优先使用 Min-Max 归一化,避免量纲大的特征主导距离计算。
- 树模型(如随机森林、XGBoost):通常不需要标准化,但标准化后不影响模型性能。
# Python 示例:使用 sklearn 进行标准化
from sklearn.preprocessing import StandardScaler, MinMaxScaler
# Z-Score 标准化
scaler_std = StandardScaler()
df[['amount', 'quantity']] = scaler_std.fit_transform(df[['amount', 'quantity']])
# Min-Max 归一化
scaler_mm = MinMaxScaler()
df[['score', 'rating']] = scaler_mm.fit_transform(df[['score', 'rating']])
采购场景提示:对于“采购金额”这类长尾分布特征,建议先进行对数变换(log1p)再标准化,能够有效压缩极端值的影响,使数据分布更接近正态。
3.4 数据清洗与预处理流程总览
以下 SVG 图展示了从原始采购数据到可用于建模的标准化数据的完整处理流程,包含缺失值处理、异常值检测与修正、标准化/归一化三个核心环节。
3.5 数据质量验证清单
完成预处理后,建议使用以下清单进行最终验证:
| 检查项 | 验收标准 | 验证方法 |
|---|---|---|
| 缺失值比例 | 所有特征缺失率 < 1% | df.isnull().sum() / len(df) |
| 异常值比例 | 异常标记样本 < 5% | IQR 或 Z-Score 统计 |
| 数据分布 | 标准化后均值接近 0,标准差接近 1 | df.describe() 查看统计量 |
| 量纲一致性 | 所有数值特征处于同一量级 | 可视化箱线图或直方图 |
| 时间连续性 | 时间序列无断裂或重复 | 检查时间戳排序与去重 |
最佳实践:将数据清洗与预处理的所有操作记录为可复现的 Python 脚本或 ETL 流程,每次建模前重新执行,确保数据版本一致。建议使用
pandas 的 pipe() 函数串联多个预处理步骤,提升代码可读性。