使用ggplot绘制真实数据时间系列的预测值

时间:2018-01-23 10:09:01

标签: r ggplot2 keras

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

这是我的代码:

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)。最后,我想制作一个如下图: lstm graph 如您所见,我想在真实数据值上添加预测值。 原始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()

2 个答案:

答案 0 :(得分:1)

不确定您预测的形状&#34;对象..但你可以试试这个:

double m11 = 0.00000001, // 1E-08
    m12 = 0,
    m21 = 0,
    m22 = 0.0000001; // 1E-07

var mat = new Matrix(m11, m12, m21, m22, 0, 0);

var det = mat.Determinant; // det = 9.9999999999999988E-16 <==> m11*m22-m12*m21 = 1E-08 * 1E-07 = 1E-15

if (mat.HasInverse) // false
    mat.Invert(); // KO : System.InvalidOperationException: 'Transform is not invertible.'

答案 1 :(得分:0)

我找到了解决方案。

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()