paper2skills Playbook

HiFoReAd 多层时序预测调和 - 母婴跨境补货分层一致性

Skill-Hierarchical-Demand-Forecasting-Reconciliation · 03-时间序列

causalexperimentforecastingoptimization供应链与补货WF-A 智能补货
年化 ROI800-1500 万元
实现难度⭐⭐⭐☆☆
业务优先级⭐⭐⭐☆☆
业务视角
适用角色供应链负责人 / 采购负责人 · 运营负责人 · 财务负责人
适用平台Amazon FBA · 海外仓 · 多市场多仓
什么情况下用大促前备货总是不是多了就是少了;新品上线第一个月断货,再补又积压;年底预算不知道各月目标怎么定
成功是什么样的提前 4-8 周准确预判各 SKU 需求峰值,库存积压减少 30%,断货率降低 50%
业务痛点
备货总是压货或断货旺季淡季波动太大预测不准补货周期 30 天但预测只看 7 天

1. 解决的问题

Momcozy 60+ SKU × 多仓(上海/香港/海外仓) × 多市场(US/DE/JP),各层独立预测加总 30-50% 不一致;采购按 SKU 下单,但财务按市场聚合,两边数字对不上,月底对账 2-3 PM 天纯人工调和 - 数据要求:历史 SKU/仓/市场 三层销售时序 + 加总矩阵 S - HiFoReAd 配置: - Stage 1: LGBM + AutoETS 三月预测

2. 核心算法逻辑

母婴跨境补货场景下,各 SKU/仓/市场层独立预测后,加总不一致(SKU 求和 ≠ 仓库 ≠ 总量),导致采购计划矛盾、财务对账打架. HiFoReAd 用多阶段调和:① 三模型集成基础预测 → ② TopDown + 谐波对齐保留季节性 → ③ MinTrace 投影使全局误差方差最小 → ④ 末层 stratified scaling 强制叶节点一致. Walmart Ads 已生产部署,各层完全一致.

3. 业务应用场景

- 业务问题:Momcozy 60+ SKU × 多仓(上海/香港/海外仓) × 多市场(US/DE/JP),各层独立预测加总 30-50% 不一致;采购按 SKU 下单,但财务按市场聚合,两边数字对不上,月底对账 2-3 PM 天纯人工调和 - 数据要求:历史 SKU/仓/市场 三层销售时序 + 加总矩阵 S - HiFoReAd 配置: - Stage 1: LGBM + AutoETS 三月预测,各层独立 - Stage 2: MinTrace + mint_shrink(协方差收缩,样本量小时鲁棒) - Stage 3: Harmonic alignment 保留 SKU 级月度季节性

- 业务问题:Momcozy 月度采购计划(大贸海运,提前 60 天)与周度补货触发(海外仓 FBA,提前 7 天)不一致,618/双11 备货期间月度预算与周度爆发严重错配 - 数据要求:月度采购历史 + 周度销售历史 + 大促日历 - HiFoReAd 配置: - Stage 1: 月度层 MSTL+ETS 抽取年度季节性,周度层 Prophet 捕捉短期峰谷 - Stage 2: Temporal MinTrace 保证 $\sum_{w \in \text{month}} \tilde{y}_w = \tilde{y}_{\text{month}}$ - Stage 3: Strati

4. 输入数据要求

请查看原始代码模板获取输入规格。

5. 输出结果

请查看原始代码模板获取输出规格。

6. 业务价值 / ROI

  • 极易:Nixtla HierarchicalForecast 开源完整,`pip install` 即可
  • 易处:MinTrace 是凸优化问题,有解析解,无需训练
  • 难处:加总矩阵 S 需要业务专家确认层级关系
  • 难处:误差方差 W 估计依赖足够历史数据(论文用 mint_shrink 协方差收缩)

7. 代码模板

代码块数量:2 · 路径:未检测到

"""
HiFoReAd 多层时序预测调和最小骨架
主论文: arXiv:2412.14718 (Walmart, BigData 2024)
开源参考: Nixtla HierarchicalForecast https://github.com/Nixtla/hierarchicalforecast
依赖: pip install hierarchicalforecast statsforecast pandas numpy
"""
from __future__ import annotations
from typing import Dict, List

import numpy as np


def build_summing_matrix(hierarchy: Dict[str, List[str]]) -> np.ndarray:
    """构造层级加总矩阵 S
    hierarchy: {parent: [children]} 描述层级关系
    返回 S[i,j] = 1 表示节点 i 包含叶子 j
    """
    leaves = []
    for parent, children in hierarchy.items():
        for c in children:
            if c not in hierarchy:
                leaves.append(c)

    nodes = ["Total"] + sorted(hierarchy.keys() - {"Total"}) + sorted(leaves)
    node_idx = {n: i for i, n in enumerate(nodes)}
    n, m = len(nodes), len(leaves)
    S = np.zeros((n, m))

    leaf_idx = {leaf: j for j, leaf in enumerate(leaves)}
    for leaf in leaves:
        S[node_idx[leaf], leaf_idx[leaf]] = 1.0

    def collect_leaves(node):
        if node in leaf_idx:
            return [node]
        result = []
        for child in hierarchy.get(node, []):
            result.extend(collect_leaves(child))
        return result

    for node in nodes:
        if node not in leaf_idx:
            for leaf in collect_leaves(node):
                S[node_idx[node], leaf_idx[leaf]] = 1.0

    return S, nodes, leaves


def mint_reconcile(y_hat: np.ndarray, S: np.ndarray, W: np.ndarray = None) -> np.ndarray:
    """MinTrace 调和投影(Eq. core)
    y_hat: (n,) 各层独立预测
    S: (n, m) 加总矩阵
    W: (n, n) 误差方差矩阵,默认单位矩阵 (OLS)
    """
    n = S.shape[0]
    if W is None:
        W = np.eye(n)
    W_inv = np.linalg.inv(W)
    G = np.linalg.inv(S.T @ W_inv @ S) @ S.T @ W_inv
    return S @ G @ y_hat

8. 论文来源

  • 2302.05650
  • 2412.14718