Sangat mungkin untuk menggunakan CNN untuk membuat prediksi deret waktu baik itu regresi atau klasifikasi. CNN pandai menemukan pola lokal dan pada kenyataannya CNN bekerja dengan asumsi bahwa pola lokal relevan di mana-mana. Konvolusi juga merupakan operasi yang terkenal dalam rangkaian waktu dan pemrosesan sinyal. Keuntungan lain dari RNN adalah bahwa mereka dapat sangat cepat untuk dihitung karena mereka dapat diparalelkan berlawanan dengan sifat sekuensial RNN.
Dalam kode di bawah ini saya akan menunjukkan studi kasus di mana dimungkinkan untuk memprediksi permintaan listrik di R menggunakan keras. Perhatikan bahwa ini bukan masalah klasifikasi (saya tidak punya contoh praktis) tetapi tidak sulit untuk memodifikasi kode untuk menangani masalah klasifikasi (gunakan output softmax alih-alih output linier dan kerugian lintas entropi).
Dataset tersedia di perpustakaan fpp2:
library(fpp2)
library(keras)
data("elecdemand")
elec <- as.data.frame(elecdemand)
dm <- as.matrix(elec[, c("WorkDay", "Temperature", "Demand")])
Selanjutnya kita membuat generator data. Ini digunakan untuk membuat kumpulan data pelatihan dan validasi untuk digunakan selama proses pelatihan. Perhatikan bahwa kode ini adalah versi sederhana dari generator data yang ditemukan dalam buku "Deep Learning with R" (dan versi video "Deep Learning with R in Motion") dari publikasi yang dikelola.
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)
})
}
Selanjutnya kita menentukan beberapa parameter untuk diteruskan ke generator data kami (kami membuat dua generator satu untuk pelatihan dan satu untuk validasi).
lookback <- 72
lookahead <- 1
batch_size <- 168
ycol <- 3
Parameter lookback adalah seberapa jauh di masa lalu kita ingin melihat dan melihat sejauh mana di masa depan yang ingin kita prediksi.
Selanjutnya kita membagi dataset kami dan membuat dua generator:
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
)
Selanjutnya kita membuat jaringan saraf dengan lapisan convolutional dan melatih model:
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
)
Akhirnya, kita dapat membuat beberapa kode untuk memprediksi urutan 24 titik data menggunakan prosedur sederhana, dijelaskan dalam komentar 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)
dan voila:
Lumayan.