【问题标题】:Keras Prediction after test values测试值后的 Keras 预测
【发布时间】:2019-03-27 15:40:03
【问题描述】:

我目前正在尝试构建能够预测时间序列的神经元网络,但问题是,是否有可能比仅测试数据集进行更进一步的预测。我的意思是,在我的示例中,我有一个包含大约 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 个预测值,或者在加载数据函数中增加我的窗口大小?

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

【问题讨论】:

    标签: python tensorflow keras


    【解决方案1】:

    如果你想根据时间 t 的数据预测你的系列在 t+x 的输出值,那么你需要馈送到网络的数据应该已经有这种格式。

    时间序列数据格式化:

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

    在您的数据集中,您的第 500 个数据点对应于第 500 个输出值。如果您想预测“未来”值,那么第 500 个数据点应该具有第 1000 个输出值。您可以使用 shift 函数在 pandas 中执行此操作。请注意,这样做会丢失最后 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]
    

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

    【讨论】:

    • 我尝试这样做:forecast = shift(X_test, -500, cval=np.NaN) 但输出是一个包含 NaN 值的数组...
    • shift的用法通常是这样的:your_dataframe['column_to_shift'] = your_dataframe['column_to_shift'].shift(-500)。然后,您将不得不删除最后一个值行,因为它们不再具有任何值:your_dataframe = your_dataframe[:len(your_dataframe)-500]。顺便说一句,每个数据点之间的时间总是相同的吗? (一小时,一分钟等......)
    • 我现在只有一列,我想做的更清楚,我希望绿色图是假设未来的 500 个值,并显示误差范围。所以最终测试数据集只有 300 个值,但预测会达到 800。
    • 我使用以下方法成功移动了数组:np.vstack((np.zeros((2,)+X_test.shape[1:], dtype=X_test.dtype), X_test)) 但我有一个大小为 293 的数组,移位后我仍然有相同的大小,这意味着我丢失了值,我认为我应该得到一个大小为 793 (293 + 500) 的数组,对吗?然后我会对这个更大的数组做出预测
    • 不是真的,您是否建议当我从数据集中准备滑动窗口时,我应该更改序列长度? (即 sequence_length = seq_len + nbelementsinfuturetopredict ?)
    猜你喜欢
    • 2020-09-03
    • 2020-10-31
    • 1970-01-01
    • 2017-01-01
    • 2017-05-29
    • 2018-04-15
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多