Comprendre les prévisions de séries chronologiques Python dans un seul article (étapes, modèles, code Python)

La prévision comprend l'ajustement numérique, la régression linéaire, la régression multiple, les séries chronologiques, le réseau neuronal, etc.

Pour la prévision de séries chronologiques univariées : les modèles incluent AR, MA, ARMA et ARIMA. De manière générale, ARIMA peut tout représenter.

Liens de données et de codes : données et fichiers Jupyter

Prenons les prévisions d’évolution du PIB américain au cours des 10 prochaines années sous forme de colonne :

Table des matières

La première étape consiste à importer des données

La deuxième étape consiste à effectuer une analyse de séquence stationnaire

La troisième étape consiste à effectuer l'opération de différence de la séquence instable

La quatrième étape consiste à effectuer la commande, la sélection et l'ajustement des modèles.

Étape 5 : Effectuer une analyse des résultats du modèle et des tests sur le modèle 

Étape 6 : Effectuer des prédictions de modèle

PS : Comparatif des AUTO-ARIMA automatisés


L'organigramme ARIMA est le suivant :

La première étape consiste à importer les données :


    Observez les données des variables à prédire, supprimez les données diverses et obtenez les attributs des données elles-mêmes tels que la taille, le type, etc.

import pandas as pd,numpy as np
from matplotlib import pyplot as plt

#加载数据,sheet_name指定excel表的数据页面,header指定指标column属性,loc去除杂数据,可选:parse_dates=[''],index_col='',use_cols=['']
df=pd.read_excel('./data/time1.xls',sheet_name='数据',header=1).loc[1:,:]

#DateFrame索引重置
df=df.set_index('DATE')#df.set_index('DATE',inplace=True)

#查看前5行
print(df.head(5))

#查看列索引
print(df.columns)#print(df.keys())

#查看表的维度
print(df.shape)

#查看行索引
print(df.index)

#np.array()  array1.reshape(,)  df.values.astype(int).tolist() np.vstack((a1,a2))  np.hstack((a1,a2))  round()  iloc

#时间索引拆分
# dates=pd.date_range(start='1991-01-01',end='2007-08-01',freq='MS')#日期取值和格式转换,MS代表每月第一天
# years=[d.strftime('%Y-%m') for d in dates][0:200:25]
# years.append('2007-09')

Le résultat est le suivant :

La deuxième étape consiste à effectuer une analyse de séquence stationnaire :


    Les séries temporelles que nous étudions et analysons, c'est-à-dire les données de panel, n'ont d'importance pour la recherche que si elles sont largement stationnaires. S'il s'agit d'une séquence non stationnaire, sa différence doit être convertie en une séquence stationnaire avant que l'analyse puisse être effectuée. Pour les séquences strictement stationnaires, les propriétés ne changent pas, c'est-à-dire que la séquence est une séquence de bruit blanc, une telle séquence n'a aucune signification pour la recherche.
    
    Par conséquent, après avoir obtenu ici les données de la série chronologique du PIB, nous effectuons d'abord un test de bruit blanc sur la séquence d'origine, en utilisant la statistique LB. Si la valeur p est inférieure au niveau significatif a = 0,05, la séquence d'origine est considérée comme une séquence de bruit non blanc, significative pour la recherche. .
    
    Ensuite, dessinez un diagramme de séries chronologiques et jugez subjectivement la stationnarité de la série chronologique du PIB. S'il y a une tendance évidente, il s'agit d'une série non stationnaire. S'il n'y a pas de tendance évidente, ou s'il vous est difficile de juger de la stationnarité, alors vous devez utiliser l'unité ADF. Les statistiques racine sont utilisées pour aider à juger si elle est stationnaire. Pour la statistique ADF, vous pouvez comparer la valeur de la statistique pour juger, ou vous pouvez comparer la valeur p pour juger. Par exemple, lorsque le niveau de signification est a = 0,05, si la statistique ADF de votre variable est inférieure à l'ADF. statistique pour a=0,05, alors cela indique que la série temporelle correspondant à la variable est une séquence stationnaire ; une méthode plus directe consiste à juger uniquement que si la valeur p de la variable est inférieure à 0,05, elle est également indiquée comme une séquence stationnaire.

   

plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
plt.rc('font',family='SimHei')
plt.style.use('ggplot')

df.plot(secondary_y=['CS','INV','P_GDP','GOV_NET'])#单个指标时序图 df['CS'].plot()
plt.xlabel('Date')
plt.ylabel('Value')
plt.title('Time Series Plot')
#plt.grid()
plt.show()

from statsmodels.tsa.stattools import adfuller# ADF检验

for i in df.columns:
    data=df[i]
    print(f'{i}的单位根检验')
    result = adfuller(data)#默认情况下,regression参数为'c',表示使用包含截距项的回归模型。
    print('ADF Statistic: %f' % result[0])#ADF统计量
    print('p-value: %f' % result[1])#p值
    print('Critical Values:')#在置信水平下的临界值
    for key, value in result[4].items():
        print('\t%s: %.3f' % (key, value))
    print()

Résultats du code :


La troisième étape consiste à effectuer l'opération de différence de la séquence non stationnaire :


    Généralement, la différence entre les séries chronologiques ne dépassera pas le troisième ordre. Effectuez l'opération de différence sur les données d'origine et répétez la deuxième étape du diagramme de séries chronologiques et l'opération de test de racine unitaire ADF. S'il s'avère que la séquence différenciée est une séquence stationnaire, enregistrez l'ordre de la différence. Ici, l'ordre de différence du PIB est 1, réussissant le test de séquence stationnaire. Effectuez à nouveau un test de bruit blanc sur la séquence différenciée. Si elle réussit comme une séquence de bruit non blanc, passez à l'étape suivante.
    

#差分时序图
diff_data = df.diff(periods=1).dropna()# 创建一阶差分的时间序列,加上dropna()后续不需要执行[1:]
#print(diff_data)

diff_data.plot()
plt.xlabel('Date')
plt.ylabel('Value')
plt.title('Time Series Plot')
#plt.grid()
plt.show()

for i in diff_data.columns:
    data=diff_data[i]#Series索引选取,一阶差分第一个数据为NA
    
    print(f'{i}的单位根检验')
    result = adfuller(data)#结果对应位置的数据需要自己判断是什么含义
    print('ADF Statistic: %f' % result[0])#ADF统计量
    print('p-value: %f' % result[1])#p值
    print('Critical Values:')#在置信水平下的临界值
    for key, value in result[4].items():
        print('\t%s: %.3f' % (key, value))
    print()

from statsmodels.stats.diagnostic import acorr_ljungbox

#这里为一阶差分后的平稳序列进行白噪声检验,lags为1,否则lags为0,这里拿上述的GDP指标进行
lags = [1,4,8,16,32]

print('差分序列的白噪声检验结果为:'+'\n',acorr_ljungbox(diff_data['GDP'], lags))  # 返回统计量和p值,这里的lags对应差分阶数

print('原始数据序列的白噪声检验结果为:'+'\n',acorr_ljungbox(df['GDP'], lags))

Les résultats du code sont les suivants :

La quatrième étape consiste à effectuer la commande, la sélection et l'ajustement des modèles :


    Pour déterminer l'ordre du modèle, nous utilisons d'abord le diagramme d'autocorrélation et le diagramme d'autocorrélation partielle pour faire un jugement préliminaire : Coefficient d'autocorrélation Coefficient d'autocorrélation partielle
           Différence
    AR Tailing Troncature d'ordre p 0
    MA Troncature d'ordre q Tailing 0
    ARMA tailing Tailing 0
    ARIMA tailing Tailing d
    En bref, les modèles ci-dessus peuvent tous être implémentés en utilisant ARIMA (p, d, q).AR, MA et ARMA sont tous des cas particuliers d'ARIMA.
    
    Jugements empiriques sur la queue et la troncature :
    queue : l'exponentielle négative converge de manière monotone vers 0 ou présente une désintégration du cosinus
    ; troncature : décroît rapidement jusqu'à 0 et fluctue près de 0 ;
    la troncature s'approche de 0 plus rapidement que la queue s'approche de 0. La troncature n'augmentera pas de manière significative dans les étapes ultérieures
    
       

        Après avoir utilisé le graphique pour porter un jugement préliminaire, si vous ne parvenez toujours pas à déterminer avec précision l'ordre du modèle, vous pouvez utiliser les critères AIC et BIC pour vous aider au jugement ou à l'optimisation. Par exemple, je juge que l'ordre du modèle peut être 2, 1, 4 ou 3, 1, 3. Pour le moment, je ne suis pas sûr. Vous pouvez d'abord faire ARIMA (2, 1, 4). Si vous constater que le modèle suivant est significatif Si le test et le test des paramètres réussissent, alors vous pouvez directement utiliser ARIMA(2,1,4) pour faire des prédictions et tirer des conclusions, mais vous pouvez également essayer plusieurs commandes proches, telles que ARIMA( 3,1,3), ARIMA (2,1,3) et ainsi de suite ont également réussi, mais les valeurs AIC et BIC d'ARIMA (3,1,3) sont les plus petites, c'est-à-dire que le modèle a un ajustement plus élevé précision et est un modèle relativement optimal. , cette étape est l'optimisation du modèle.

    
    Le paramétrage et l'optimisation de l'ordre ici sont implémentés en Python comme suit : de q à (longueur des données/10), de p à 0 à (longueur des données/10), et généralement l'ordre ne dépassera pas (longueur des données/10) ; Ensuite effectuez l'ajustement du modèle q*p et utilisez les résultats de l'ajustement du modèle pour comparer les valeurs de l'AIC et du BIC. Plus la valeur du BIC est petite, plus le modèle est le modèle relativement optimal, puis utilisez l'ordre du modèle comme modèle final.L'ordre de la combinaison.

    

#生成自相关图,偏自相关图
from statsmodels.graphics.tsaplots import plot_acf,plot_pacf

fig, ax = plt.subplots(figsize=(5, 4))
plot_acf(diff_data['GDP'],ax=ax)#可以换成df的数据,这里用一阶差分数据得到平稳序列
    
ax.set_title("Autocorrelation Plot")
lags=list(range(24))
ax.set_xticks(lags)#这里把x坐标刻度变更精细,加网格图更方便,xticklabels替换标签
ax.set_xlabel("Lag")
ax.set_ylabel("Autocorrelation")
ax.grid(alpha=0.5)
plt.legend(['GDP'])#这里区别直接放入df.columns[i],如果是多字符如‘CS’,这样会被认为是一个序列,拆成C和S的图例
plt.show()
    
fig, ax = plt.subplots(figsize=(5, 4))
lags=list(range(24))
ax.set_xticks(lags)#这里把x坐标刻度变更精细,加网格图更方便,xticklabels替换标签
plot_pacf(diff_data['GDP'], ax=ax,method='ywm')#ywm替换默认的yw,去除警告
ax.set_xlabel('Lags')
ax.set_ylabel('Partial Autocorrelation')
ax.grid(alpha=0.5)
plt.legend(['GDP'])
plt.show()

import warnings
warnings.filterwarnings("ignore")
import statsmodels.api as sm


#diff_data['GDP'].values.astype(float),这里发现Serise的dtype为object,模型用的应该为float或者int类型,需要注意原数据的数据类型是否一致

Min=float('inf')
for i in range(0,6):#AIC,BIC最小找到p,q阶数来定阶,从0开始定阶是否可行??
    for j in range(0,6):
        result=sm.tsa.ARIMA(df['GDP'].values.astype(float),order=(i,1,j)).fit()
        print([i,j,result.aic,result.bic])
        if result.bic<Min:
            Min=result.bic
            best_pq=[i,j,result.aic,result.bic]
print(f'最优定阶为{best_pq}')

Résultats du code :


La cinquième étape consiste à effectuer une analyse des résultats du modèle et des tests sur le modèle. 

    Les tests de modèle sont divisés en tests de paramètres de modèle et en tests de signification de modèle.

    Test de signification du modèle : c'est-à-dire le test de bruit blanc du résidu. Si le résidu est une séquence de bruit blanc, c'est-à-dire que les informations de la séquence d'origine sont entièrement extraites. Regardez la statistique LB. La statistique LB du résultat du modèle en python est la statistique LB du résidu. , si la valeur p est inférieure à 0,05, il s'agit d'une séquence de bruit non blanc. Si la valeur p est supérieure à 0,05, cela signifie que le résidu est une séquence de bruit blanc. C'est la résultat que nous souhaitons. Ici, vous pouvez extraire la valeur résiduelle du modèle séparément, dessiner vous-même le diagramme de série temporelle résiduelle, le diagramme QQ, le diagramme de distribution normale ou effectuer vous-même un test de bruit blanc pour vous aider au jugement. La séquence de bruit blanc obéit à la distribution normale, le diagramme de série chronologique fluctue doucement et les points numériques sur le diagramme QQ sont proches de la diagonale.
    
    Test des paramètres du modèle : testez si chaque paramètre inconnu est significativement égal à 0 et testez si le modèle est le plus rationalisé. Si le paramètre n’est pas significativement différent de zéro, il peut être éliminé du modèle ajusté et voir la statistique t.
    
    Explication partielle des résultats du modèle :
    const : terme constant       
    ar.L1 : coefficient de terme autorégressif
    ma.L1 : coefficient de terme moyen mobile
    sigma2 : variance
    P>|z| sous chaque paramètre, si elle est inférieure à a=0,05, l'hypothèse nulle est rejetée. On considère que les paramètres sont significativement non nuls, c’est-à-dire qu’il n’est pas nécessaire de simplifier le modèle.
    Ljung-Box : statistique LB. Il convient de noter ici que la valeur P de LB doit être >0,95, c'est-à-dire que la séquence résiduelle est jugée comme une séquence de bruit blanc, et si elle est inférieure à 0,05, c'est une séquence de bruit blanc. séquence de bruit non blanc.
    Jarque-Bera : Les résultats du   
    test d'hétéroscédasticité statistique JB indiquent un cas de variance stable

Result=sm.tsa.ARIMA(df['GDP'].values.astype(float),order=(best_pq[0],1,best_pq[1])).fit()
print(Result.summary())  #显示模型的所有信息

print(len(Result.resid))
#print(Result.resid)这里观察到残差的第一项为原数据的1239.5,即差分数据不管第一项,这里需要调整残差的观测

#这里就可以观察到原始模型的结果LB统计量和这里的白噪声检验是一致的,p>0.05,即认为残差为白噪声序列,原序列信息提取充分。
lags = [1,4,8,16,32]
print('差分序列的白噪声检验结果为:'+'\n',acorr_ljungbox(Result.resid[1:], lags))

## 查看模型的拟合残差分布
fig = plt.figure(figsize=(12,5))
ax = fig.add_subplot(1,2,1)
plt.plot(Result.resid[1:])
plt.title("ARIMA(2,1,1)残差曲线")

## 检查残差是否符合正太分布
ax = fig.add_subplot(1,2,2)
sm.qqplot(Result.resid[1:], line='q', ax=ax)
plt.title("ARIMA(2,1,0)残差Q-Q图")
plt.tight_layout()
plt.show()

fig = plt.figure(figsize=(12,5))
Residual=pd.DataFrame(Result.resid[1:])
Residual.plot(kind='kde', title='密度')
plt.legend('')
plt.show()

Le résultat du code est :

  

La sixième étape consiste à effectuer une prédiction du modèle :


    La prédiction du modèle consiste à utiliser le modèle relativement optimal mentionné ci-dessus pour prédire les valeurs correspondant aux variables de données d'origine à des moments ultérieurs.
    Notez qu'en python, si la fonction de prévision prédit des données différentielles, faites attention au début du début et à la fin de la fin. Par exemple, les données de différence du premier ordre commencent à partir de la deuxième valeur d'observation, et l'erreur résiduelle correspondante est également la idem
    Lorsque vous dessinez plus tard, vous devez faire attention au dessin du modèle différentiel.

#预测,绘制原序列和预测序列值对比图

Predict=Result.predict(start=1, end=len(df['GDP'])-1+1+10); #不加参数默认0到n-1,要加预测个数在end后面N-1+预测n即可
#如果是一阶差分的序列预测,第一个数据已经差分消去了,应该start从第二个观测数据开始,即n=1;如果是0阶,则不需要按默认0到n-1

print(list(zip(range(193,203),Predict[-10:])))#打印预测值

plt.figure()
plt.plot(range(193),df['GDP'].values)#'o-k'
plt.plot(range(193+10),Predict)#'P--'
plt.legend(('原始观测值','预测值'))
plt.xticks(list(range(0,203,10)),rotation=90)
plt.show()

plt.figure()
plt.plot(range(193),df['GDP'].values)#'o-k'
plt.plot(range(192,193+10),Predict[-11:])#'P--'#接着原数据最后一个,进行拟合预测表示
plt.legend(('原始观测值','预测值'))
plt.xticks(list(range(0,203,10)),rotation=90)
plt.show()

Résultats du code :

PS : Comparatif des AUTO-ARIMA automatisés

import pmdarima as pm
# ## 自动搜索合适的参数
model = pm.auto_arima(df['GDP'].values,
                      start_p=1, start_q=1, # p,q的开始值
                      max_p=12, max_q=12, # 最大的p和q
                      d = 0,            # 寻找ARMA模型参数
                      m=1,              # 序列的周期
                      seasonal=False,   # 没有季节性趋势
                      trace=True,error_action='ignore',  
                      suppress_warnings=True, stepwise=True)
 
print(model.summary())

Je n'ai pas étudié ce domaine en profondeur, la méthode auto présente des avantages et des inconvénients, mais elle peut aussi donner une idée pour écrire du code.

Je suppose que tu aimes

Origine blog.csdn.net/weixin_56115549/article/details/130930187
conseillé
Classement