一、为什么要做“预测 + 补货一体化”

在大多数企业中,预测和补货是割裂的:

  • 预测团队 → 给一个“销量预测”

  • 供应链 → 再用规则做补货

问题是:

预测不懂库存,补货不懂需求

导致结果:

  • 断货(低估需求)

  • 积压(高估需求)

  • 调拨混乱(没有全局视角)


✅ 正确方式

构建一体化链路:

历史数据 → 需求预测(LightGBM)
              ↓
        真实需求还原
              ↓
        库存策略计算(ROP / 安全库存)
              ↓
        补货建议输出

二、模型整体架构设计

1. 数据层(Data Layer)

数据来源建议分为五类:

类型

字段示例

销量数据

日销量、周销量、销售间隔

库存数据

在库、在途、可售库存

商品属性

分类、品牌、生命周期

策略数据

ABC分类、补货周期、Lead Time

外部因素

节假日、促销、价格


2. 特征层(Feature Layer)

核心原则:

不要让模型猜,让模型“知道”


三、特征工程设计(核心)

1️⃣ 时间特征

df['day_of_week'] = df['date'].dt.weekday
df['is_weekend'] = df['day_of_week'].isin([5,6]).astype(int)
df['month'] = df['date'].dt.month

2️⃣ 销量特征(需求惯性)

df['sales_7d_avg'] = df['sales'].rolling(7).mean()
df['sales_14d_avg'] = df['sales'].rolling(14).mean()
df['sales_30d_avg'] = df['sales'].rolling(30).mean()

df['sales_week_ratio'] = df['sales_7d_avg'] / df['sales_14d_avg']

3️⃣ 库存特征(关键差异点🔥)

df['stock_cover_days'] = df['stock'] / (df['sales_7d_avg'] + 1)
df['is_oos'] = (df['stock'] == 0).astype(int)
df['total_supply'] = df['stock'] + df['in_transit']

👉 核心意义:

区分“卖不动” vs “没货卖”


4️⃣ 商品特征

df['new_product_days'] = (df['date'] - df['launch_date']).dt.days

df['is_new'] = (df['new_product_days'] < 30).astype(int)

5️⃣ 策略特征

df['abc_class'] = df['abc_class'].map({'A':3, 'B':2, 'C':1})

df['safety_stock_ratio'] = df['safety_stock'] / (df['sales_30d_avg'] + 1)

df['replenish_cycle'] = df['replenish_days']
df['lead_time'] = df['lead_time_days']

四、关键难点:真实需求还原

问题:

销量 ≠ 真实需求

当库存为0时:

销量 = 被截断的需求


解决方案:

方法1:剔除断货样本

df = df[df['is_oos'] == 0]

方法2:需求修正(推荐)

df['adjusted_sales'] = df['sales']

df.loc[df['is_oos'] == 1, 'adjusted_sales'] = df['sales_7d_avg']

方法3:加权训练

df['weight'] = 1
df.loc[df['is_oos'] == 1, 'weight'] = 0.5

五、模型训练(LightGBM)

1. 数据准备

features = [
    'sales_7d_avg','sales_14d_avg','sales_30d_avg',
    'stock_cover_days','total_supply',
    'abc_class','lead_time','replenish_cycle',
    'day_of_week','month'
]

target = 'adjusted_sales'

2. 模型训练

import lightgbm as lgb

train_data = lgb.Dataset(
    df[features],
    label=df[target],
    weight=df.get('weight', None)
)

params = {
    'objective': 'regression',
    'metric': 'rmse',
    'learning_rate': 0.05,
    'num_leaves': 31,
    'max_depth': -1
}

model = lgb.train(params, train_data, num_boost_round=500)

六、多SKU建模策略(非常关键🔥)

❌ 不建议:一个模型打全部SKU

✅ 推荐:分层建模

类型

建议

新品

单独模型

稳定SKU

主模型

长尾SKU

简化模型


示例:

df_A = df[df['abc_class'] == 3]
df_B = df[df['abc_class'] == 2]
df_C = df[df['abc_class'] == 1]

七、补货决策模型(核心落地)

预测只是第一步,关键是:

怎么转成“要补多少货”


1. 需求预测

df['forecast'] = model.predict(df[features])

2. 补货核心公式

补货量 = 未来需求 + 安全库存 - 当前库存 - 在途

3. Python实现

df['demand_lt'] = df['forecast'] * df['lead_time']

df['reorder_point'] = df['demand_lt'] + df['safety_stock']

df['replenish_qty'] = (
    df['reorder_point']
    - df['stock']
    - df['in_transit']
)

df['replenish_qty'] = df['replenish_qty'].clip(lower=0)

八、进阶优化(高阶能力)

1️⃣ 调拨建模

增加特征:

df['other_warehouse_stock']
df['transfer_time']

2️⃣ 价格/促销敏感性

df['price_change_rate']
df['is_promo']

3️⃣ 多仓协同

核心目标:

不是单仓最优,而是全局库存最优


九、常见坑(非常重要)

❌ 1. 直接用销量做预测

→ 忽略断货


❌ 2. 不加库存特征

→ 模型误判需求


❌ 3. SKU混在一起训练

→ 规律冲突


❌ 4. 只调参数

→ 忽略特征才是核心


十、总结

LightGBM 在供应链中的本质不是“算法工具”,而是:

把业务经验结构化的载体


一句话总结:

模型效果 = 50%业务理解 + 40%特征工程 + 10%模型参数

十一、适用场景

  • 连锁门店补货

  • 多仓库存协同

  • 电商SKU预测

  • 新品备货决策