3、数据准备与特征工程:数据来源、清洗与特征构造

预测模型的精度上限由数据质量决定,而特征工程决定了模型逼近该上限的速度。在供应链预测场景中,数据来源分散、口径不一、缺失与异常频发,若直接建模,轻则预测偏差,重则导致库存失衡或产能浪费。本章围绕“数据来源—清洗—特征构造”三层链路展开,重点解决三个问题:哪些数据值得纳入、如何清洗成可用形态、如何构造出对预测有解释力的特征。

① 数据来源 ② 数据清洗 ③ 特征构造 历史销售(POS/订单/发货) 促销(折扣/活动/渠道) 天气(温度/降水/灾害) 经济指标(GDP/CPI/PMI) 供应链内部(库存/在途/产能) 多源异构,需统一时间粒度与实体口径 缺失值处理(删除/插补/标记) 异常值检测(IQR/3σ/业务规则) 去重与口径统一(SKU/时间/渠道) 时序对齐(日/周/月粒度重采样) 数据质量评分(完整性/一致性) 清洗原则:可追溯、可复现、保留业务语义 滞后特征(Lag 1/7/28/52) 滚动统计(均值/标准差/最大/最小) 日历特征(节假日/星期/月份) 事件特征(促销/缺货/天气事件) 交互特征(价格弹性/促销强度) 特征质量决定模型上限,业务理解决定特征方向 数据准备链路:来源 → 清洗 → 特征 → 建模

3.1 数据来源:从多源异构到统一视图

供应链预测的数据来源通常分为内部业务数据和外部环境数据两大类。内部数据包括历史销售记录(POS、订单、发货单)、库存水位、在途订单、促销计划、渠道铺货信息等;外部数据则涵盖天气、节假日、经济指标(GDP、CPI、PMI)、竞品动态、社交媒体热度等。不同来源的数据在时间粒度、实体标识、更新频率上差异巨大,必须建立统一的数据接入规范。

数据类别 典型字段 时间粒度 主要用途 获取难度
历史销售 SKU、日期、销量、销售额、渠道 日/周 预测基线、趋势识别 低(内部系统)
促销数据 折扣率、活动类型、持续时间 日/活动周期 识别促销脉冲效应 中(需跨部门协调)
天气数据 温度、降水、风速、灾害预警 小时/日 季节性品类(如饮品、空调) 中(API或气象局)
经济指标 PMI、CPI、社零总额 月/季度 宏观趋势、长期预测 低(公开数据)
供应链内部 库存量、在途量、产能、交期 日/周 约束条件、补货建议 低(内部系统)
经验提醒:不要一开始就追求“全量数据”。先明确预测目标(SKU级、周度、未来4周),再反向筛选数据源。过多无关特征不仅增加计算成本,还可能引入噪声。

3.2 数据清洗:缺失值、异常值与口径统一

数据清洗是特征工程的前置条件,也是预测项目中最耗时、最容易被低估的环节。清洗的目标不是“删掉坏数据”,而是让数据变得可解释、可复现、可追溯。

3.2.1 缺失值处理

缺失值在供应链数据中极为常见,原因包括:新SKU上市无历史、渠道停售、系统故障、节假日无发货记录等。处理策略需结合缺失比例和业务含义:

  • 删除策略:当缺失比例超过30%且该字段对预测无关键贡献时,直接删除该字段或样本。
  • 插补策略:时间序列数据优先使用前向填充(ffill)或线性插值;对于周期性数据,可用去年同期值或同周均值填充。
  • 标记策略:将缺失本身作为特征(如“是否缺货”“是否新品”),让模型学习缺失模式。

3.2.2 异常值检测

异常值不等于错误值,可能是真实的促销爆发或突发缺货。检测方法包括:

  1. 统计方法:3σ原则(正态分布)、IQR(四分位距)识别极端值。
  2. 业务规则:单日销量超过安全库存的5倍、负销量、超过历史最大值3倍等。
  3. 时序方法:STL分解后残差超过阈值,或使用孤立森林等无监督算法。
风险提示:不要机械地删除所有异常值。例如“双11”当天销量是平时的20倍,这并非错误,而是需要保留并作为事件特征。建议先标记、再分类、最后决定保留或修正。

3.2.3 口径统一与去重

同一SKU在不同系统中可能使用不同编码,同一订单可能被重复记录。清洗时需建立主数据映射表,统一SKU编码、渠道名称、时间时区。建议在清洗后输出一份数据质量报告,记录清洗前后行数、缺失率、异常值处理明细。

3.3 特征构造:让模型“看见”规律

特征工程的核心是将原始数据转化为模型可学习的信号。供应链预测中,最有效的三类特征为:滞后特征、滚动统计特征、日历特征。

3.3.1 滞后特征(Lag Features)

滞后特征直接引用过去某个时间点的值,用于捕捉自相关性。例如预测第t周的销量,可构造:

lag_1 = sales[t-1]   # 上周销量
lag_4 = sales[t-4]   # 上月同期
lag_52 = sales[t-52] # 去年同周

滞后阶数的选择需结合业务周期:快消品关注lag_1和lag_7(日数据),季节性商品关注lag_52(周数据)。

3.3.2 滚动统计特征(Rolling Statistics)

滚动统计特征通过滑动窗口计算历史数据的聚合值,帮助模型理解近期趋势和波动性。常用窗口为4周、8周、12周:

  • 滚动均值(rolling_mean):反映近期平均水平。
  • 滚动标准差(rolling_std):反映波动性,波动大时预测难度高。
  • 滚动最大值/最小值:捕捉峰值和谷值。
  • 滚动偏度/峰度:用于识别分布形态变化。

3.3.3 日历特征(Calendar Features)

日历特征将时间本身转化为模型可用的信息:

特征名称 示例 适用场景
星期几 周一=1,周日=7 周内波动明显的品类(如生鲜)
月份 1-12 季节性商品(如月饼、羽绒服)
是否节假日 0/1 春节、国庆等脉冲式需求
节前/节后偏移 -7~+7 捕捉节前囤货和节后回落
季度初/末 0/1 季度考核驱动的冲量

3.4 实战案例:某饮料企业周度销量预测的特征工程

背景与约束:某饮料企业需要预测华东区域200个SKU的未来4周销量,用于制定生产计划和原料采购。历史数据包含2年日度销售记录,但存在以下问题:部分SKU在冬季销量接近零、促销记录不完整、去年夏季有一周数据因系统故障缺失。

初始现象与目标:使用原始数据直接建模时,MAPE(平均百分比误差)高达38%,尤其在促销周和天气突变周误差超过60%。目标是将MAPE降至25%以内。

关键输入数据:

  • 销售数据:SKU、日期、销量、渠道(KA/流通/电商)
  • 促销数据:折扣率、活动类型(买赠/满减/特价)
  • 天气数据:日最高温度、降水量(来自气象API)
  • 日历数据:节假日、周末标记

分析判断过程:

  1. 缺失值处理:缺失的一周数据使用去年同周销量+今年趋势系数插补,并增加“是否插补”标记特征。
  2. 异常值检测:发现某KA渠道在“618”期间销量为平时15倍,判定为真实促销事件,保留并标记为“大促脉冲”。
  3. 特征构造:构造lag_1、lag_4、lag_52;滚动均值(4周、8周);温度高于30℃的天数;是否节假日;促销折扣率。
  4. 特征筛选:使用随机森林特征重要性排序,剔除重要性低于0.01的特征(如经济指标PMI,因周度预测中变化太小)。

实际操作步骤:

# 伪代码示例
df['lag_1'] = df.groupby('SKU')['sales'].shift(1)
df['lag_4'] = df.groupby('SKU')['sales'].shift(4)
df['rolling_mean_4'] = df.groupby('SKU')['sales'].transform(lambda x: x.rolling(4, min_periods=1).mean())
df['is_hot'] = (df['temp_max'] > 30).astype(int)
df['promo_discount'] = df['discount_rate'].fillna(0)

结果对比:加入特征工程后,模型MAPE从38%降至22%,促销周误差从60%降至31%。关键贡献特征为:lag_4、滚动均值_4、是否高温天、促销折扣率。

风险与代价:插补数据引入了约2%的偏差;滚动窗口过短(4周)在换季时产生滞后。复盘后调整为动态窗口(根据季节性自动选择6-12周)。

复盘经验:特征工程不是一次性工作,而是需要随业务周期迭代。建议每月回顾特征重要性,剔除失效特征,加入新发现的业务信号(如竞品调价、新渠道上线)。

3.5 常见误区与总结

  • 误区一:特征越多越好。高维稀疏特征会导致过拟合,尤其在SKU数量大、历史数据短的情况下。
  • 误区二:忽视时间顺序。构造滞后特征和滚动特征时必须按时间排序,避免未来数据泄漏。
  • 误区三:清洗过度。将“异常”全部删除会抹掉真实业务信号,建议先标记后决策。
  • 误区四:忽略业务可解释性。纯黑箱特征(如PCA降维后的成分)难以获得业务团队信任,尽量保留可解释特征。

总结:数据准备与特征工程是供应链预测项目的“地基工程”。数据来源决定了信息的上限,清洗质量决定了数据的可信度,特征构造决定了模型的学习效率。建议团队建立标准化的数据管道,将清洗和特征构造流程固化,以便在SKU扩展或业务调整时快速复用。