社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

[Python学习]预测银行间资金利率的一个方法-基于Prophet模型

Rick笔记 • 4 年前 • 470 次点击  

研判银行间资金利率走势,对于分析债券市场而言非常重要。Facebook在2017年开源了一个时间序列预测的算法,叫做fbprophet,其功能包括:

  1. 为预测设置上下限;
  2. 设置趋势断点;
  3. 处理季节性和节假日效应;
  4. 允许乘法形式的季节性;
  5. 区间预测;
  6. 处理异常值;
  7. 处理非日度数据;
  8. 模型检测。

我们认为,可以用这个算法,来为银行间资金利率,做出一个基础性的预测。初步探索如下:

一、安装

我们推荐使用conda安装,由于fbprophet需要调用pyStan这个开源工具,因此安装命令为下述两条:

conda install -c conda-forge pystan
conda install -c conda-forge fbprophet

二、数据准备

fbprophet的基础输入数据只需要两列,第一列是日期,第二列是要拟合和预测的时间序列数据。在本文中,我们使用3个月的SHIBOR作为案例。要注意的一点是,数据的变量名,一定修改成dsy。原始数据如下:


dsy
35472020-12-162.952
35482020-12-172.905
35492020-12-182.855
35502020-12-212.818
35512020-12-222.796

三、初步处理

fbprophet算法的大概步骤是,先生成一个Prophet 实例,然后调用fit方法进行拟合,调用predict方法进行拟合。代码如下:

m = Prophet()
m.fit(data)
future_time = m.make_future_dataframe(periods=365)
forecast = m.predict(future_time)
fig1 = m.plot(forecast)
fig2 = m.plot_components(forecast)

下图就是模型预测的初步结果,其中黑色表示原始数据的离散点,深蓝色线表示通过时间序列模型拟合的值,浅蓝色区域表示预测的置信区间。

我们来看看模型提取出的时间序列分项,从下图可以看到,模型自2018年之后,对资金利率的趋势预测是线性向下的。从年内各月份的资金利率规律来看,呈现出上半年下行、下半年上行、年中短暂跳升的W型。从周内的规律来看,周五有一个明显的跳升。

四、进一步修正

1、趋势项预测方法的选择。 fbprophet模型中,对趋势项的预测有两种方法,第一种是基于逻辑回归函数(logistic function),一般用来拟合单向增长或下降,但是增长或者下降有界限的数据,第二种是基于分段线性函数(piecewise linear function)。我们在本案例中选择第二种方法,这也是fbprophet模型的默认方法,不需要单独设定。

2、趋势变点的设定和检测。 时间序列数据中,趋势的方向可能会出现变化,这就是所谓的“变点”。fbprophet模型会自动识别变点,而且为了避免过拟合的问题,模型默认在前80%的样本中识别变点。下图用红色竖线标识出模型自动识别的变点,根据最新识别的变点,整体趋势预测是下行的:

我们可以用changepoint_range来调整设置变点的范围,比如我们修改设置changepoint_range=1,可以看到,模型将5月份以来的资金面边际收紧,识别为未来的趋势,对未来资金利率的预测整体上行,这就产生了过拟合的问题。

我们也可以手动设置变点的位置,比如我们认为,银行间资金利率,受到准备金率调整的影响特别大,那么就可以把调整准备金率的时间,作为变点进行输入,结果如下:

3、节假日调整。 在很多时间序列中,节假日是很常见的影响因子,我们可以在模型中添加下述语句,来纳入中国的节假日,fbprophet模型中纳入的中国节假日有:元旦、春节、清明节、劳动节、端午节、中秋节 国庆节。由于这些假日银行间市场一般都不交易,所以我们在本案例中不予处理。

m.add_country_holidays(country_name='CN')

id          holiday
0          New Year's Day
1        Chinese New Year
2       Tomb-Sweeping Day
3               Labor Day
4    Dragon Boat Festival
5     Mid-Autumn Festival
6            National Day

4、季节性设置。 fbprophet模型中,默认识别的季节性是周度和年度,但是对于银行间资金利率而言,周度的季节性特征并不明显,但是月度和季度的季节性比较明显,因此我们需要把周度季节性调整成月度和季度季节性。

从季节性分解图上可以看到,资金利率在月内有比较明显的季节性,月初缴准是一个高点,下旬税期是一个高点,月末是一个高点。资金利率在每个季度的最后一个月,利率偏高。

5、工作日调整。 因为银行间资金利率,只有工作日有数据,因此我们需要对预测的工作日进行调整:

future_time = m.make_future_dataframe(periods=365,freq='B')

五、优缺点分析

fbprophet模型速度比较快,而且有一定的灵活度,可以自行设置节假日、淡旺季、工作日、季节性特征、变点等,是一个功能很强大的模型。

但是缺点也比较明显,就是模型仅基于历史数据进行预测,无法引入外部变量,比如央行降准,或者大额超量续作MLF等,都会对资金利率带来明显影响,但是模型无法捕捉这种外生变量。因此笔者认为,fbprophet模型可以基于时间序列特征,提供一个很好的基准情形,然后我们再根据其他外部因素进行调整。

我们对未来1年的资金利率的预测结果和代码如下:

m = Prophet(changepoints=rrr.index.astype(str).tolist(),weekly_seasonality=False)
m.add_seasonality(name='monthly', period=30.5, fourier_order=5)
m.add_seasonality(name='quarterly', period=90, fourier_order=7)
future_time = m.make_future_dataframe(periods=365,freq='B')
forecast = m.fit(data).predict(future_time)
fig1 = m.plot(forecast)
fig2 = m.plot_components(forecast)


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/103876
 
470 次点击