【问题标题】:Plot predicted values on true data time serie using ggplot使用 ggplot 在真实数据时间序列上绘制预测值
【发布时间】:2018-01-23 10:09:01
【问题描述】:

我正在尝试在 R (https://github.com/llSourcell/How-to-Predict-Stock-Prices-Easily-Demo) 中复制 Siraj 预测股票价格的代码。

这是我的代码:

url <- "https://raw.githubusercontent.com/llSourcell/How-to-Predict-Stock-Prices-Easily-Demo/master/sp500.csv"
sp500 <- read.csv(url, header = FALSE, stringsAsFactors = FALSE)
colnames(sp500) <- "closingPrice"

# choose sequence length
seq_length <- 50
sequence_length <- seq_length + 1
result <- list()
for (i in 1:(nrow(sp500) - seq_length)){
  result[[i]] <- sp500[i : (i + seq_length),1]
}

# normalised data
normalised_data <- list()
for (i in 1:length(result)){
  normalised_window <- ((result[[i]] / result[[i]][[1]]) - 1)
  normalised_data[[i]] <- normalised_window
}
result <- normalised_data

# test <- do.call(rbind, result)
# define train and test datasets
row <- round(0.9 * length(result))
train <- result[1:as.integer(row)]
# train <- sample(train)
x_train <- lapply(train, '[', -length(train[[1]]))
y_train <- lapply(train, '[', length(train[[1]]))
y_train <- unlist(y_train)
test = result[(as.integer(row)+1):length(result)]
x_test <- lapply(test, '[', -length(test[[1]]))
y_test <- lapply(test, '[', length(test[[1]]))

x_train <- array(as.numeric(unlist(x_train)), dim = c(3709, 50, 1))
x_test <- array(as.numeric(unlist(x_test)), dim = c(412, 50, 1))
# x_train <- as.matrix(x_train, dim = c(3709, 51))
# x_test <- as.matrix(x_test, dim = c(412, 51))

class(x_train)

#########################
# Step 2: Build a model #
#########################

library(keras)

model <- keras_model_sequential()
model %>% layer_lstm(units = 50L, return_sequences = TRUE, input_shape = list(NULL, 1)) %>%
  layer_dropout(0.2) %>%
  layer_lstm(units = 50L, return_sequences = FALSE) %>%
  layer_dropout(0.2) %>%
  layer_dense(1L) %>%
  layer_activation('linear')
summary(model)

model %>% compile(
  optimizer = 'rmsprop',
  loss = 'mse'
)

###########################
# Step 2: Train the model #
###########################

model %>% fit(x_train, y_train, epochs=1, batch_size=512, validation_split = 0.05)


################################
# Step 2: Plot the predictions #
################################

predict_sequences_multiple <- function(model, data, window_size, prediction_len){
  #Predict sequence of 50 steps before shifting prediction run forward by 50 steps
  prediction_seqs = list()
  for (i in 1:as.integer(nrow(data)/prediction_len)){
    curr_frame = array(data[i*prediction_len,,], dim = c(prediction_len,1,1))
    predicted = list()
    for (j in 1:prediction_len){
      predicted[[j]] <- model$predict(curr_frame)[1]
      curr_frame <- curr_frame[2:nrow(curr_frame)]
      curr_frame <- array(c(curr_frame, predicted[[j]]), dim = c(prediction_len,1,1))
    }
    prediction_seqs[[i]] <- unlist(as.numeric(predicted))
  }
  return(prediction_seqs)
}
predictions <- predict_sequences_multiple(model, x_test, 50, 50)

您可以只运行代码来获取预测值(您需要安装 keras)。最后,我想制作一个如下所示的图表: 如您所见,我想在真实数据值上添加预测值。 原始 Siraj 在 python 中的代码如下所示:

def plot_results_multiple(predicted_data, true_data, prediction_len):
    fig = plt.figure(facecolor='white')
    ax = fig.add_subplot(111)
    ax.plot(true_data, label='True Data')
    print 'yo'
    #Pad the list of predictions to shift it in the graph to it's correct start
    for i, data in enumerate(predicted_data):
        padding = [None for p in xrange(i * prediction_len)]
        plt.plot(padding + data, label='Prediction')
        plt.legend()
plt.show()

如何使用 ggplot 复制此图? 到目前为止我的代码:

library(tidyr)
library(rowr)
library(ggplot2)

plot_data <- data.frame(y_test = unlist(y_test), stringsAsFactors = FALSE)
plot_data <- cbind.fill(plot_data, predictions, fill = NA)
plot_data <- gather(plot_data, key = "key", value = "value")
plot_data <- plot_data %>% dplyr::group_by(key) %>% dplyr::mutate(n = 1:n())


ggplot(plot_data, aes(x = n, y = value, col = key)) + geom_line()

【问题讨论】:

  • 如果您的问题只是关于如何生成图表,就像我认为的那样,那么如果您删除所有用于生成预测的代码并只发布所需的数据集,那就太好了制作图表。

标签: r ggplot2 keras


【解决方案1】:

不确定你的“预测”对象的形状..但你可以试试这个:

fr <- as.data.frame(unlist(predictions))
plot_data <- data.frame(y_test = unlist(y_test), stringsAsFactors = FALSE)
plot_data <- cbind.fill(plot_data, fr, fill = NA)
plot_data <- gather(plot_data, key = "key", value = "value")
plot_data <- plot_data %>% dplyr::group_by(key) %>% dplyr::mutate(n = 1:n()) %>% ungroup()
plot_data[plot_data$key!="y_test",] <- plot_data %>% filter(key != "y_test") %>% mutate(key = n %/%50)

ggplot(plot_data, aes(x = n, y = value, col = key)) + geom_line()

【讨论】:

    【解决方案2】:

    我找到了解决办法。

    url <- "https://raw.githubusercontent.com/llSourcell/How-to-Predict-Stock-Prices-Easily-Demo/master/sp500.csv"
    sp500 <- read.csv(url, header = FALSE, stringsAsFactors = FALSE)
    colnames(sp500) <- "closingPrice"
    
    # choose sequence length
    seq_length <- 50
    sequence_length <- seq_length + 1
    result <- list()
    for (i in 1:(nrow(sp500) - seq_length)){
      result[[i]] <- sp500[i : (i + seq_length),1]
    }
    
    # normalised data
    normalised_data <- list()
    for (i in 1:length(result)){
      normalised_window <- ((result[[i]] / result[[i]][[1]]) - 1)
      normalised_data[[i]] <- normalised_window
    }
    result <- normalised_data
    
    # test <- do.call(rbind, result)
    # define train and test datasets
    row <- round(0.9 * length(result))
    train <- result[1:as.integer(row)]
    # train <- sample(train)
    x_train <- lapply(train, '[', -length(train[[1]]))
    y_train <- lapply(train, '[', length(train[[1]]))
    y_train <- unlist(y_train)
    test = result[(as.integer(row)+1):length(result)]
    x_test <- lapply(test, '[', -length(test[[1]]))
    y_test <- lapply(test, '[', length(test[[1]]))
    
    # x_train <- array(as.numeric(unlist(x_train)), dim = c(3709, 50, 1))
    # x_test <- array(as.numeric(unlist(x_test)), dim = c(412, 50, 1))
    x_train <- array_reshape(as.numeric(unlist(x_train)), dim = c(3709, 50, 1))
    x_test <- array_reshape(as.numeric(unlist(x_test)), dim = c(412, 50, 1))
    
    
    #########################
    # Step 2: Build a model #
    #########################
    
    library(keras)
    
    model <- keras_model_sequential()
    model %>% layer_lstm(units = 50L, return_sequences = TRUE, input_shape = list(NULL, 1)) %>%
      layer_dropout(0.2) %>%
      layer_lstm(units = 100L, return_sequences = FALSE) %>%
      layer_dropout(0.2) %>%
      layer_dense(1L) %>%
      layer_activation('linear')
    summary(model)
    
    model %>% compile(
      optimizer = 'rmsprop',
      loss = 'mse'
    )
    
    ###########################
    # Step 2: Train the model #
    ###########################
    
    model %>% fit(x_train, y_train, epochs=5, batch_size=512, validation_split = 0.05)
    
    
    ################################
    # Step 2: Plot the predictions #
    ################################
    
    predict_sequences_multiple <- function(model, data, window_size, prediction_len){
      #Predict sequence of 50 steps before shifting prediction run forward by 50 steps
      prediction_seqs = list()
      for (i in 1:as.integer(nrow(data)/prediction_len)){
        curr_frame = array(data[i*prediction_len,,], dim = c(1,prediction_len,1))
        predicted = list()
        for (j in 1:prediction_len){
          predicted[[j]] <- predict_on_batch(model, curr_frame)[1]
          curr_frame <- array_reshape(curr_frame[,2:50,], dim = c(1,49,1))
          curr_frame <- array(c(curr_frame, predicted[[j]]), dim = c(1,prediction_len,1))
        }
        prediction_seqs[[i]] <- unlist(as.numeric(predicted))
      }
      return(prediction_seqs)
    }
    predictions <- predict_sequences_multiple(model, x_test, 50, 50)
    predictions <- data.frame(pred = unlist(predictions), stringsAsFactors = FALSE)
    
    
    library(ggplot2)
    library(tidyr)
    library(rowr)
    library(dplyr)
    library(optmach)
    
    # fr <- as.data.frame(unlist(predictions))
    plot_data <- data.frame(y_test = unlist(y_test), stringsAsFactors = FALSE)
    plot_data <- cbind.fill(plot_data, predictions, fill = NA)
    number_of_predictions <- nrow(plot_data) %/% 50
    cols <- paste0("Prediction ", 1:number_of_predictions)
    help_vector <- c(1, seq(50, number_of_predictions*50, by = 50))
    for (i in 1:number_of_predictions){
      if(i == 1){
        plot_data[,cols[i]] <- NA
        plot_data[help_vector[i]:help_vector[i+1],cols[i]] <- c(plot_data[(help_vector[i]):help_vector[i+1],"pred"])
        }else{
          plot_data[,cols[i]] <- NA
          x <- plot_data[help_vector[i]+1,"pred"] - plot_data[help_vector[i]+1,"y_test"]
          plot_data[(help_vector[i]+1):(help_vector[i+1]),cols[i]] <- c(plot_data[(help_vector[i]+1):help_vector[i+1],"pred"]) - x
        }
      }
    
    plot_data[,"pred"] <- NULL
    plot_data <- gather(plot_data, key = "key", value = "value")
    plot_data <- plot_data %>% dplyr::group_by(key) %>% dplyr::mutate(n = 1:n())
    
    ggplot(plot_data, aes(x = n, y = value, col = key)) + geom_line()
    

    【讨论】:

      猜你喜欢
      • 2018-11-11
      • 2021-11-08
      • 1970-01-01
      • 1970-01-01
      • 2018-09-10
      • 2013-11-24
      • 1970-01-01
      • 2020-07-01
      • 2023-03-11
      相关资源
      最近更新 更多