测试值后的Keras预测

时间:2019-03-27 15:40:03

标签: python tensorflow keras

我目前正在尝试构建神经元网络以能够预测时间序列,但是问题是,是否可以预测比测试数据集更多的预测。我的意思是,例如,我有一个大约3000个值的数据集,其中90%用于训练,而10%用于测试。然后,当我将预测值与实际测试值进行比较时,它对应,但是例如可以要求程序预测下一个500个值(即从3001到3500)吗?

这是我使用的代码的摘要。

import csv
import numpy as np
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import matplotlib.pyplot as plt
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM, GRU
from keras.models import Sequential
from keras import optimizers
from sklearn.svm import SVR
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import learning_curve
from sklearn.kernel_ridge import KernelRidge
import time
from sklearn.preprocessing import MinMaxScaler
sc = MinMaxScaler(feature_range = (-1, 1))


def load_data(datasetname, column, seq_len, normalise_window):
    # A support function to help prepare datasets for an RNN/LSTM/GRU
    data = datasetname.loc[:,column]

    sequence_length = seq_len + 1
    result = []
    for index in range(len(data) - sequence_length):
        result.append(data[index: index + sequence_length])

    result = np.array(result)
    result.reshape(-1,1)
    training_set_scaled = sc.fit_transform(result)

    print (result)
    #Last 10% is used for validation test, first 90% for training
    row = round(0.9 * training_set_scaled.shape[0])
    train = training_set_scaled[:int(row), :]
    #np.random.shuffle(train)
    x_train = train[:, :-1]
    y_train = train[:, -1]
    X_test = training_set_scaled[int(row):, :-1]
    y_test = training_set_scaled[int(row):, -1]
    print ("shape train", x_train)
    print ("shape train", X_test)
    x_train = np.reshape(x_train, (x_train.shape[0], x_train.shape[1], 1))
    X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))  

    return [x_train, X_test, y_train, y_test]


def build_model():
    model = Sequential()
    layers = {'input': 100, 'hidden1': 150, 'hidden2': 256, 'hidden3': 100, 'output': 10}

    model.add(LSTM(
            50, 
            return_sequences=True, 

            input_shape=(200,1)
            ))
    model.add(Dropout(0.2))

    model.add(LSTM(
            layers['hidden2'],
            return_sequences=True,
           ))
    model.add(Dropout(0.2))

    model.add(LSTM(
            layers['hidden3'],
            return_sequences=False,
            ))
    model.add(Dropout(0.2))

    model.add(Activation("linear"))

    model.add(Dense(
            output_dim=layers['output']))


    start = time.time()
    model.compile(loss="mean_squared_error", optimizer="adam")
    print ("Compilation Time : ", time.time() - start)
    return model

dataset = pd.read_csv(
    'data.csv')
X_train, X_test, y_train, y_test = load_data(dataset, 'mean anomaly', 200, False)
model = build_model()
print ("train",X_train)
print ("test",X_test)

model.fit(X_train, y_train, batch_size=256, epochs=1,  validation_split=0.05)
predictions =  model.predict(X_test)
predictions = np.reshape(predictions, (predictions.size,))
plt.figure(1)
plt.subplot(311)
plt.title("Actual Test Signal w/Anomalies & noise")
plt.plot(y_test)
plt.subplot(312)
plt.title("predicted signal")
plt.plot(predictions, 'g')
plt.subplot(313)
plt.title("training signal")
plt.plot(y_train, 'b')
plt.plot(y_test, 'y')
plt.legend(['train', 'test'])
plt.show()

我已经读到我应该增加密集层的输出暗淡以获得大于1的预测值,还是在加载数据函数中增加窗口的大小?

这是结果,黄色图应该在蓝色图之后,它代表了我输入的测试数据,第一个图是此数据的缩放,第二个图是预测。 result

1 个答案:

答案 0 :(得分:0)

如果您要基于时间 t 预测数据在 t + x 处的意向输出值,则需要馈入网络的数据应该已经具有这种格式。

时间序列数据格式:

如果您有3000个数据点,并且想要预测下一个“虚拟” 500点的输出值,则应将输出值偏移此数量。例如:

在数据集中,第500个数据点对应于第500个输出值。如果要预测“未来”值,则第500个数据点应具有第1000个输出值。您可以使用shift函数在熊猫中执行此操作。请注意,这样做将失去最后的500个数据点,因为它们将不再具有输出值。

然后,当您对数据点xi进行预测时,将得到输出值yi + 500。在machinelearningmastery

之类的网站上,您应该找到一些有关时间序列预测的基本指南。

用于模型评估的好方法:

如果您想更好地评估模型的质量,请首先找到一些适合您问题的指标,然后尝试增加测试集的适用性。虽然图形是可视化结果的好方法,但它们可能具有欺骗性,请尝试将它们与一些指标结合起来! (请谨慎对待均方误差,它会为您提供一个偏见的分数,其值的范围为[-1; 1],因为此范围内的误差平方始终小于实际误差,请尝试使用均值绝对误差)

缩放数据时数据泄漏:

虽然缩放数据通常是一件好事,但您需要格外小心。您承诺了一种称为数据泄漏的事情。在拆分为训练集和测试集之前,您对整个数据集使用了缩放比例。进一步了解此data leak

更新

我想我误解了你的问题。

如果您想“预测的不仅仅是测试数据集”,您将需要一些看不见的/新的数据来进行更多的预测。测试集仅用于评估学习阶段的表现。

现在,如果您只想对下一步做进一步的预测(由于更改数据集的方式,这将使您不能“仅对测试数据集进行更进一步的预测”,请参见下面): 您制作的模型只能预测下一步。

在您的示例中,您将输入长度为'seq_len'的算法系列,并在这些系列结束后立即为它们提供输出值。如果您想让算法学会对未来进行更多的预测,则y_train必须在未来的相应时间具有价值,例如:

x = [0,1,2,3,4,5,6,7,8,9,10,...]
seq_len = 5
step_to_predict = 5

所以要预测不是未来的一步而是五步,您的系列将必须像这样:

x_serie_1 = [0,1,2,3,4]
y_serie_1 = [9]
x_serie_2 = [1,2,3,4,5]
y_serie_2 = [10]

这是一种让您的模型学习如何对未来进行预测的方法,而不仅仅是下一步。