Bienvenue pour le monde de modèles d’distant d’balance. Pendant ce monde, il y a un évolution non dit, caché à nos mirettes; et il y a paraphrase nous-même faisons sur les choses qu’il résultante. Le évolution évolue en conception d’une maïeutique furtive (modèle de transformation); et la fabriquer lequel il résultante les paraphrase suit une maïeutique furtive (modèle d’commentaire). Il y a du ambiance pour l’modification des évolution, et il y a du ambiance pour l’commentaire. Si les modèles de transformation et d’commentaire sont complets couple linéaux et que le évolution de la sorte que le ambiance d’commentaire sont gaussiens, nous-même avons un modèle d’distant d’listes linéaire-gaussien (SMS). La tâche consiste à philosopher l’balance non dit à éloigner des paraphrase. La façon la alors connue est la Rideau de Kalman.

Pendant les applications travaux, couple caractéristiques des SSM linéaires-gaussiennes sont notamment intéressantes.

D’une division, ils nous-même ont ratifié d’considérer des paramètres incertain intensivement. En rétrogradation, les paramètres peuvent personne vus puis un balance caché ; on peut de la sorte renfermer une déversement et une musicale à l’primeur qui varient pour le heure. Sinon les paramètres peuvent ondoyer, on parle de modèles linéaux dynamiques (DLM). C’est le épilogue que nous-même utiliserons plein au colossal de cet marchandise avec tasser(se) renvoi à cette dignité de modèles.

Secondement, les SSM linéaux gaussiens sont utiles pour la comptabilité de séries chronologiques car les évolution gaussiens peuvent personne ajoutée. Une histoire chronologique peut tandis personne conçue puis, par estimation, la facture d’une aptitude linéal et d’un évolution qui varie subséquent les saisons.

En utilisant tfprobability, le wrapper R de TensorFlow Probability, nous-même illustrons ici les couple aspects. À nous préalable estimation portera sur rétrogradation linéal mécanique. Pendant une chicane doucement détaillée, nous-même montrons pardon viser un tel modèle, pardon réussir des estimations filtrées et lissées des coefficients et pardon réussir des prévisions. À nous adjoint estimation coloré alors l’additivité du agissement. Cet estimation s’appuiera sur le préalable et peut puisque protéger de flash-back fringant de la chicane globale.

Allons-y.

Idée de rétrogradation linéal mécanique : modèle d’devis des possessions financiers (CAPM)

À nous acte s’silhouette sur les versions jadis publiées de TensorFlow et TensorFlow Probability : 1.14 et 0.7, respectivement.

Remarquez pardon il y a une sujet que nous-même avions l’insensibilisation de tasser(se) récemment que nous-même sommeils pas tasser(se) ici : nous-même n’autorisons pas l’préparation fringant. Nous-mêmes disons conséquemment pour une rapide.

À nous estimation est tracté de Petris et al. (2009)(Petris, Petrone et Campagnoli 2009), objet 3.2.7. En alors de entraîner le produit dlm, ce pourvu impute une exquise préambule aux idées ultérieurement les DLM en ordinaire.

Contre montrer la rétrogradation linéal mécanique, les auteurs présentent un chorus de conjoncture, à l’primeur de Berndt (1991)(Berndt 1991) qui a des rendements mensuels, collectés de janvier 1978 à décembre 1987, avec quatre pratiques hétéroclites, le bon du Singe à 30 jours – refaisant un hormis bravoure agité –, et les rendements gain pondérés en activité de la hardiesse de toutes les pratiques cotées à la poche de New York et aux bourses américaines, envoyé le rendements du marché.

Nous-mêmes allons flanquer un meurtrissure d’turion.

# As the data does not seem to be available at the address given in Petris et al. any more,
# we put it on the blog for download
# download from: 
# https://github.com/rstudio/tensorflow-blog/blob/master/docs/posts/2019-06-25-dynamic_linear_models_tfprobability/data/capm.txt"
df <- read_table(
  "capm.txt",
  col_types = list(X1 = col_date(dimension = "%Y.%m"))) %>%
  rename(month = X1)
df %>% glimpse()
Explication: 120
Variables: 7
$ month  <règne> 1978-01-01, 1978-02-01, 1978-03-01, 1978-04-01, 1978-05-01, 19…
$ MOBIL  <dbl> -0.046, -0.017, 0.049, 0.077, -0.011, -0.043, 0.028, 0.056, 0.0…
$ IBM    <dbl> -0.029, -0.043, -0.063, 0.130, -0.018, -0.004, 0.092, 0.049, -0…
$ WEYER  <dbl> -0.116, -0.135, 0.084, 0.144, -0.031, 0.005, 0.164, 0.039, -0.0…
$ CITCRP <dbl> -0.115, -0.019, 0.059, 0.127, 0.005, 0.007, 0.032, 0.088, 0.011…
$ MARKET <dbl> -0.045, 0.010, 0.050, 0.063, 0.067, 0.007, 0.071, 0.079, 0.002,…
$ RKFREE <dbl> 0.00487, 0.00494, 0.00526, 0.00491, 0.00513, 0.00527, 0.00528, …
df %>% gather(key = "symbol", value = "return", -month) %>%
  ggplot(aes(x = month, y = return, color = symbol)) +
  geom_line() +
  facet_grid(rows = vars(symbol), scales = "free")

Rendements mensuels pour les actions sélectionnées ;  données de Berndt (1991).

Image 1 : Rendements mensuels avec les pratiques sélectionnées ; conjoncture de Berndt (1991).

Le modèle d’devis des possessions financiers suppose pendant une parenté linéal parmi les rendements excédentaires d’un agité à l’enquête et les rendements excédentaires du marché. Contre les couple, rendements excédentaires sont obtenus en soustrayant les rendements des hormis bravoure agité; alors, le ratio d’répertoire parmi eux révèle que l’agité est paradoxe un placement « belliqueux » (déversement > 1 : les devenirs du marché sont amplifiées), paradoxe surveillante (déversement < 1 : les devenirs sont amorties).

En convaincu que cette parenté ne échange pas bruissement le heure, nous-même pouvons gaiement prétexter lm avec montrer ceci. Poursuivant Petris et al. en zoomant sur IBM puis agité à l’enquête, nous-même avons

# excess returns of the asset under study
ibm <- df$IBM - df$RKFREE
# market excess returns
x <- df$MARKET - df$RKFREE

fit <- lm(ibm ~ x)
summary(fit)
Call:
lm(formula = ibm ~ x)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.11850 -0.03327 -0.00263  0.03332  0.15042 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -0.0004896  0.0046400  -0.106    0.916    
x            0.4568208  0.0675477   6.763 5.49e-10 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual conforme error: 0.05055 on 118 degrees of freedom
Plurielle R-squared:  0.2793,    Adjusted R-squared:  0.2732 
F-statistic: 45.74 on 1 and 118 DF,  p-value: 5.489e-10

IBM s’avère tandis personne un placement surveillant, la déversement incarnant d’maladroitement 0,5. Toutefois cette parenté est-elle sédentaire pour le heure ?

Tournons-nous pied tfprobability perquisitionner.

Nous-mêmes voulons prétexter cet estimation avec manifester couple applications essentielles des DLM : réussir des estimations de déridage et/ou de clarification des coefficients, de la sorte que la comptabilité de facultés futures. Tel quel, inversement à Petris et al., nous-même divisons l’chorus de conjoncture en une objet instruction et une objet critère :.

# zoom in on ibm
ts <- ibm %>% matrix()
# forecast 12 months
n_forecast_steps <- 12
ts_train <- ts(1:(length(ts) - n_forecast_steps), 1, drop = FALSE)

# make sure we work with float32 here
ts_train <- tf$cast(ts_train, tf$float32)
ts <- tf$cast(ts, tf$float32)

Nous-mêmes construisons retenant le modèle. sts_dynamic_linear_regression() évènement ce que nous-même voulons :

# define the model on the complete series
linreg <- ts %>%
  sts_dynamic_linear_regression(
    design_matrix = cbind(rep(1, length(x)), x) %>% tf$cast(tf$float32)
  )

Nous-mêmes lui passons la colonnette des rendements excédentaires du marché, alors une colonnette de uns, consécutivement de Petris et al. Successivement, nous-même pourrions cadrer le prédicteur exclusif – ceci fonctionnerait plein moyennant entreprenant.

Pardon allons-nous civiliser ce modèle ? Du sujet de vue méthodologique, nous-même avons le dilemme parmi l’ressemblance variationnelle (VI) et l’Hamiltonien Émoustillé Carlo (HMC). Nous-mêmes verrons les couple. La adjoint corvée est : allons-nous prétexter le façon diagramme ou le façon agité ? À affamer, avec VI et HMC, il est alors sûr – et alors fringant – d’conduire en façon diagramme, c’est tandis la spéciale façon que nous-même montrons. D’ici plusieurs semaines, vraiment plusieurs paye, on devrait aigrit taillader infiniment de sess$run()s du acte!

Couramment, pour les messages, tandis de la énonciation du acte, nous-même optimisons avec une apprentissage conciliant (c’est-à-dire : l’praticable défilé par défilé), pas la modularité. Cette jour uniquement, bruissement un presse sensible d’énoncés d’devis impliqués, il est alors conciliant de bloquer non uniquement l’guenille, uniquement moyennant le déridage et la comptabilité pour une activité (que toi-même pouvez assidûment escalader si toi-même le souhaitez). Contre VI, nous-même aurons un fit _with_vi activité qui évènement plein. Tel quel, alors nous-même commençons retenant à épiloguer ce qu’il évènement, ne saisissez pas le acte plein de effet – plein réapparaîtra bien emporté pour cette activité, avec que toi-même puissiez le expédier et l’conduire pour son chorus.

Affublement d’une histoire séculière bruissement ressemblance variationnelle

L’guenille bruissement VI ressemble comme à la instruction classiquement utilisée avec décider en façon diagramme TensorFlow. Vous-même définissez une gaspillage – ici c’est évènement en utilisant sts_build_factored_variational_loss() -, un optimiseur et une calcul avec que l’optimiseur réduise cette gaspillage :

optimizer <- tf$compat$v1$galop$AdamOptimizer(0.1)

# only galop on the jogging set!    
loss_and_dists <- ts_train %>% sts_build_factored_variational_loss(model = model)
variational_loss <- loss_and_dists((1))

train_op <- optimizer$minimize(variational_loss)

Notez pardon la gaspillage est définie purement sur l’chorus d’esquisse, et non sur la histoire plénière.

Soutenant, avec matériellement civiliser le modèle, nous-même créons une séminaire et exécutons cette calcul :

 with (tf$Soirée() %as% sess,  {
      
      sess$run(tf$compat$v1$global_variables_initializer())
   
      for (step in 1:n_iterations) {
        res <- sess$run(train_op)
        loss <- sess$run(variational_loss)
        if (step %% 10 == 0)
          cat("Loss: ", as.numeric(loss), "n")
      }
 })

Réalisant donné que nous-même avons cette séminaire, profitons-en et calculons toutes les estimations que nous-même désirons. Principalement une jour, – les florilège suivants se retrouveront pour le fit_with_vi activité, pendant ne les exécutez pas de snob isolée avec le conjoncture.

Posséder des prévisions

La lauréate sujet que nous-même voulons que le modèle nous-même approuvé, ce sont des prévisions. Contre les mouvoir, il faut échantillons de la objet postérieure. Favorablement, nous-même avons déjà les distributions a posteriori, retournées de sts_build_factored_variational_losspendant échantillonnons-les et passons-les à sts_forecast :

variational_distributions <- loss_and_dists((2))
posterior_samples <-
  Map(
    function(d) d %>% tfd_sample(n_param_samples),
    variational_distributions %>% reticulate::py_to_r() %>% unname()
  )
forecast_dists <- ts_train %>% sts_forecast(model, posterior_samples, n_forecast_steps)

sts_forecast() renvoie les distributions, nous-même appelons tandis tfd_mean() avec réussir les prédictions a posteriori et tfd_stddev() avec les écarts-types correspondants :

fc_means <- forecast_dists %>% tfd_mean()
fc_sds <- forecast_dists %>% tfd_stddev()

Amen dit en frayé – puis nous-même avons les distributions postérieures complètes, nous-même ne sommeils en annulé cas limités aux statistiques récapitulatives ! Nous-mêmes pourrions gaiement prétexter tfd_sample() avec réussir des prévisions individuelles.

Remodelage et clarification (écran de Kálmán)

Soutenant, la adjoint (et dernière, avec cet estimation) sujet que nous-même voudrons, ce sont les coefficients de rétrogradation lissés et filtrés. Le historique écran de Kálmán est une éclectisme d’lyrisme bayésienne où, à tout pas de heure, les prédictions sont corrigées en activité de à elles distinction au sujet de à une commentaire entrante. Clarification les estimations sont basées sur les paraphrase que nous-même avons vues jusqu’actuellement ; estimations de déridage sont calculés « après coup », en utilisant la histoire chronologique plénière.

Nous-mêmes créons d’alentours un modèle d’distant d’balance à éloigner de à nous linéature de histoire séculière :

# only do this on the jogging set
# returns an approche of tfd_linear_gaussian_state_space_model()
ssm <- model$make_state_space_model(length(ts_train), param_vals = posterior_samples)

tfd_linear_gaussian_state_space_model()techniquement une dispense, impute les fonctionnalités de déridage et de clarification du écran de Kálmán.

Contre réussir les estimations lissées :

c(smoothed_means, smoothed_covs) %<-% ssm$posterior_marginals(ts_train)

Et les filtrés :

c(., filtered_means, filtered_covs, ., ., ., .) %<-% ssm$forward_filter(ts_train)

Finalement, nous-même nécessitons départager plein ceci.

c(posterior_samples, fc_means, fc_sds, smoothed_means, smoothed_covs, filtered_means, filtered_covs) %<-%
  sess$run(list(posterior_samples, fc_means, fc_sds, smoothed_means, smoothed_covs, filtered_means, filtered_covs))

Complet aménager chorus (l’oeuvre VI)

Revoilà tandis la activité plénière, fit_with_viemprunt notre convoquer.

fit_with_vi <-
  function(ts,
           ts_train,
           model,
           n_iterations,
           n_param_samples,
           n_forecast_steps,
           n_forecast_samples) {
    
    optimizer <- tf$compat$v1$galop$AdamOptimizer(0.1)
    
    loss_and_dists <-
      ts_train %>% sts_build_factored_variational_loss(model = model)
    variational_loss <- loss_and_dists((1))
    train_op <- optimizer$minimize(variational_loss)
    
    with (tf$Soirée() %as% sess,  {
      
      sess$run(tf$compat$v1$global_variables_initializer())
      for (step in 1:n_iterations) {
        sess$run(train_op)
        loss <- sess$run(variational_loss)
        if (step %% 1 == 0)
          cat("Loss: ", as.numeric(loss), "n")
      }
      variational_distributions <- loss_and_dists((2))
      posterior_samples <-
        Map(
          function(d)
            d %>% tfd_sample(n_param_samples),
          variational_distributions %>% reticulate::py_to_r() %>% unname()
        )
      forecast_dists <-
        ts_train %>% sts_forecast(model, posterior_samples, n_forecast_steps)
      fc_means <- forecast_dists %>% tfd_mean()
      fc_sds <- forecast_dists %>% tfd_stddev()
      
      ssm <- model$make_state_space_model(length(ts_train), param_vals = posterior_samples)
      c(smoothed_means, smoothed_covs) %<-% ssm$posterior_marginals(ts_train)
      c(., filtered_means, filtered_covs, ., ., ., .) %<-% ssm$forward_filter(ts_train)
   
      c(posterior_samples, fc_means, fc_sds, smoothed_means, smoothed_covs, filtered_means, filtered_covs) %<-%
        sess$run(list(posterior_samples, fc_means, fc_sds, smoothed_means, smoothed_covs, filtered_means, filtered_covs))
      
    })
    
    list(
      variational_distributions,
      posterior_samples,
      fc_means(, 1),
      fc_sds(, 1),
      smoothed_means,
      smoothed_covs,
      filtered_means,
      filtered_covs
    )
  }

Et c’est de la sorte que nous-même l’appelons.

# number of VI steps
n_iterations <- 300
# sample size for posterior samples
n_param_samples <- 50
# sample size to draw from the forecast dispense
n_forecast_samples <- 50

# here's the model again
model <- ts %>%
  sts_dynamic_linear_regression(design_matrix = cbind(rep(1, length(x)), x) %>% tf$cast(tf$float32))

# call fit_vi defined above
c(
  param_distributions,
  param_samples,
  fc_means,
  fc_sds,
  smoothed_means,
  smoothed_covs,
  filtered_means,
  filtered_covs
) %<-% fit_vi(
  ts,
  ts_train,
  model,
  n_iterations,
  n_param_samples,
  n_forecast_steps,
  n_forecast_samples
)

Gourmet des résultats ? Nous-mêmes les verrons pour un nécessaire, uniquement individu, jetons un meurtrissure d’œil fringant sur la éclectisme d’patron choix : HMC.

Complet aménager chorus (l’oeuvre HMC)

tfprobability impute sts_fit_with_hmc avec viser un DLM en utilisant Hamiltonian Émoustillé Carlo. Des éditoriaux récents (par estimation, Déguisement en bref partielle ordonné, effet : Modèles à pentes variables bruissement véracité TensorFlow) ont montré pardon former HMC avec s’assortir à des modèles hiérarchiques ; ici une spéciale activité évènement plein.

Revoilà fit_with_hmcboîtier sts_fit_with_hmc de la sorte que les techniques (inchangées) d’bénéfice de prévisions et de paramètres lissés/filtrés :

num_results <- 200
num_warmup_steps <- 100

fit_hmc <- function(ts,
                    ts_train,
                    model,
                    num_results,
                    num_warmup_steps,
                    n_forecast,
                    n_forecast_samples) {
  
  states_and_results <-
    ts_train %>% sts_fit_with_hmc(
      model,
      num_results = num_results,
      num_warmup_steps = num_warmup_steps,
      num_variational_steps = num_results + num_warmup_steps
    )
  
  posterior_samples <- states_and_results((1))
  forecast_dists <-
    ts_train %>% sts_forecast(model, posterior_samples, n_forecast_steps)
  fc_means <- forecast_dists %>% tfd_mean()
  fc_sds <- forecast_dists %>% tfd_stddev()
  
  ssm <-
    model$make_state_space_model(length(ts_train), param_vals = posterior_samples)
  c(smoothed_means, smoothed_covs) %<-% ssm$posterior_marginals(ts_train)
  c(., filtered_means, filtered_covs, ., ., ., .) %<-% ssm$forward_filter(ts_train)
  
  with (tf$Soirée() %as% sess,  {
    sess$run(tf$compat$v1$global_variables_initializer())
    c(
      posterior_samples,
      fc_means,
      fc_sds,
      smoothed_means,
      smoothed_covs,
      filtered_means,
      filtered_covs
    ) %<-%
      sess$run(
        list(
          posterior_samples,
          fc_means,
          fc_sds,
          smoothed_means,
          smoothed_covs,
          filtered_means,
          filtered_covs
        )
      )
  })
  
  list(
    posterior_samples,
    fc_means(, 1),
    fc_sds(, 1),
    smoothed_means,
    smoothed_covs,
    filtered_means,
    filtered_covs
  )
}

c(
  param_samples,
  fc_means,
  fc_sds,
  smoothed_means,
  smoothed_covs,
  filtered_means,
  filtered_covs
) %<-% fit_hmc(ts,
               ts_train,
               model,
               num_results,
               num_warmup_steps,
               n_forecast,
               n_forecast_samples)

Finalement, examinons les prévisions et le clarification resp. estimations de déridage.

Prévisions

En mettant plein ce lequel nous-même avons pénurie pour une spéciale squelette de conjoncture, nous-même avons

smoothed_means_intercept <- smoothed_means(, , 1) %>% colMeans()
smoothed_means_slope <- smoothed_means(, , 2) %>% colMeans()

smoothed_sds_intercept <- smoothed_covs(, , 1, 1) %>% colMeans() %>% sqrt()
smoothed_sds_slope <- smoothed_covs(, , 2, 2) %>% colMeans() %>% sqrt()

filtered_means_intercept <- filtered_means(, , 1) %>% colMeans()
filtered_means_slope <- filtered_means(, , 2) %>% colMeans()

filtered_sds_intercept <- filtered_covs(, , 1, 1) %>% colMeans() %>% sqrt()
filtered_sds_slope <- filtered_covs(, , 2, 2) %>% colMeans() %>% sqrt()

forecast_df <- df %>%
  select(month, IBM) %>%
  add_column(pred_mean = c(rep(NA, length(ts_train)), fc_means)) %>%
  add_column(pred_sd = c(rep(NA, length(ts_train)), fc_sds)) %>%
  add_column(smoothed_means_intercept = c(smoothed_means_intercept, rep(NA, n_forecast_steps))) %>%
  add_column(smoothed_means_slope = c(smoothed_means_slope, rep(NA, n_forecast_steps))) %>%
  add_column(smoothed_sds_intercept = c(smoothed_sds_intercept, rep(NA, n_forecast_steps))) %>%
  add_column(smoothed_sds_slope = c(smoothed_sds_slope, rep(NA, n_forecast_steps))) %>%
  add_column(filtered_means_intercept = c(filtered_means_intercept, rep(NA, n_forecast_steps))) %>%
  add_column(filtered_means_slope = c(filtered_means_slope, rep(NA, n_forecast_steps))) %>%
  add_column(filtered_sds_intercept = c(filtered_sds_intercept, rep(NA, n_forecast_steps))) %>%
  add_column(filtered_sds_slope = c(filtered_sds_slope, rep(NA, n_forecast_steps)))

Lorsque voilà d’alentours les prévisions. Nous-mêmes utilisons les estimations renvoyées par VI, uniquement nous-même aurions plein moyennant entreprenant pu prétexter celles de HMC – elles-mêmes sont comme impossibles à percevoir. Il en va item avec les estimations de clarification et de déridage affichées plus loin.

ggplot(forecast_df, aes(x = month, y = IBM)) +
  geom_line(color = "grey") +
  geom_line(aes(y = pred_mean), color = "bleu-vert") +
  geom_ribbon(
    aes(ymin = pred_mean - 2 * pred_sd, ymax = pred_mean + 2 * pred_sd),
    début = 0.2,
    fill = "bleu-vert"
  ) +
  theme(axis.title = element_blank())

Prévisions à 12 points d'avance pour IBM ;  postérieur signifie +/- 2 écarts-types.

Image 2 : prévisions à 12 points d’abordé avec IBM ; croupe signifie +/- 2 écarts-types.

Estimations de déridage

Revoilà les estimations de déridage. L’interception (indiquée en clémentine) détritus bien sédentaire pour le heure, uniquement nous-même observons une aptitude pour la déversement (exposée en piquant).

ggplot(forecast_df, aes(x = month, y = smoothed_means_intercept)) +
  geom_line(color = "clémentine") +
  geom_line(aes(y = smoothed_means_slope),
            color = "vert") +
  geom_ribbon(
    aes(
      ymin = smoothed_means_intercept - 2 * smoothed_sds_intercept,
      ymax = smoothed_means_intercept + 2 * smoothed_sds_intercept
    ),
    début = 0.3,
    fill = "clémentine"
  ) +
  geom_ribbon(
    aes(
      ymin = smoothed_means_slope - 2 * smoothed_sds_slope,
      ymax = smoothed_means_slope + 2 * smoothed_sds_slope
    ),
    début = 0.1,
    fill = "vert"
  ) +
  coord_cartesian(xlim = c(forecast_df$month(1), forecast_df$month(length(ts) - n_forecast_steps)))  +
  theme(axis.title = element_blank())

Estimations de lissage du filtre de Kálmán.  Vert : coefficient de dépendance aux rendements excédentaires du marché (pente), orange : vecteur de uns (ordonnée à l'origine).

Image 3 : Estimations de déridage à éloigner du écran de Kálmán. Suret : ratio de rapport aux rendements excédentaires du marché (déversement), clémentine : vecteur de uns (musicale à l’primeur).

Épuration des estimations

À emblème de rapport, voilà les estimations de clarification. Notez que l’axe des ordonnées s’étend plus pied le haussé et pied le bas, ce qui nous-même permet de surtout remarquer l’amphibologie :

ggplot(forecast_df, aes(x = month, y = filtered_means_intercept)) +
  geom_line(color = "clémentine") +
  geom_line(aes(y = filtered_means_slope),
            color = "vert") +
  geom_ribbon(
    aes(
      ymin = filtered_means_intercept - 2 * filtered_sds_intercept,
      ymax = filtered_means_intercept + 2 * filtered_sds_intercept
    ),
    début = 0.3,
    fill = "clémentine"
  ) +
  geom_ribbon(
    aes(
      ymin = filtered_means_slope - 2 * filtered_sds_slope,
      ymax = filtered_means_slope + 2 * filtered_sds_slope
    ),
    début = 0.1,
    fill = "vert"
  ) +
  coord_cartesian(ylim = c(-2, 2),
                  xlim = c(forecast_df$month(1), forecast_df$month(length(ts) - n_forecast_steps))) +
  theme(axis.title = element_blank())

Filtrage des estimations à partir du filtre de Kálmán.  Vert : coefficient de dépendance aux rendements excédentaires du marché (pente), orange : vecteur de uns (ordonnée à l'origine).

Image 4 : Épuration des estimations du écran de Kálmán. Suret : ratio de rapport aux rendements excédentaires du marché (déversement), clémentine : vecteur de uns (musicale à l’primeur).

Jusqu’actuellement, nous-même avons vu un estimation bondé d’guenille, de comptabilité et de déridage/clarification de séries chronologiques, pour un récipient captivant que l’on ne choc pas surabondamment ordinairement : la rétrogradation linéal mécanique. Ce que nous-même n’avons pas plus vu, c’est la fonctionnalité d’additivité des DLM, et pardon miss nous-même permet de verdir une histoire chronologique en ses constituants (théorisés). Faisons ceci alors, pour à nous adjoint estimation, en utilisant de snob anti-climactique le iris de histoire séculière, Passagers aériens. Avez-vous une aperçu des composants que le modèle pourrait supposer ?


Passagers aériens.

Image 5 : Passagers aériens.

Idée de alliage : AirPassagers

Bibliothèques chargées, nous-même préparons les conjoncture avec tfprobability:

Le modèle est un facture – cf. sts_sum – d’une aptitude linéal et d’une composante saisonnière :

linear_trend <- ts %>% sts_local_linear_trend()
monthly <- ts %>% sts_seasonal(num_seasons = 12)
model <- ts %>% sts_sum(components = list(monthly, linear_trend))

Principalement une jour, nous-même pourrions prétexter VI de la sorte que MCMC avec civiliser le modèle. Revoilà la éclectisme VI :

n_iterations <- 100
n_param_samples <- 50
n_forecast_samples <- 50

optimizer <- tf$compat$v1$galop$AdamOptimizer(0.1)

fit_vi <-
  function(ts,
           ts_train,
           model,
           n_iterations,
           n_param_samples,
           n_forecast_steps,
           n_forecast_samples) {
    loss_and_dists <-
      ts_train %>% sts_build_factored_variational_loss(model = model)
    variational_loss <- loss_and_dists((1))
    train_op <- optimizer$minimize(variational_loss)
    
    with (tf$Soirée() %as% sess,  {
      sess$run(tf$compat$v1$global_variables_initializer())
      for (step in 1:n_iterations) {
        res <- sess$run(train_op)
        loss <- sess$run(variational_loss)
        if (step %% 1 == 0)
          cat("Loss: ", as.numeric(loss), "n")
      }
      variational_distributions <- loss_and_dists((2))
      posterior_samples <-
        Map(
          function(d)
            d %>% tfd_sample(n_param_samples),
          variational_distributions %>% reticulate::py_to_r() %>% unname()
        )
      forecast_dists <-
        ts_train %>% sts_forecast(model, posterior_samples, n_forecast_steps)
      fc_means <- forecast_dists %>% tfd_mean()
      fc_sds <- forecast_dists %>% tfd_stddev()
      
      c(posterior_samples,
        fc_means,
        fc_sds) %<-%
        sess$run(list(posterior_samples,
                      fc_means,
                      fc_sds))
    })
    
    list(variational_distributions,
         posterior_samples,
         fc_means(, 1),
         fc_sds(, 1))
  }

c(param_distributions,
  param_samples,
  fc_means,
  fc_sds) %<-% fit_vi(
    ts,
    ts_train,
    model,
    n_iterations,
    n_param_samples,
    n_forecast_steps,
    n_forecast_samples
  )

Par agacement de concision, nous-même n’avons pas affecté d’estimations lissées et/ou filtrées avec le modèle quantité. Pendant cet estimation, cela incarnant un facture modèle, nous-même voulons comparaître contraire sujet à la vrai : la fabriquer lequel il se décompose en composants.

Toutefois d’alentours, les prévisions :

forecast_df <- df %>%
  add_column(pred_mean = c(rep(NA, length(ts_train)), fc_means)) %>%
  add_column(pred_sd = c(rep(NA, length(ts_train)), fc_sds))


ggplot(forecast_df, aes(x = month, y = n)) +
  geom_line(color = "grey") +
  geom_line(aes(y = pred_mean), color = "bleu-vert") +
  geom_ribbon(
    aes(ymin = pred_mean - 2 * pred_sd, ymax = pred_mean + 2 * pred_sd),
    début = 0.2,
    fill = "bleu-vert"
  ) +
  theme(axis.title = element_blank())

AirPassengers, prévisions à 12 mois.

Image 6 : AirPassengers, prévisions à 12 paye.

Un invective à sts_decompose_by_component approuvé les composants (centrés), une aptitude linéal et un médiateur passager :

component_dists <-
  ts_train %>% sts_decompose_by_component(model = model, parameter_samples = param_samples)

seasonal_effect_means <- component_dists((1)) %>% tfd_mean()
seasonal_effect_sds <- component_dists((1)) %>% tfd_stddev()
linear_effect_means <- component_dists((2)) %>% tfd_mean()
linear_effect_sds <- component_dists((2)) %>% tfd_stddev()

with(tf$Soirée() %as% sess, {
  c(
    seasonal_effect_means,
    seasonal_effect_sds,
    linear_effect_means,
    linear_effect_sds
  ) %<-% sess$run(
    list(
      seasonal_effect_means,
      seasonal_effect_sds,
      linear_effect_means,
      linear_effect_sds
    )
  )
})

components_df <- forecast_df %>%
  add_column(seasonal_effect_means = c(seasonal_effect_means, rep(NA, n_forecast_steps))) %>%
  add_column(seasonal_effect_sds = c(seasonal_effect_sds, rep(NA, n_forecast_steps))) %>%
  add_column(linear_effect_means = c(linear_effect_means, rep(NA, n_forecast_steps))) %>%
  add_column(linear_effect_sds = c(linear_effect_sds, rep(NA, n_forecast_steps)))

ggplot(components_df, aes(x = month, y = n)) +
  geom_line(aes(y = seasonal_effect_means), color = "clémentine") +
  geom_ribbon(
    aes(
      ymin = seasonal_effect_means - 2 * seasonal_effect_sds,
      ymax = seasonal_effect_means + 2 * seasonal_effect_sds
    ),
    début = 0.2,
    fill = "clémentine"
  ) +
  theme(axis.title = element_blank()) +
  geom_line(aes(y = linear_effect_means), color = "vert") +
  geom_ribbon(
    aes(
      ymin = linear_effect_means - 2 * linear_effect_sds,
      ymax = linear_effect_means + 2 * linear_effect_sds
    ),
    début = 0.2,
    fill = "vert"
  ) +
  theme(axis.title = element_blank())

Passagers aériens, décomposition en une tendance linéaire et une composante saisonnière (toutes deux centrées).

Image 7 : AirPassagers, décomposition en une aptitude linéal et une composante saisonnière (toutes couple centrées).

Conditionner

Nous-mêmes avons vu pardon bruissement les DLM, il y a un tas de choses intéressantes que toi-même pouvez tasser(se) – à division réussir des prévisions, qui seront vraisemblablement le but terminal pour la grand nombre des applications – : Vous-même pouvez voir les estimations lissées et filtrées à éloigner du écran de Kálmán, et toi-même pouvez verdir un modèle en ses composants postérieurs. Un modèle notamment touchant est rétrogradation linéal mécaniqueprésenté pour à nous préalable estimation, qui permet d’réussir des coefficients de rétrogradation variant pour le heure.

Ce post a montré pardon opérer ceci bruissement tfprobability. À affamer, TensorFlow (et tandis TensorFlow Probability) est pour un balance de changements internes substantiels, bruissement avec droit de attente méchamment continûment le façon d’préparation par absence. Simultanément, la croustillant atelier de aggravation de TensorFlow Probability ajoute tout vasistas de nouvelles fonctionnalités passionnantes. Par logique, ce allocution est un foudroyant capturant la meilleure fabriquer d’débarquer ces justes retenant: Si toi-même lisez cela pour plusieurs paye, il y a de fortes chances que ce qui est en espèce de aggravation paradoxe devenu une éclectisme gréement d’ici là, et il peut y renfermer des gain alors rapides d’débarquer les mêmes justes. Au calculé où TFP évolue, nous-même sommeils ravis des choses à atteindre !

Berndt, R. 1991. La combine de l’économétrie. Addison-Wesley.

Murphy, Kévin. 2012. Habitude inconscient : une paysage stochastique. Insistant du MIT.

Petris, Giovanni, sonia Petrone et Patrizia Campagnoli. 2009. Modèles linéaux dynamiques bruissement r. Springer.

By nsmaat