大家好,又见面了,我是你们的朋友全栈君。
例子代码
https://github.com/lilihongjava/prophet_demo/tree/master/seasonality_holiday_effects__regressors
一、假期和特殊事件建模
如果有假期或其他想要建模的重复事件,则必须为它们创建dataframe。对于dataframe,每个假期一行有两列(holiday
节假日和ds
日期戳)。它必须包括所有出现的假期,包括过去(历史数据),以及将来(待预测的时间)。如果假期没出现在待预测的时间里,那么Prophet 不会其包含在预测中。
dataframe还可以包括lower_window
和upper_window两
列,它们将假日扩展到该日期的前后[Lower_Window,Upper_Window]天。例如,如果你想在圣诞节之外加上平安夜,那么就lower_window=-1,upper_window=0
这样设置。如果你想在感恩节之外加上黑色星期五,那么就lower_window=0,upper_window=1这样设置
。还可以包含一个prior_scale
列,以便为每个假日分别设置先前的比例,如下所述。
在这里,我们创建一个dataframe,其中包括Peyton Manning所有季后赛出场的日期:
# Python
playoffs = pd.DataFrame({
'holiday': 'playoff',
'ds': pd.to_datetime(['2008-01-13', '2009-01-03', '2010-01-16',
'2010-01-24', '2010-02-07', '2011-01-08',
'2013-01-12', '2014-01-12', '2014-01-19',
'2014-02-02', '2015-01-11', '2016-01-17',
'2016-01-24', '2016-02-07']),
'lower_window': 0,
'upper_window': 1,
})
superbowls = pd.DataFrame({
'holiday': 'superbowl',
'ds': pd.to_datetime(['2010-02-07', '2014-02-02', '2016-02-07']),
'lower_window': 0,
'upper_window': 1,
})
holidays = pd.concat((playoffs, superbowls))
上面我们将超级碗日包括在季后赛和超级碗赛中。这意味着超级碗效应将在季后赛效应之外的额外叠加。
创建dataframe后,通过使用holidays
参数传递假日效应,将其包含在预测中。在这里,我们使用快速入门案例中的Peyton Manning数据:
# Python
m = Prophet(holidays=holidays)
forecast = m.fit(df).predict(future)
假日效应可以在forecast
dataframe中看到:
# Python
forecast[(forecast['playoff'] + forecast['superbowl']).abs() > 0][
['ds', 'playoff', 'superbowl']][-10:]
ds playoff superbowl
2190 2014-02-02 1.224102 1.197251
2191 2014-02-03 1.912033 1.459945
2532 2015-01-11 1.224102 0.000000
2533 2015-01-12 1.912033 0.000000
2901 2016-01-17 1.224102 0.000000
2902 2016-01-18 1.912033 0.000000
2908 2016-01-24 1.224102 0.000000
2909 2016-01-25 1.912033 0.000000
2922 2016-02-07 1.224102 1.197251
2923 2016-02-08 1.912033 1.459945
假期效应也将出现在组件图中,我们可以看到季后赛的几天里有一个高峰,超级碗有一个特别大的峰值:
# Python
fig = m.plot_components(forecast)
假期可以使用plot_forecast_component
函数(import fbprophet.plot包
)绘制,就像plot_forecast_component(m, forecast, 'superbowl')
绘制超级碗假期组件一样。
二、内置国家假期
可以使用add_country_holidays
方法设置内置的国家/地区特定假日集合。通过country_name指定国家/地区的名称,然后在上述holidays
参数指定的假日外,将包含该国家主要假日:
# Python
m = Prophet(holidays=holidays)
m.add_country_holidays(country_name='US')
m.fit(df)
可以通过查看模型的train_holiday_names
(Python)属性来查看包含哪些假期:
# Python
m.train_holiday_names
0 playoff
1 superbowl
2 New Year's Day
3 Martin Luther King, Jr. Day
4 Washington's Birthday
5 Memorial Day
6 Independence Day
7 Labor Day
8 Columbus Day
9 Veterans Day
10 Thanksgiving
11 Christmas Day
12 Christmas Day (Observed)
13 Veterans Day (Observed)
14 Independence Day (Observed)
15 New Year's Day (Observed)
每个国家的假期都由holidays包
提供。可用国家/地区列表以及要使用的国家/地区名称可在此链接上找到: https://github.com/dr-prodigy/python-holidays。除了这些国家,Prophet还包括这些国家的假期:巴西(BR),印度尼西亚(ID),印度(IN),马来西亚(MY),越南(VN),泰国(TH),菲律宾(PH),土耳其( TU),巴基斯坦(PK),孟加拉国(BD),埃及(EG),中国(CN)和俄罗斯(RU)。
在Python中,大多数假期都是确定性计算的,因此可用于任何日期范围; 如果日期超出该国家支持的范围,将会发出警告。在R语言中,假日日期是从1995年到2044年计算的,并存储在 data-raw/generated_holidays.csv
中。如果需要更宽的日期范围,可以使用此脚本将该文件替换为不同的日期范围:https://github.com/facebook/prophet/blob/master/python/scripts/generate_holidays_file.py。
如上所述,国家级假期将显示在组件图中:
# Python
forecast = m.predict(future)
fig = m.plot_components(forecast)
三、季节性的傅立叶级数
使用傅里叶级数的部分和来估计季节性。有关完整的详细信息,请参阅本文,以及维基百科上的此图,以了解傅里叶级数的部分和如何逼近非周期信号。部分和(级数)的项是一个参数,用于确定季节性变化的速度。为了说明这一点,继续使用快速入门例子中的Peyton Manning数据。每年季节性的默认傅里叶级数为10,产生了这种拟合:
# Python
from fbprophet.plot import plot_yearly
m = Prophet().fit(df)
a = plot_yearly(m)
默认值通常是合适的,但是当季节性需要拟合更高频率的变化时,值是可以增加,并且通常不太平滑。在实例化模型时,可以为每个内置季节性指定傅立叶级数,此处值增加到20:
# Python
from fbprophet.plot import plot_yearly
m = Prophet(yearly_seasonality=20).fit(df)
a = plot_yearly(m)
增加傅里叶项的数量可以使季节性拟合更快的变化周期,但也可能导致过度拟合:N个傅里叶项对应于用于建模周期的2N变量
四、指定自定义季节性
如果时间序列长度超过两个周期,Prophet将默认拟合每周和每年的季节性。对于每日一次的时间序列,将拟合每日季节性。可以使用add_seasonality
方法添加其他季节性(每月,每季度,每小时)。
此函数的输入是名称,季节性的周期,以及季节性的傅里叶级数。作为参考,默认情况下,Prophet对于每周季节性的傅立叶级数为3,每年季节性使用10次。可选输入add_seasonality
为季节性组件的先验scale – 这将在下面讨论。
作为一个例子,这里我们拟合来自快速入门例子的Peyton Manning数据,但用每月季节性取代每周季节性。月度季节性将出现在组件图中:
# Python
m = Prophet(weekly_seasonality=False)
m.add_seasonality(name='monthly', period=30.5, fourier_order=5)
forecast = m.fit(df).predict(future)
fig = m.plot_components(forecast)
五、季节性其他因素
在某些情况下,季节性可能取决于其他因素,例如每周季节性模式,在夏季是不同于一年中其余时间,或者每日季节性模式,在周末是不同于工作日。这些类型的季节性可以使用条件季节性来建模。
使用快速入门中的Peyton Manning的数据。默认的每周季节性假设每周季节性的模式在全年都是相同的,但我们希望每个季节性的模式在赛季(每个星期天有比赛时)和休赛期间是不同的。我们可以使用有条件的季节性来构建单独的赛季和休赛季的每周季节性。
首先,我们在dataframe中添加一个布尔列,指定每个日期是在赛季还是休赛季:
# Python
def is_nfl_season(ds):
date = pd.to_datetime(ds)
return (date.month > 8 or date.month < 2)
df['on_season'] = df['ds'].apply(is_nfl_season)
df['off_season'] = ~df['ds'].apply(is_nfl_season)
然后我们禁用内置的每周季节性,并将其替换为将这些列指定为条件的两个每周季节性。这意味着季节性仅适用于condition_name
列为True的日期
。还必须将这个列添加到我们正在进行预测的future
dataframe中。
# Python
m = Prophet(weekly_seasonality=False)
m.add_seasonality(name='weekly_on_season', period=7, fourier_order=3, condition_name='on_season')
m.add_seasonality(name='weekly_off_season', period=7, fourier_order=3, condition_name='off_season')
future['on_season'] = future['ds'].apply(is_nfl_season)
future['off_season'] = ~future['ds'].apply(is_nfl_season)
forecast = m.fit(df).predict(future)
fig = m.plot_components(forecast)
现在,两个季节都出现在上面的组成图中。我们可以看到,在每个星期天进行比赛的赛季期间,周日和周一有大幅增加,而在休赛期完全没有。
六、节假日和季节性的先验scale
如果发现假期过度拟合,可以使用holidays_prior_scale
参数调整先验scale以使之平滑。默认情况下,此参数为10,这提供了很少的正则化。减少此参数会抑制假日效应:
# Python
m = Prophet(holidays=holidays, holidays_prior_scale=0.05).fit(df)
forecast = m.predict(future)
forecast[(forecast['playoff'] + forecast['superbowl']).abs() > 0][
['ds', 'playoff', 'superbowl']][-10:]
ds playoff superbowl
2190 2014-02-02 1.205038 0.969811
2191 2014-02-03 1.854391 0.986626
2532 2015-01-11 1.205038 0.000000
2533 2015-01-12 1.854391 0.000000
2901 2016-01-17 1.205038 0.000000
2902 2016-01-18 1.854391 0.000000
2908 2016-01-24 1.205038 0.000000
2909 2016-01-25 1.854391 0.000000
2922 2016-02-07 1.205038 0.969811
2923 2016-02-08 1.854391 0.986626
和以前相比,假日效应的幅度减小了,特别是对于观察量最少的超级碗。有一个参数seasonality_prior_scale
可以类似地调整季节性模型拟合数据的程度。
可以在假期的dataframe中包含一列prior_scale来设置先验
scales。季节性的先验
scales可以作为参数传递给add_seasonality
。例如,可以使用以下方式设置每周季节性的先验
scales:
# Python
m = Prophet()
m.add_seasonality(
name='weekly', period=7, fourier_order=3, prior_scale=0.1)
七、额外回归量
可以使用add_regressor
方法或函数将额外回归量添加到模型的线性部分。具有回归量值的列都需要存在于拟合和预测dataframe中。例如,我们可以在NFL赛季期间为周日增加额外的影响。在组件图上,此效果将显示在“extra_regressors”图中:
# Python
def nfl_sunday(ds):
date = pd.to_datetime(ds)
if date.weekday() == 6 and (date.month > 8 or date.month < 2):
return 1
else:
return 0
df['nfl_sunday'] = df['ds'].apply(nfl_sunday)
m = Prophet()
m.add_regressor('nfl_sunday')
m.fit(df)
future['nfl_sunday'] = future['ds'].apply(nfl_sunday)
forecast = m.predict(future)
fig = m.plot_components(forecast)
通过创建过去和未来nfl_sunday的list,也可以使用上述“holidays”来处理nfl_sunday。add_regressor
函数提供了更通用的接口,用于定义额外的线性回归量,特别是不要求回归量是二进制指示符。另一个时间序列可以用作回归量,尽管它的未来值必须是已知的。
此jupyter代码展示了一个使用天气因素作为预测自行车使用的额外回归量的示例,并提供了如何将其他时间序列作为额外回归量包含在内的很好的说明。
add_regressor
函数有指定先验scale的可选参数(默认情况下使用假日先验scale)以及参数回归量是否标准化 – 请参阅help(Prophet.add_regressor)查看相关参数 。请注意,必须在拟合模型之前添加回归量。
额外的回归量必须知道历史和未来的日期。因此,它必须是具有已知未来值(例如nfl_sunday
),或者在其他地方单独预测过的结果。如果回归量在整个历史数据中保持不变,Prophet也会引起错误,因为没有任何东西可以拟合它。
额外的回归量被置于模型的线性分量中,因此底层模型是时间序列依赖于额外回归量作为加法或乘法因子(参见下一节的乘法季节性 )。
参考资料:
https://facebook.github.io/prophet/docs/seasonality,_holiday_effects,_and_regressors.html
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/151787.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...