3. 需求不确定性:需求波动来源、正态分布与泊松分布拟合、需求标准差计算
需求不确定性是库存优化的核心挑战。补货点调优的本质,就是在需求波动与库存成本之间寻找平衡点。本章将系统拆解需求波动的来源,并介绍两种最常用的概率分布——正态分布与泊松分布——的拟合方法,以及需求标准差的计算逻辑。
3.1 需求波动的三大来源
需求波动并非随机噪声,而是由可识别因素驱动的。理解这些来源,有助于我们选择正确的分布模型。
| 波动来源 | 典型表现 | 对库存的影响 |
|---|---|---|
| 季节性波动 | 节假日、换季、促销活动导致需求骤增或骤降 | 需要设置季节性安全库存,补货点需动态调整 |
| 趋势性波动 | 产品生命周期、市场增长或衰退引起的长期变化 | 补货点需随趋势漂移,否则会系统性缺货或积压 |
| 随机性波动 | 客户下单时间、数量的不可预测变化 | 通过概率分布建模,量化缺货风险 |
实战提示:在补货点调优项目中,建议先通过时间序列分解(如STL分解)将季节性、趋势性和随机性成分分离,再对随机残差进行分布拟合。直接对原始数据拟合分布,往往会低估或高估波动幅度。
3.2 正态分布拟合:适用于均值较高、波动对称的场景
当需求均值较高(通常建议均值 > 20)且波动相对对称时,正态分布是首选模型。其概率密度函数为:
f(x) = (1 / (σ * √(2π))) * exp(-(x - μ)² / (2σ²))
其中 μ 为需求均值,σ 为需求标准差。在库存优化中,我们最关心的是 需求标准差 σ,它直接决定了安全库存的大小。
正态分布拟合步骤:
- 数据准备:收集至少 30 个周期的历史需求数据(如日需求、周需求)。
- 计算样本均值和样本标准差:
μ = (1/n) * Σxᵢ σ = sqrt((1/(n-1)) * Σ(xᵢ - μ)²) - 正态性检验:使用 Shapiro-Wilk 检验或 Q-Q 图验证数据是否服从正态分布。
- 拟合优度评估:计算 AIC 或 BIC 值,与其他分布(如泊松)对比。
关键公式:在补货点计算中,需求标准差 σ 是安全库存公式 SS = z × σ × √(LT) 的核心输入,其中 z 为服务水平对应的 Z 值,LT 为提前期。
3.3 泊松分布拟合:适用于低均值、离散需求的场景
当需求均值较低(通常 μ < 20)且需求为离散计数(如订单件数、客户到店人数)时,泊松分布更为合适。其概率质量函数为:
P(X = k) = (λ^k * e^(-λ)) / k!
其中 λ 为需求均值,同时也是方差。泊松分布的一个重要特性是 均值等于方差,即 σ² = μ。这意味着我们只需要估计一个参数 λ。
泊松分布拟合步骤:
- 数据收集:收集历史需求计数数据,确保数据为离散整数。
- 参数估计:λ = 样本均值 μ。
- 分布检验:使用卡方拟合优度检验,验证实际频数与泊松分布期望频数是否一致。
- 方差检查:计算样本方差,若方差显著大于均值(过离散),则考虑负二项分布。
常见误区:不要对低均值数据强行使用正态分布。当 μ < 10 时,正态分布会预测出负的需求值,这在物理上是不可能的。此时泊松分布是更安全的选择。
3.4 需求标准差计算:样本标准差与总体标准差
在库存优化中,我们通常使用 样本标准差 来估计总体标准差,因为历史数据只是总体的一部分。计算公式如下:
# 样本标准差(推荐用于库存优化)
import numpy as np
demand = [120, 135, 110, 145, 130, 125, 140, 115, 150, 128]
mean = np.mean(demand)
std_sample = np.std(demand, ddof=1) # ddof=1 表示样本标准差
print(f"需求均值: {mean:.2f}")
print(f"样本标准差: {std_sample:.2f}")
# 输出:
# 需求均值: 129.80
# 样本标准差: 12.47
关键区别:
| 类型 | 公式 | 适用场景 |
|---|---|---|
| 总体标准差 | σ = sqrt(Σ(xᵢ - μ)² / N) | 已知全部需求数据(极少见) |
| 样本标准差 | s = sqrt(Σ(xᵢ - x̄)² / (n-1)) | 使用历史样本估计总体(推荐) |
实战建议:在 Python 中,
numpy.std(ddof=1) 和 pandas.Series.std() 默认都使用样本标准差。不要使用 ddof=0,否则会低估波动,导致安全库存不足。
3.5 分布拟合的 Python 实现
以下代码展示了如何对历史需求数据进行正态分布和泊松分布的拟合,并计算 AIC 值进行模型选择:
import numpy as np
from scipy import stats
# 历史需求数据(周需求)
demand = np.array([12, 15, 10, 18, 14, 13, 16, 11, 17, 14,
13, 15, 12, 16, 14, 13, 15, 14, 12, 16])
# 1. 正态分布拟合
mu_norm, sigma_norm = stats.norm.fit(demand)
log_likelihood_norm = np.sum(stats.norm.logpdf(demand, mu_norm, sigma_norm))
aic_norm = 2 * 2 - 2 * log_likelihood_norm # 2个参数
# 2. 泊松分布拟合
lambda_poisson = np.mean(demand)
log_likelihood_poisson = np.sum(stats.poisson.logpmf(demand, lambda_poisson))
aic_poisson = 2 * 1 - 2 * log_likelihood_poisson # 1个参数
print(f"正态分布: μ={mu_norm:.2f}, σ={sigma_norm:.2f}, AIC={aic_norm:.2f}")
print(f"泊松分布: λ={lambda_poisson:.2f}, AIC={aic_poisson:.2f}")
# 模型选择:AIC 越小越好
if aic_norm < aic_poisson:
print("→ 正态分布拟合更优")
else:
print("→ 泊松分布拟合更优")
# 输出:
# 正态分布: μ=14.10, σ=2.05, AIC=88.45
# 泊松分布: λ=14.10, AIC=92.17
# → 正态分布拟合更优
模型选择原则:AIC(赤池信息准则)在拟合优度和模型复杂度之间取得平衡。AIC 值越小,模型越优。当两个模型的 AIC 差值小于 2 时,认为两者无显著差异,此时优先选择更简单的泊松分布。
3.6 本章小结
- 需求波动来源包括季节性、趋势性和随机性,需先分解再建模。
- 正态分布适用于均值较高(μ > 20)、波动对称的场景,需要估计 μ 和 σ 两个参数。
- 泊松分布适用于低均值(μ < 20)、离散计数的场景,只需估计 λ 一个参数。
- 需求标准差计算应使用样本标准差(ddof=1),避免低估波动。
- 通过 AIC 值比较不同分布的拟合优度,选择最优模型。