%matplotlib inline
from fbprophet import Prophet
import pandas as pd
from matplotlib import pyplot as plt
import numpy as np
import logging
logging.getLogger('fbprophet').setLevel(logging.ERROR)
import warnings
warnings.filterwarnings("ignore")
df = pd.read_csv('examples/example_wp_log_peyton_manning.csv')
您可能已经注意到在本文档的早期示例中,实时时间序列经常会在其轨迹中发生突然变化。默认情况下,Prophet会自动检测这些变化点,并允许趋势适当调整。但是,如果您希望更好地控制此过程(例如,Prophet错过了速率变化,或者历史记录中的速率变化过度),那么您可以使用几个输入参数调节。
Prophet自动改变点检测
Prophet通过首先指定允许速率改变的大量潜在变化点来检测变更点。然后它在速率变化的幅度上放置一个稀疏的先验(相当于L1正则化) - 这实质上意味着Prophet有大量可能的位置,在那些位置速率可以改变,但将尽可能少地使用它们。考虑一下快速入门中的Peyton Manning预测。默认情况下,Prophet指定25个潜在的变化点,它们统一放置在前80%的时间序列中。此图中的垂直线表示潜在变更点的放置位置:
m = Prophet()
m.fit(df)
future = m.make_future_dataframe(periods=366)
forecast = m.predict(future)
fig = m.plot(forecast)
for cp in m.changepoints:
plt.axvline(cp, c='gray', ls='--', lw=2)
即使我们有很多地方可能会改变费率,但由于先前稀疏,大多数这些改变点都未被使用。我们可以通过绘制每个变化点的速率变化幅度来看到这一点:
deltas = m.params['delta'].mean(0)
fig = plt.figure(facecolor='w', figsize=(10, 6))
ax = fig.add_subplot(111)
ax.bar(range(len(deltas)), deltas, facecolor='#0072B2', edgecolor='#0072B2')
ax.grid(True, which='major', c='gray', ls='-', lw=1, alpha=0.2)
ax.set_ylabel('Rate change')
ax.set_xlabel('Potential changepoint')
fig.tight_layout()
可以使用参数n_changepoints设置潜在变更点的数量,但可以通过调整正则化来更好地调整。可以通过以下方式显示表示变更点的位置:
from fbprophet.plot import add_changepoints_to_plot
fig = m.plot(forecast)
a = add_changepoints_to_plot(fig.gca(), m, forecast)
默认情况下,只会在前80%的时间序列中推断变换点,以便有足够的数据来预测趋势并避免在时间序列结束时过度拟合波动。此默认值适用于许多情况但不是全部,可以使用changepoint_range参数进行更改。例如,Python中的**m = Prophet(changepoint_range = 0.9)**将在前90%的时间序列中放置潜在的变化点。
调整趋势灵活性
如果趋势变化过度拟合(灵活性太大)或不足(灵活性不够),您可以使用输入参数changepoint_prior_scale调整稀疏之前的强度。默认情况下,此参数设置为0.05。增加它会使趋势更灵活:
m = Prophet(changepoint_prior_scale=0.5)
forecast = m.fit(df).predict(future)
fig = m.plot(forecast)
m = Prophet(changepoint_prior_scale=0.001)
forecast = m.fit(df).predict(future)
fig = m.plot(forecast)
指定变更点位置
如果您愿意,可以使用changepoints参数手动指定潜在变更点的位置,而不是使用自动变换点检测。然后,仅允许在这些点处进行斜率变化,具有与之前相同的稀疏正则化。例如,人们可以创建一个自动完成的点网格,但随后用一些已知可能有变化的特定日期来扩充该网格。作为另一个例子,变更点可以完全限于一小组日期,如下所示:
m = Prophet(changepoints=['2014-01-01'])
forecast = m.fit(df).predict(future)
fig = m.plot(forecast)