时间序列
之前的时间序列入门,很多人还是觉得不好理解
那么我们趁着出分的热度,专门做一下2021年国家线的时间序列预测把
考研MBA分数分析
MBA数值少,好理解
2009~2020年 MBA分数分析
预测2021年分数线
不见得准确,因为数据量太少,但是可以好好理解一下时间序列
我们把所有的功能只保留三部————
- 数据读取
- 模型构建
- 预测
数据读取
xls表mba.xlsx
import pandas as pd
df = pd.read_excel('./mba.xlsx', index_col='年份')
总分(A) 英语(A) 管综(A) 总分(B) 英语(B) 管综(B)
年份
2009年 155 50 85 145 45 77
2010年 165 47 94 155 42 84
2011年 165 45 90 155 40 80
2012年 150 41 82 140 36 72
2013年 155 41 82 145 37 72
2014年 160 41 82 150 36 72
2015年 160 40 80 150 35 70
2016年 165 39 78 155 34 68
2017年 170 42 84 160 37 74
2018年 165 42 84 155 37 74
2019年 170 42 84 160 37 74
2020年 175 44 88 165 39 78
时间序列图表
画个图看看效果
完全可以在xls里面画,这步可以省略
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['font.family'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
df.plot()
模型构建
获取一下最佳p和q
我们在p=0、1、2、3、4和q=0、1、2中做对比
这时候画一个热力图效果很好
这个函数直接拿去用,不用管里面怎么写的
import numpy as np
from statsmodels.tsa import arima_model
import itertools
import seaborn as sns #热力图
import warnings
warnings.filterwarnings("ignore")
def thermodynamicOrder(df, ar=4, ma=2):
results_aic = pd.DataFrame(\
index=['AR{}'.format(i) for i in range(0, ar+1)],\
columns=['MA{}'.format(i) for i in range(0, ma+1)])
for p, q in itertools.product(range(0, ar+1), range(0, ma+1)):
if p==0 and q==0:
results_aic.loc['AR{}'.format(p), 'MA{}'.format(q)] = np.nan
continue
try:
results = arima_model.ARMA(df, (p, q)).fit()
#返回不同pq下的model的BIC值
results_aic.loc['AR{}'.format(p), 'MA{}'.format(q)] = results.aic
except:
continue
results_aic = results_aic[results_aic.columns].astype(float)
fig, ax = plt.subplots(figsize=(10, 8))
ax = sns.heatmap(results_aic,
#mask=results_aic.isnull(),
ax=ax,
annot=True, #将数字显示在热力图上
fmt='.2f',
)
ax.set_title('AIC')
plt.show()
A区总分建模
df里面是所有数据,所以我们要只取里面的某一列
python的pandas直接可以按照列取值,非常方便
thermodynamicOrder(df['总分(A)'], 4, 2)
记住,最小的值代表最好,并且也是最暗
这里是81.78最小,对应的是AR0和MA1
也就是p=0,q=1 效果最好
然后我们把这个值带入模型
必须是有色块的值才能用,空白的是非法值,不能用
预测
使用刚才的参数创建模型预测2021年数据
arima_model.ARMA(df['总分(A)'], (0, 1)).fit().forecast(1)
(array([166.07142745]),
array([5.11281472]),
array([[156.05049474, 176.09236017]]))
我们现在预测出来了总分数据
均值 165(166.07142745)
最大值 175(176.09236017)
最小值 155(156.05049474)
因为分数线都是5分为最小单位,所以四舍五入
然后用同样的方法去预测其他的数据
A区英语
thermodynamicOrder(df['英语(A)'], 4, 2)
arima_model.ARMA(df['英语(A)'], (1, 0)).fit().forecast(1)
(array([44.12855737]),
array([1.92440793]),
array([[40.35678715, 47.9003276 ]]))
A区管综
thermodynamicOrder(df['管综(A)'], 4, 2)
arima_model.ARMA(df['管综(A)'], (0, 1)).fit().forecast(1)
(array([85.78637262]),
array([3.08996814]),
array([[79.73014636, 91.84259889]]))
B区总分
thermodynamicOrder(df['总分(B)'], 4, 2)
arima_model.ARMA(df['总分(B)'], (0, 1)).fit().forecast(1)
(array([156.07142745]),
array([5.11281472]),
array([[146.05049474, 166.09236017]]))
B区英语
thermodynamicOrder(df['英语(B)'], 4, 2)
arima_model.ARMA(df['英语(B)'], (1, 0)).fit().forecast(1)
(array([39.13014005]), array([1.96343784]), array([[35.2818726, 42.9784075]]))
B区管综
thermodynamicOrder(df['管综(B)'], 4, 2)
arima_model.ARMA(df['管综(B)'], (0, 1)).fit().forecast(1)
(array([75.75000016]),
array([2.96273148]),
array([[69.94315315, 81.55684716]]))
我们预测2021年A区分数线为
均值
总分:165
英语:44
管综:85
最高
总分:175
英语:48
管综:91
最低
总分:156
英语:40
管综:80
我们预测2021年B区分数线为
均值
总分:155
英语:39
管综:76
最高
总分:165
英语:43
管综:82
最低
总分:146
英语:35
管综:70
预测是不会考虑外因的,我倾向于按照最高来算
A区
总
分
:
175
\color{#ff0000}{总分:175}
总分:175
英
语
:
48
\color{#ff0000}{英语:48}
英语:48
管
综
:
91
\color{#ff0000}{管综:91}
管综:91
B区
总
分
:
165
\color{#ff0000}{总分:165}
总分:165
英
语
:
43
\color{#ff0000}{英语:43}
英语:43
管
综
:
82
\color{#ff0000}{管综:82}
管综:82
到了国家线发榜时间咱们看看预测结果~
再次声明,不要过多在意数值,本文只是时间序列的应用
时间序列,调参非常重要,了解之后,如果想深入,一定要做自相关
具体内容请看 时间序列基础