您只需几行代码即可创建和评估预测。
只要提供pandas的DataFrame,需要包含时间序列和需要预测的值。时间序列可以是任何pandas.to_datatime认识的格式
在本例中,我们将会加载一个数据集,代表的是佩顿·曼宁维基百科页面的访问量。
本数据集包含了从2007-12-10到2016-01-20期间的数据。
加载依赖
#将图表嵌入到Notebook中
%matplotlib inline
# 忽略警告
import warnings
warnings.filterwarnings("ignore")
# 加载依赖
import pandas as pd
import plotly
from greykite.common.data_loader import DataLoader
from greykite.framework.templates.autogen.forecast_config import ForecastConfig
from greykite.framework.templates.autogen.forecast_config import MetadataParam
from greykite.framework.templates.forecaster import Forecaster
from greykite.framework.templates.model_templates import ModelTemplateEnum
from greykite.framework.utils.result_summary import summarize_grid_search_results
将数据集加载到pandas DataFrame中
dl = DataLoader()
df = dl.load_peyton_manning()
display(df.head(),df.tail())
这个df就是从2007-12-10到2016-01-20期间的数据。如果要用自己的数据集,可以pd.read_csv读取自己的数据。只要是pandas.to_datatime能认识的时间格式就可以(一般常见的格式都认识)。
指定数据集信息
metadata = MetadataParam(
time_col="ts", # time列的列名
value_col="y", # value列的列名
freq="D"
'''
"H" 代表小时, "D" 是天, "W" 是星期, etc. `pandas.date_range`能接受的任何格式
'''
)
创建预测模型
你可以选择PROPHET或者SILVERKITE预测模型模板。
在本例中,我们使用SILVERKITE作为预测模型。
首先创建Forecaster()对象,然后对该实例对象应用run_forecast_config方法。
传入两个参数,df 和 config。df就是前面创建的数据集,config需要用ForecastConfig()函数创建。
ForecastConfig()里面的参数包括:
- model_template:模型算法,这里选择使用ModelTemplateEnum.SILVERKITE.name
- forecast_horizon:预测的步长,这里预测365步
- coverage:置信度,0.95是95%置信度在预测的范围内。
- metadata_param:这个就选上一步创建的那个数据集信息,时间列名、值列名、时间频率
forecaster = Forecaster() # 创建forecaster对象,并且存储预测结果
result = forecaster.run_forecast_config( # 结果也被存储为`forecaster.forecast_result`
df=df,
config=ForecastConfig(
model_template=ModelTemplateEnum.SILVERKITE.name,
forecast_horizon=365, # 向前预测365步长
coverage=0.95, # 95%预测置信度
metadata_param=metadata
)
)
检查结果
run_forecast_config的输出是一个字典,包含了未来的预测,历史拟合性能评估,以及原始的时间序列。
绘制历史的时序数据
使用plotly
画出可交互的图表
ts = result.timeseries
fig = ts.plot()
plotly.io.show(fig)
Cross-validation交叉验证:
默认地,run_forecast_config提供了历史数据的估计,所以你可以看到这个模型对于历史数据的“预测”效果。
这个被存储在grid_search
(交叉验证拆分)和backtest
(holdout测试集)
让我们看一下交叉验证的结果吧。
下面展示了MAPE(Mean Absolute Percentage Error)
grid_search = result.grid_search
cv_results = summarize_grid_search_results(
grid_search=grid_search,
decimals=2, # 小数位
# The below saves space in the printed output. Remove to show all available metrics and columns.
cv_report_metrics=None,
column_order=["rank", "mean_test", "split_test", "mean_train", "split_train", "mean_fit_time", "mean_score_time", "params"])
# Transposes to save space in the printed output
# 转置,节省打印输出的空间
cv_results["params"] = cv_results["params"].astype(str)
cv_results.set_index("params", drop=True, inplace=True)
cv_results.transpose()
这些参数具体代表的含义,我尚不能解释清楚。埋坑,待以后用到的时候再研究吧。如果读者您知道,请不吝赐教。
使用Backtest ,画出历史数据的拟合效果吧。
backtest = result.backtest
fig = backtest.plot()
plotly.io.show(fig)
使用前一部分的历史数据历史数据作为训练集,来预测后一部分的历史数据。看看跟实际的数据差别。
这个预测的时间周期,是跟上面模型创建时定义的forecast_horizon=365一样。要往后预测365天,默认做模型检验的时候,backtest也时拿最后的365天做校验。
你也可以查看历史数据评估矩阵(基于历史的训练和测试集)
dict_train = {}
for i,j in backtest.train_evaluation.items():
dict_train[i] = j
df_train = pd.DataFrame(dict_train,index=["train"])
dict_test = {}
for i,j in backtest.test_evaluation.items():
dict_test[i] = j
df_test = pd.DataFrame(dict_train,index=["test"])
metrics = pd.concat([df_train,df_test],axis=0).T
metrics
Forecast预测
结果的forecast属性包含了预测的结果,就跟backtest类似,你可以画出结果,或者看到评估矩阵。
让我们画出预测结果吧(使用所有的数据进行训练):
forecast = result.forecast
fig = forecast.plot()
plotly.io.show(fig)
这个预测结果的数值可以在df里面拿到。
forecast.df.tail().round(2)
Model Diagnostics模型诊断:
各个组件图展示了展示了你的数据集的整体趋势、季节性影响、以及事件、节假日模式。
fig = forecast.plot_components()
plotly.io.show(fig) # 如果使用PROPHET算法模板,就用 fig.show()
模型总结,可以了解模型如何工作以及可以进一步改进的内容。但是看不懂,先写在这下面。
summary = result.model[-1].summary() # -1 retrieves the estimator from the pipeline
print(summary)
应用模型
这个训练的模型可以在sklearn.pipeline.Pipeline
中被使用
model = result.model
model
你可以拿这个模型来预测任意时间范围,make_future_dataframe这个函数可以帮你方便地创建未来日期的dataframe。
注意传给predict函数的dataframe需要跟前面传给run_forecast_config
的df具有相同的列。包括数值列,要用np.nan来填充。
future_df = result.timeseries.make_future_dataframe(
periods=4,
include_history=False)
future_df
调用.predict()函数来计算预测值。
model.predict(future_df)