文章链接
模型原理
Prophet模型,是Facebook公司开源的一个专门用于大规模时间序列分析的模型,基于加性模型(Additive Model),利用年月日等的周期性再加上假期影响去拟合非线性的趋势。具体内容可以在这里找到。该模型最适合用于拟合那些具有较强周期性并且拥有几个周期的数据,并且对缺失值,趋势偏移和异常值都有着较好的支持。Prophet采用一种独特的策略(如图所示),在保证当需要的时候可以完全自动化整个流程的前提下,允许数据分析学家通过一组关键的模型参数和选项来在预测中加入自己的判断。 Prophet原理图Prophet的大致原理如下,它将一个时间序列看成是三部分的组合:趋势,季节和假日。$y(t)=g(t)+s(t)+h(t)+\epsilon_t$。$g(t)$代表趋势项,用于拟合时间序列里面的非周期项;$s(t)$代表周期性变化(如季节性变化);$h(t)$代表了假期的影响(通常表现为对某些时间点的特殊影响);误差项$\epsilon_t$代表了所有未被模型考虑到的误差因素。同时该模型将一个预测类问题,映射为了曲线拟合类问题,这天然的就和那些用于分析数据间有依赖性的模型有所不同。尽管这种策略会使其放弃很多常规模型(如ARIMA)的一些优势,但是这种映射带来了一些其他的优势:
- 可拓展:曲线拟合问题可以很轻易的引入季节和多周期性的影响,可以应用于多种数据类型;
- 数据灵活:与ARIMA模型不同,曲线拟合问题不需要数据等步长,所以不需要对数据进行一些特殊操作(如插值);
- 速度快:相比较于传统的训练模型,曲线拟合的速度更快,有助于数据科学家进行迭代;
- 变量易解释:模型的大部分变量都有着明确的物理含义,并且拥有一定数据分析经验的人可以很快的将背景知识转换为新的参数引入模型。
模型安装
Prophet模型的安装推荐使用conda
conda install -c conda-forge fbprophet
下载并安装Anaconda,在cmd/powershell里面输入 conda
已验证是否成功安装
如果你对conda不熟悉,下面有一些链接可能会对你有所帮助:
模型实现
注意:Prophet模型对输入有所限制,接受的是DataFrame格式的输入,并且时间数据列名为ds,观测数据列名为y
def prophet_predict_fb(observed_data, x_name="ds", y_name="y", forecast_cnt=365, frep="D", file_name=""):
"""
function that predict time series with library fbprophet
:param observed_data: time series data(DataFrame format)
(two columns, one is time in YYYY-MM-DD or YYYY-MM-DD HH:MM:SS format and the other is numeric data)
:param x_name: x column name(time data), usually is DATE
:param y_name: y column name(numeric data) e.g. HMD, MAX...
:param forecast_cnt: how many point needed to be predicted
:param frep: the frequency/period of prediction
:param file_name:
:return: None
"""
def check_parameter_validity():
if x_name not in observed_data.keys():
raise KeyError("train_data doesn't have column named %s" % x_name)
if y_name not in observed_data.keys():
raise KeyError("train_data doesn't have column named %s" % y_name)
try:
check_parameter_validity()
except KeyError as e:
print("key error: %s" % str(e))
return None
observed_data = observed_data.rename(columns={x_name: "ds", y_name: "y"})
observed_data["ds"] = pd.to_datetime(observed_data["ds"])
observed_data["y"] = pd.to_numeric(observed_data["y"], downcast='float', errors='coerce')
df2_pro = fbprophet.Prophet(changepoint_prior_scale=0.1)
df2_pro.fit(observed_data)
future_date = df2_pro.make_future_dataframe(periods=forecast_cnt, freq=frep)
df2_forecast = df2_pro.predict(future_date)
# register a datetime converter for matplotlib
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
if file_name:
fig1 = df2_pro.plot(df2_forecast, xlabel=x_name, ylabel=y_name)
fig1.show()
fig1.savefig('./result/%s.png' % file_name)
fig2 = df2_pro.plot_components(df2_forecast)
fig2.show()
fig2.savefig('./result/%s.png' % str(file_name + "1"))
return df2_forecast
关键参数
该模型封装较好,无需修改较多参数
- changepoint_prior_scale:数据趋势的变化频率,值越大,数据的趋势项变化越缓慢。
注意该模型比较适合于分析周期性较为明显的数据。