我正在运行一个预测模型来预测呼入呼叫量。我花了很多时间清理数据,运行日志标度和超参数调优--最终得到了“好”的MAPE (平均百分比误差)。
在这一点上,我的问题是模型总是拟合不足。尤其是在这个月的前12天--甚至在这个月的前6天。由于运营原因,这些天的呼叫量总是很高。随着交易量在下个月初开始攀升,它们也在接近月底时开始增加。
实际数据是蓝点,预测数据是灰色线条。这只是一个月,但它代表了所有其他月份的月度季节性:

为简单起见,我将只包含模型的详细信息,而不考虑所有的数据清理过程。如果有帮助,我可以提供更多的信息,但到目前为止,我得到的反馈是,额外的细节只是把水搅乱了。真正重要的是,对构建模型的数据运行boxcox转换后的结果,以及对模型输出的数据运行反向boxcox后的结果:
# Create Model
M = Prophet(
changepoint_prior_scale = 15,
changepoint_range = .8,
growth='linear',
seasonality_mode= 'multiplicative',
daily_seasonality=False,
weekly_seasonality=False,
yearly_seasonality=False,
holidays=Holidays
).add_seasonality(
name='monthly',
period=30.5,
fourier_order = 20,
prior_scale = 45
).add_seasonality(
name='daily',
period=1,
fourier_order=75,
prior_scale=20
).add_seasonality(
name='weekly',
period=7,
fourier_order=75,
prior_scale=30
).add_seasonality(
name='yearly',
period = 365.25,
fourier_order = 30,
prior_scale = 15)总体而言,我希望全面改善不适应的情况-但特别是在月初和月底。我试着增加changepoint_range来放松模型,但结果并不明显。我也试过增加“每月”季节性的prior_scale,但没有比上面的截图更好的结果。
我有点不知所措。有没有一种建模技术可以让我用FaceBook Prophet模型来解决这个问题?有没有办法添加一个回归器,为前12天和最后7天分配特定的季节性?我做了一些研究,不确定你是否可以和/或如何工作。
任何帮助都将不胜感激。
作为更新,我已经尝试增加change_point范围和变化点之前的比例,没有任何影响。将尝试减少训练数据量(目前使用4年)。
发布于 2021-11-20 04:51:12
我想我找到了一个可行的解决方案,将其记录下来作为解决方案,以防其他任何人在未来遇到类似的问题。
因为我知道这种行为是周期性的,我知道它为什么会存在(月初有两个不同的月度计费周期,月底的交易量反复增加,这是不合适的),我使用Prophet文档为这些特定的时期创建了额外的季节性回归变量。
我从定义季节的函数开始(根据Prophet文档,示例是NFL on-季和NFL淡季):
def is_1st_billing_season(ds):
date = pd.to_datetime(ds)
return (date.day >= 1 and date.day <= 6)
def is_2nd_billing_season(ds):
date = pd.to_datetime(ds)
return (date.day >= 7 and date.day <= 12)
def EOM (ds):
date = pd.to_datetime(ds)
return (date.day >= 25 and date.day <= 31)然后我将这些函数应用到我的数据帧中:
#Create Additional Seasonal Categories
Box_Cox_Data['1st_season'] = Call_Data['ds'].apply(is_1st_billing_season)
Box_Cox_Data['2nd_season'] = Call_Data['ds'].apply(is_2nd_billing_season)
Box_Cox_Data['EOM'] = Call_Data['ds'].apply(EOM)然后,我更新了我的模型,以包括额外的季节回归变量:
# Create Model
M = Prophet(
changepoint_prior_scale = 15,
changepoint_range = .8,
growth='linear',
seasonality_mode= 'multiplicative',
daily_seasonality=False,
weekly_seasonality=False,
yearly_seasonality=False,
holidays=Holidays
).add_seasonality(
name='monthly',
period=30.5,
fourier_order = 20,
prior_scale = 45
).add_seasonality(
name='daily_1st_season',
period=1,
fourier_order=75,
prior_scale=20,
condition_name='1st_season'
).add_seasonality(
name='daily_2nd_season',
period=1,
fourier_order=75,
prior_scale=20,
condition_name='2nd_season'
).add_seasonality(
name='daily_EOM_season',
period=1,
fourier_order=75,
prior_scale=20,
condition_name='EOM'
).add_seasonality(
name='weekly',
period=7,
fourier_order=75,
prior_scale=30
).add_seasonality(
name='yearly',
period = 365.25,
fourier_order = 30, #CHECK THIS
prior_scale = 15)
#Fit Model
M.fit(Box_Cox_Data)
# Create Future Dataframe (in Hours)
future = M.make_future_dataframe(freq='H', periods = Hours_Needed)
future['1st_season'] = future['ds'].apply(is_1st_billing_season)
future['2nd_season'] = future['ds'].apply(is_2nd_billing_season)
future['EOM'] = future['ds'].apply(EOM)
# Predict Future Values
forecast = M.predict(future)最终结果看起来要好得多:

为了完全透明,此屏幕截图的时间与原始截图略有不同。对于这个项目,我的起点并不是非常重要(对未来时间段的预测是主要关注点),我意外地对不同的时间框架运行了交叉验证,但最终结果是在我迄今为止看到的所有时间框架内都能得到更好的季节性预测。
https://stackoverflow.com/questions/70028705
复制相似问题