Parmi les modèles d'espace d'état, il y avait peu de sites qui expliquaient les modèles personnalisés en japonais (je ne pouvais pas les trouver), je publierai donc les résultats de mes propres recherches.
Pour les modèles de statistiques (en particulier les modèles d'espace d'état personnalisés), il était difficile de définir le modèle, donc j'ai eu du mal à le faire.
Je vous serais reconnaissant si vous pouviez signaler des descriptions incorrectes.
La structure du modèle se compose d'une équation d'observation (il existe également un document qui la décrit comme un modèle d'observation) et d'une équation d'état (il existe également un document qui la décrit comme un modèle système).
Équation d'observation: $ y_t = Z_t (x_ {t}) + d_t + \ epsilon_t $ Équation d'état: $ x_ {t + 1} = T_t (x_ {t}) + c_t + R_t \ eta_ {t} $
Bien qu'une explication détaillée soit omise, le modèle d'espace d'états effectue les estimations suivantes pour le passé, le présent et le futur.
Parmi les modèles d'espace d'états, la signification du modèle personnalisé est la suivante.
Équation d'observation:
La différence avec la formule ci-dessus est que $ Z_t $ est fixé dans l'équation d'observation, $ d_t $ dans le terme constant est omis et $ c_t $ dans le terme constant dans l'équation d'état est $ A \ cdot . Remplacé par exp \ left (\ frac {B} {z} \ right) $.
Une constante
B: constante
z: variable exogène
Qu'est-ce qu'une variable exogène: En règle générale, une variable (variable explicative) créée à l'aide de données passées d'une valeur numérique future (variable objective) que vous souhaitez prédire dans une analyse de série chronologique est appelée une variable endogène, mais à part cela. Les variables sont appelées variables exogènes.
Voici maintenant le code Python.
import numpy as np
import pandas as pd
import datetime
import statsmodels.api as sm
import matplotlib.pyplot as plt
%matplotlib inline
plt.rc("figure", figsize=(16,8))
plt.rc("font", size=15)
Créez des données pour les tests. (Lors de son utilisation réelle, un tel travail est inutile, une explication détaillée est donc omise.)
def gen_data_for_model1():
nobs = 1000
rs = np.random.RandomState(seed=93572)
Ht = 5
Tt = 1.001
A = 0.1
B = -0.007
Qt = 0.01
var_z = 0.1
et = rs.normal(scale=Ht**0.5, size=nobs)
z = np.cumsum(rs.normal(size=nobs, scale=var_z**0.05))
Et = rs.normal(scale=Qt**0.5, size=nobs)
xt_1 = 50
x = []
for i in range(nobs):
xt = Tt * xt_1
x.append(xt)
xt_1 = xt
xt = np.array(x)
xt = xt + A * np.exp(B/z) + Et
yt = xt + et
return yt, xt, z
yt, xt, z = gen_data_for_model1()
_ = plt.plot(yt,color = "r")
_ = plt.plot(xt, color="b")
df = pd.DataFrame()
df['y'] = yt
df['x'] = xt
df['z'] = z
st = datetime.datetime.strptime("2001/1/1 0:00", '%Y/%m/%d %H:%M')
date = []
for i in range(1000):
if i == 0:
d = st
dt = d.strftime('%Y/%m/%d %H:%M')
date.append(dt)
d += datetime.timedelta(days=1)
df['date'] = date
df['date'] = pd.to_datetime(df['date'] )
df = df.set_index("date")
df
class custom(sm.tsa.statespace.MLEModel):
param_names = ['T', 'A', 'B', 'Ht', 'Qt'] #Spécifiez les paramètres à estimer
start_params = [1., 1., 0., 1., 1] #Valeur initiale du paramètre à estimer
def __init__(self, endog, exog):
exog = np.squeeze(exog)
super().__init__(endog, exog=exog, k_states=1, initialization='diffuse')
self.k_exog = 1
# Z = I,La partie correspondant à Zt dans l'équation ci-dessus devient cette fois la matrice unitaire.
self['design', 0, 0] = 1.
# R = I,La partie correspondant à Rt dans l'équation ci-dessus devient cette fois la matrice unitaire.
self['selection', 0, 0] = 1.
# c_Régler t à l'heure
self['state_intercept'] = np.zeros((1, self.nobs))
def clone(self, endog, exog, **kwargs):
return self._clone_from_init_kwds(endog, exog=exog, **kwargs)
def transform_params(self, params):
#La variance doit être un nombre positif, alors mettez-la au carré une fois
params[3:] = params[3:]**2
return params
def untransform_params(self, params):
#Au carré 1/Carré pour revenir à la taille d'origine (racine carrée)
params[3:] = params[3:]**0.5
return params
def update(self, params, **kwargs):
#C'est une spécification à mettre à jour
params = super().update(params, **kwargs)
# T = T
self['transition', 0, 0] = params[0]
# c_t = A * exp(B / z_t)
self['state_intercept', 0, :] = params[1] * np.exp(params[2] / self.exog)
# Ht
self['obs_cov', 0, 0] = params[3]
# Qt
self['state_cov', 0, 0] = params[4]
df_test = df.iloc[:800,:]
df_train = df.iloc[800:,:]
mod = custom(df_test['y'], df_test['z'])
res = mod.fit()
print(res.summary())
La partie coef est la valeur estimée, mais elle est proche de la valeur numérique des données créées au début.
ss = pd.DataFrame(res.smoothed_state.T, columns=['x'], index=df_test.index)
predict = res.get_prediction()
forecast = res.get_forecast(df.index[-1], exog = df_train['z'].values)
Lors de la prédiction, vous devez spécifier à quel point vous souhaitez prédire. (Cette heure est spécifiée par df.index [-1]) De plus, lors de l'utilisation de variables exogènes dans le modèle, il est nécessaire de spécifier les données avec l'argument "exog =" au moment de la prédiction. Cette fois, tout est des données factices, mais si vous souhaitez réellement les utiliser dans la prédiction, vous devez créer des données factices à partir de données passées. Les données dont l'espacement des données est irrégulier ne peuvent pas être utilisées pour la prédiction. (Il en va de même pour SARIMAX, qui utilise également des variables exogènes.)
fig, ax = plt.subplots()
y = df['y']
y.plot(ax=ax,label='y')
predict.predicted_mean.plot(label='x')
predict_ci = predict.conf_int(alpha=0.05)
predict_index = predict_ci.index
ax.fill_between(predict_index[2:], predict_ci.iloc[2:, 0], predict_ci.iloc[2:, 1], alpha=0.1)
forecast.predicted_mean.plot(ax=ax, style='r', label='forecast')
forecast_ci = forecast.conf_int()
forecast_index = forecast_ci.index
ax.fill_between(forecast_index, forecast_ci.iloc[:, 0], forecast_ci.iloc[:, 1], alpha=0.1)
legend = ax.legend(loc='best');
fig.savefig('custom_statespace.png')
La partie bleu clair est l'intervalle de confiance estimé à 95% et la partie rose est l'intervalle de confiance prévu à 95%.
Cet article a été rédigé en référence aux informations suivantes.
Merci à Chad Fulton, le développeur de statsmodels!
Nous présenterons également des livres recommandés autres que ceux énumérés ci-dessus. Ils sont répertoriés par ordre de lisibilité relative.
Recherche de l'invisible - Voilà les statistiques pratiques de Bayes avec l'outil Bayes Ce livre est probablement le livre le plus simple pour décrire un modèle d'espace d'État au Japon, et je pense que c'est la meilleure façon de commencer et de voir à quoi il ressemble.
Bases de la modélisation statistique pour la prédiction de l'introduction à l'application des statistiques de base Ce livre a été écrit par le professeur Tomoyuki Higuchi, l'actuel directeur de l'Institut de mathématiques statistiques. Il est difficile de prédire qu'il existe une description du modèle d'espace d'état à partir du titre du livre, mais le modèle d'espace d'état est décrit avec soin.
Bases de l'analyse des séries temporelles et de la théorie et de la mise en œuvre des modèles d'espace d'états appris de R et Tan C'est le livre de M. Baba qui est apparu plusieurs fois dans ce billet. C'est un bon livre très facile à comprendre. Recommandé pour ceux qui veulent apprendre en bougeant leurs mains (codage).
[Analyse de séries chronologiques-modèle d'auto-retour / modèle d'espace d'état / détection d'anomalies-] (https://www.kyoritsu-pub.co.jp/bookdetail/9784320125018) C'est peut-être le seul livre au Japon qui décrit le modèle d'espace d'état en python. Vous serez capable de coder, mais c'est un peu bâclé et difficile à comprendre. Cependant, je n'ai pas touché à un modèle personnalisé comme cet article.
3 octobre 2020: Première édition
Recommended Posts