Réseau de neurones convolutifs pour les séries temporelles?

21

Je voudrais savoir s'il existe un code pour former un réseau neuronal convolutionnel à la classification des séries chronologiques.

J'ai vu des articles récents ( http://www.fer.unizg.hr/_download/repository/KDI-Djalto.pdf ) mais je ne sais pas s'il existe quelque chose ou si je dois le coder moi-même.

moelleux
la source
1
Mec, c'est très étrange. CNN est un outil très génial pour les images (signaux) et il n'y a presque aucun article sur la prédiction des stocks les utilisant ... Tout ce que je peux trouver concerne les anciens réseaux de neurones qui n'étaient bons à rien à l'époque ...
MasterID

Réponses:

21

Si vous voulez une solution de boîte noire open source, essayez de regarder Weka , une bibliothèque java d'algorithmes ML. Ce type a également utilisé Covolutional Layers dans Weka et vous pouvez modifier son code de classification pour l'adapter à une tâche de classification de séries chronologiques.

Quant au codage du vôtre ... Je travaille sur le même problème en utilisant la bibliothèque python, theano (je vais éditer ce post avec un lien vers mon code si je le craque très bientôt). Voici une liste complète de tous les documents que je vais utiliser pour m'aider à passer une bonne heure de recherche sur le Web:

Comme point de départ, vous pouvez modifier le code trouvé ici pour classer selon un nombre différent de catégories, ou le modifier de la classification à la régression - je l'ai fait en supprimant la couche softmax finale et en créant un seul nœud de sortie. Je l'ai formé sur des tranches de fonction comme y=sin(x)un test.

Alexander McFarlane
la source
Juste pour info - j'ai trouvé beaucoup d'erreurs dans certains d'entre eux, alors ne les appliquez pas aveuglément. Certains d'entre eux ne sont notamment pas des articles publiés. C'est un bon point de départ pour apprendre les bases
Alexander McFarlane
Ce serait apprécié si vous pouviez partager vos connaissances acquises sur les articles mentionnés ici qui ont des problèmes?
bicepjai
1

Il est tout à fait possible d'utiliser un CNN pour faire des prédictions de séries temporelles que ce soit la régression ou la classification. Les CNN sont bons pour trouver des modèles locaux et, en fait, les CNN fonctionnent avec l'hypothèse que les modèles locaux sont pertinents partout. La convolution est également une opération bien connue dans les séries chronologiques et le traitement du signal. Un autre avantage par rapport aux RNN est qu'ils peuvent être très rapides à calculer car ils peuvent être parallélisés par opposition à la nature séquentielle RNN.

Dans le code ci-dessous, je vais démontrer une étude de cas où il est possible de prédire la demande d'électricité en R en utilisant des keras. Notez que ce n'est pas un problème de classification (je n'avais pas d'exemple à portée de main) mais il n'est pas difficile de modifier le code pour gérer un problème de classification (utilisez une sortie softmax au lieu d'une sortie linéaire et une perte d'entropie croisée).

L'ensemble de données est disponible dans la bibliothèque fpp2:

library(fpp2)
library(keras)

data("elecdemand")

elec <- as.data.frame(elecdemand)

dm <- as.matrix(elec[, c("WorkDay", "Temperature", "Demand")])

Ensuite, nous créons un générateur de données. Il est utilisé pour créer des lots de données de formation et de validation à utiliser pendant le processus de formation. Notez que ce code est une version plus simple d'un générateur de données trouvé dans le livre "Deep Learning with R" (et la version vidéo de celui-ci "Deep Learning with R in Motion") de publications manning.

data_gen <- function(dm, batch_size, ycol, lookback, lookahead) {

  num_rows <- nrow(dm) - lookback - lookahead
  num_batches <- ceiling(num_rows/batch_size)
  last_batch_size <- if (num_rows %% batch_size == 0) batch_size else num_rows %% batch_size
  i <- 1
  start_idx <- 1
  return(function(){
    running_batch_size <<- if (i == num_batches) last_batch_size else batch_size
    end_idx <- start_idx + running_batch_size - 1
    start_indices <- start_idx:end_idx

    X_batch <- array(0, dim = c(running_batch_size,
                                lookback,
                                ncol(dm)))
    y_batch <- array(0, dim = c(running_batch_size, 
                                length(ycol)))

    for (j in 1:running_batch_size){
      row_indices <- start_indices[j]:(start_indices[j]+lookback-1)
      X_batch[j,,] <- dm[row_indices,]
      y_batch[j,] <- dm[start_indices[j]+lookback-1+lookahead, ycol]
    }
    i <<- i+1
    start_idx <<- end_idx+1 
    if (i > num_batches){
      i <<- 1
      start_idx <<- 1
    }

    list(X_batch, y_batch)

  })
}

Ensuite, nous spécifions certains paramètres à transmettre à nos générateurs de données (nous créons deux générateurs, un pour la formation et un pour la validation).

lookback <- 72
lookahead <- 1
batch_size <- 168
ycol <- 3

Le paramètre de rétrospection est de savoir jusqu'où nous voulons regarder dans le passé et d'anticiper jusqu'où nous voulons prédire l'avenir.

Ensuite, nous séparons notre ensemble de données et créons deux générateurs:

train_dm <- dm [1: 15000,]

val_dm <- dm[15001:16000,]
test_dm <- dm[16001:nrow(dm),]

train_gen <- data_gen(
  train_dm,
  batch_size = batch_size,
  ycol = ycol,
  lookback = lookback,
  lookahead = lookahead
)


val_gen <- data_gen(
  val_dm,
  batch_size = batch_size,
  ycol = ycol,
  lookback = lookback,
  lookahead = lookahead
)

Ensuite, nous créons un réseau de neurones avec une couche convolutionnelle et formons le modèle:

model <- keras_model_sequential() %>%
  layer_conv_1d(filters=64, kernel_size=4, activation="relu", input_shape=c(lookback, dim(dm)[[-1]])) %>%
  layer_max_pooling_1d(pool_size=4) %>%
  layer_flatten() %>%
  layer_dense(units=lookback * dim(dm)[[-1]], activation="relu") %>%
  layer_dropout(rate=0.2) %>%
  layer_dense(units=1, activation="linear")


model %>% compile(
  optimizer = optimizer_rmsprop(lr=0.001),
  loss = "mse",
  metric = "mae"
)

val_steps <- 48

history <- model %>% fit_generator(
  train_gen,
  steps_per_epoch = 50,
  epochs = 50,
  validation_data = val_gen,
  validation_steps = val_steps
)

Enfin, nous pouvons créer du code pour prédire une séquence de 24 points de données en utilisant une procédure simple, expliquée dans les commentaires R.

####### How to create predictions ####################

#We will create a predict_forecast function that will do the following: 
#The function will be given a dataset that will contain weather forecast values and Demand values for the lookback duration. The rest of the MW values will be non-available and 
#will be "filled-in" by the deep network (predicted). We will do this with the test_dm dataset.

horizon <- 24

#Store all target values in a vector
goal_predictions <- test_dm[1:(lookback+horizon),ycol]
#get a copy of the dm_test
test_set <- test_dm[1:(lookback+horizon),]
#Set all the Demand values, except the lookback values, in the test set to be equal to NA.
test_set[(lookback+1):nrow(test_set), ycol] <- NA

predict_forecast <- function(model, test_data, ycol, lookback, horizon) {
  i <-1
  for (i in 1:horizon){
    start_idx <- i
    end_idx <- start_idx + lookback - 1
    predict_idx <- end_idx + 1
    input_batch <- test_data[start_idx:end_idx,]
    input_batch <- input_batch %>% array_reshape(dim = c(1, dim(input_batch)))
    prediction <- model %>% predict_on_batch(input_batch)
    test_data[predict_idx, ycol] <- prediction
  }

  test_data[(lookback+1):(lookback+horizon), ycol]
}

preds <- predict_forecast(model, test_set, ycol, lookback, horizon)

targets <- goal_predictions[(lookback+1):(lookback+horizon)]

pred_df <- data.frame(x = 1:horizon, y = targets, y_hat = preds)

et le tour est joué:

entrez la description de l'image ici

Pas mal.

kostas
la source