当前位置:首页>python>下月备货算不准?Python时间序列预测实战

下月备货算不准?Python时间序列预测实战

  • 2026-10-12 13:00:51
下月备货算不准?Python时间序列预测实战

下月备货算不准?Python时间序列预测实战

"下个月咱大概能卖多少?备多少货合适?"

之前我习惯拍脑袋:上个月卖200,这个月估个210,理由全凭感觉。如果直接拿去定目标的话,要么压一仓库存,要么中途断货,两头不讨好。

销量不是随机数,它有自己的节奏。

后面翻了过去18个月的销量,发现里面藏着两样东西:一个慢慢往上走的趋势,一个每年都差不多的季节波动。比如一到年底2个月就猛涨,春节后大幅回落,用行业术语说就是"基于历史数据预判未来"叫预测性分析,是商业分析里单独的一类,核心就是时间序列。

把这两个规律拆开看,预测就可以分成三步走。

第一步:把历史销量读进来

用 pandas,一段加法模型就够用,不用装任何额外包。趋势用移动平均抹平,季节用同月均值算出来。

import pandas as pdimport numpy as np# 过去18个月销量,换成你自己的数据sales = pd.Series(    [120, 135, 150, 142, 160, 178, 190, 175, 168, 185, 200, 230,     130, 145, 158, 150, 172, 188],    index=pd.date_range("2025-01-01", periods=18, freq="MS"))# 趋势项:12期移动平均,抹平波动看大方向trend = sales.rolling(12, min_periods=6).mean()# 季节项:去掉趋势后,看每个月相对趋势的偏离detrend = sales - trendseason = detrend.groupby(detrend.index.month).mean().reindex(range(1, 13)).fillna(0)

第二步:趋势外推,季节叠回

趋势用最近斜率往外推,季节用历史均值加回去,一个函数全部搞定。

def forecast_monthly(sales, periods=3):    trend = sales.rolling(12, min_periods=6).mean()    detrend = sales - trend    season = detrend.groupby(detrend.index.month).mean().reindex(range(1, 13)).fillna(0)    tc = trend.dropna()    slope = tc.diff().mean()          # 每月平均增量    last = tc.iloc[-1]    future = pd.date_range(sales.index[-1] + pd.offsets.MonthBegin(1), periods=periods, freq="MS")    fc = [round(last + slope * (i + 1) + season.get(m.month, 0)) for i, m in enumerate(future)]    return pd.Series(fc, index=future, name="预测销量")print(forecast_monthly(sales, 3))

跑出来下三个月大概是 213、197、191。八月份因为季节回落,预测值反而比七月低。这正是趋势和季节"打架"的结果,如果拍脑袋很容易漏掉这一层。

第三步:别光看预测,先回测

预测完一定先验证准不准。把最后三个月藏起来当"未知",用前面的数据预测,再和真实值比误差。

pred = forecast_monthly(sales.iloc[:-3], 3)true = sales.iloc[-3:]mape = (abs(pred - true) / true).mean() * 100print(f"回测MAPE={mape:.1f}%")   # 约 10%

这版示例数据回测下来 MAPE 在 10% 左右,也就是平均误差一成。可以接受,但不能当成精确值。

避坑

数据至少要攒够 12 个月。如果只有半年数据,季节项根本算不出来,预测就是瞎蒙了。

大促和节假日要单独标记。别让它污染"正常月"的季节值,不然每年都多算一笔。

MAPE 超过 15% 就别当真了。先查一下数据有没有异常缺录,千万别直接拿去定目标。

预测是给你定目标的参考值,不是圣旨。要结合业务判断再做拍板,比任何模型都稳。

最新文章

随机文章