使用ARIMA算法进行时间序列预测。

147 阅读3分钟

本文以行健宏扬中国为例,提取数据,使用ARIMA算法进行时间序列预测。

爬取数据


\

# 抓取行健宏扬中国基金 from bs4 import BeautifulSoup import requests headers = {'Accept':'text/javascript, application/javascript, /; q=0.01',            'Accept-Encoding':'gzip, deflate',            'Accept-Language':'zh-CN,zh;q=0.8',            'Connection':'keep-alive',            'Cookie':'vjuids=148cf0186.15e03abf2ac.0.c311af0ddaa6c; ADVS=358187b0bd1a65; ASL=17431,000pn,7010519170105191; jrj_uid=15060593555978DJcIwmvnb; jrj_z3_newsid=723; ADVC=35686f6caeedf3; WT_FPC=id=2ef30c6a0af7eaf3a501506059355507:lv=1506063782501:ss=1506063782501; channelCode=3763BEXX; ylbcode=24S2AZ96; vjlast=1503300154.1506059356.23; Hm_lvt_a07bde197b7bf109a325eebaee445939=1506059356; Hm_lpvt_a07bde197b7bf109a325eebaee445939=1506063783',            'Host':'fund.jrj.com.cn',            'Referer':'fund.jrj.com.cn/archives,96…',            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',            'X-Requested-With':'XMLHttpRequest'} params = {'fundCode':'968006',           'obj':'obj',           'date':2017} r = requests.get('fund.jrj.com.cn/json/archiv…) r.encoding ='utf-8' mydata = r.text

存储数据


  • \
# 从字符串中提取标准json格式数据 table = mydata[8:] # 将字符串转为json,不用手动解析 myJson = json.loads(table) # 提取净值数据 myJson['fundHistoryNetValue']
from pymongo import MongoClient db = MongoClient('localhost',27017)['fund'] collect = db.get_collection('hjhy') collect.insert(myJson['fundHistoryNetValue']) print('done')

提取&处理数据


\

from pymongo import MongoClient import pandas as pd import time,datetime db = MongoClient('localhost',27017)['fund'] data = dict() for item in db.get_collection('hjhy').find():     data[datetime.datetime.fromtimestamp(time.mktime(time.strptime(item['enddate'],'%Y-%m-%d')))] = item['accum_net']

使用ARIMA模型预测


\

1.构建时间序列

# 构建时间序列 my_series = pd.Series(data, data.keys()) # 处理数据类型,将Str转换为float my_series = my_series.apply(lambda x: float(x)) # 按日期生序排序 my_series = my_series.sort_index()

\

2.查看趋势图

自此基金成立至今,价格增长趋势变化。

%pylab # plot(my_series) my_series.plot()

直接使用plot(my_series)会多画出来一条首尾相连接的直线。还是使用my_series.plot()调用对象自身的plot方法吧。

\

3.进行差分操作

from matplotlib import pyplot as plt # 一阶差分 fig = plt.figure() diff1 = my_series.diff(1) diff1.plot() # 二阶差分 fig = plt.figure() diff2 = my_series.diff(2) diff2.plot()
  • \

4.一阶差分

\

\

5.二阶差分

\

\

6.查看描述性统计

# 一阶差分描述性统计 diff1.dropna(inplace=True) diff1.describe()

每一次做差分,都会产生一个NA,所以要记得剔除NA。下面的结果是diff1的描述性统计:

# 二阶差分描述性统计 diff2.dropna(inplace=True) diff2.describe()

下面的结果是diff2的描述性统计:

所以做一次差分就够了。

\

7.确定p, q参数值

\

import statsmodels.api as sm fig = plt.figure() ax0 = fig.add_subplot(211) fig = sm.graphics.tsa.plot_acf(diff1, lags=30, ax=ax0) ax1 = fig.add_subplot(212) fig = sm.graphics.tsa.plot_pacf(diff1, lags=30, ax=ax1)

\

这是一阶差分的自相关与偏相关的趋势图,虽然一阶差分的平稳度要比二阶差分略好,但p>0,MR(q)截尾;q>0,AR(p)截尾。

\

选择使用二阶差分,二阶差分的自相关与偏相关趋势图如下所示:

\

5.预测

from statsmodels.tsa.arima_model import ARIMA

model = ARIMA(history_price, (12, 2, 1)).fit()

model.forecast(10)[0]

实际值

预测值

array([ 1.41013409,  1.4134152 ,  1.41570651,  1.41638723,  1.42131414,        1.42299673,  1.42647455,  1.42795939,  1.43099336,  1.43316138])

\

\

欢迎大家围观,长按识别二维码,关注“数据分析手记”~

\