You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Prophet办公出勤预测优化:解决预测值为负与拟合度不足问题

办公出勤人数Prophet建模优化方案

问题背景

使用Python的Prophet库对15分钟间隔的办公出勤人数建模,已纳入节假日因素,每日、周度趋势拟合准确,但存在两个核心问题:

  1. 预测值出现现实中不可能的负数
  2. 观测数据峰值远超预测置信区间

原建模代码如下:

m = Prophet(holidays=holidays, weekly_seasonality=True, growth="flat")  # "logistic")
p_df = sdf[["OCCUPANCY_AVG"]].reset_index()
p_df.columns = ["ds", "y"]
p_df["cap"] = 180
df["floor"] = 0
m.fit(p_df)

future = m.make_future_dataframe(periods=24 * 60, freq="H")
future["cap"] = 180
future["floor"] = 0

forecast = m.predict(future)

fig1 = m.plot(forecast, xlabel="Date", ylabel="Headcount", include_legend=True)
fig2 = m.plot_components(forecast)

解决非负约束问题

方法1:从建模层面约束(推荐)

切换为logistic增长模型,同时修正原代码的笔误(将df["floor"] = 0改为p_df["floor"] = 0,确保训练数据携带非负下限约束):

m = Prophet(holidays=holidays, weekly_seasonality=True, growth="logistic")
p_df = sdf[["OCCUPANCY_AVG"]].reset_index()
p_df.columns = ["ds", "y"]
p_df["cap"] = 180
p_df["floor"] = 0  # 修正原代码的df为p_df,让训练数据生效约束
m.fit(p_df)

# 未来数据保持一致约束
future = m.make_future_dataframe(periods=24 * 60, freq="H")
future["cap"] = 180
future["floor"] = 0

方法2:后处理截断预测值

若不想切换增长模型,可直接对预测结果做非负截断,简单直接但约束性较弱:

forecast['yhat'] = forecast['yhat'].clip(lower=0)
forecast['yhat_lower'] = forecast['yhat_lower'].clip(lower=0)
forecast['yhat_upper'] = forecast['yhat_upper'].clip(lower=0)

提升拟合度与置信区间覆盖峰值

1. 增强季节性拟合能力

  • 提高周度季节性的傅里叶阶数(默认阶数3,可调整为8-12),增强对周内出勤波动的捕捉
  • 添加每日季节性(因数据是15分钟间隔,日内波动显著),同样可指定高阶数:
m = Prophet(holidays=holidays,
            weekly_seasonality=10,  # 提高周度季节性复杂度
            daily_seasonality=8,    # 添加并增强每日季节性
            growth="logistic")

2. 强化节假日效应

若节假日对出勤影响较大,可调高全局节假日权重(默认10,可尝试20-30),或针对特定节假日单独设置权重:

# 全局调高节假日权重
m = Prophet(holidays=holidays,
            weekly_seasonality=10,
            daily_seasonality=8,
            growth="logistic",
            holidays_prior_scale=20)

3. 添加外部回归因子

引入额外影响变量(如小时段、月度会议周期等),帮助模型捕捉更多波动:

# 给训练数据添加小时特征
p_df['hour'] = p_df['ds'].dt.hour
# 未来数据同步添加
future['hour'] = future['ds'].dt.hour

# 建模时加入外部回归
m = Prophet(holidays=holidays,
            weekly_seasonality=10,
            daily_seasonality=8,
            growth="logistic")
m.add_regressor('hour')
m.fit(p_df)

4. 调整置信区间宽度

将默认80%的置信区间调高至95%,让区间更宽以覆盖峰值:

m = Prophet(holidays=holidays,
            weekly_seasonality=10,
            daily_seasonality=8,
            growth="logistic",
            interval_width=0.95)

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 15:33:14