我正在使用 Keras建立一个LSTM recurrent neural network .我的代码运行良好,但可以进行认真的重构。我正在预测时间序列值,并且根据我想要预测的窗口大小,我最终编写的代码似乎过于具体到该窗口大小,即很难满足许多不同的大小。
我将我的数据集分成训练集和测试集
print "Dataset length: %d" % len(dataset)
train_size = int(len(dataset) * 0.67)
test_size = len(dataset) - train_size
train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:]
print "Train length: %d, Test length: %d" % (len(train), len(test))
Dataset length: 1826 Train length: 1223, Test length: 603
然后对于 train
和 test
我需要创建一个作为输入的 X
和一个 Y
这是输出(我试图预测的)
def create_dataset(dataset, look_back=1, predict_steps=1):
dataX, dataY = [], []
for i in range(dataset.shape[0] - look_back - predict_steps):
dataX.append(dataset[i:(i + look_back), 0])
dataY.append(dataset[i + look_back:i + look_back + predict_steps, 0])
return np.array(dataX), np.array(dataY)
look_back = 10
predict_steps = 5
input_dim = look_back + 1
trainX, trainY = create_dataset(train, look_back=look_back, predict_steps=predict_steps)
testX, testY = create_dataset(test, look_back=look_back, predict_steps=predict_steps)
print "trainX shape: %s, trainY shape: %s" % (trainX.shape, trainY.shape,)
trainX shape: (1208, 10), trainY shape: (1208, 5)
如果我想提前预测 5 个时间步,那么我的预测(存储在变量 trainY
中)将采用 [[t+6, t+7, t+8, t +9, t+10], [t+7, t+8, t+9, t+10, t+11]]
, 即
prediction 1 [t+6, t+7, t+8, t+9, t+10]
prediction 2 [t+7, t+8, t+9, t+10, t+11]
prediction 3 [t+8, t+9, t+10, t+11, t+12]
prediction 4 [t+9, t+10, t+11, t+12, t+13]
prediction 5 [t+10, t+11, t+12, t+13, t+14]
现在,如果我想按逻辑顺序取回这些值,即 t+6, t+7, t+8,...,t+14
我正在使用这段代码
output = trainY
output_plot = np.array([])
output_plot = np.append(output_plot, output[0][0])
output_plot = np.append(output_plot, np.mean([output[0][1], output[1][0]]))
output_plot = np.append(output_plot, np.mean([output[0][2], output[1][1], output[2][0]]))
output_plot = np.append(output_plot, np.mean([output[0][3], output[1][2], output[2][1], output[3][0]]))
for i in range (len(output) - predict_steps + 1):
tmp = np.mean([output[i][4], output[i+1][3], output[i+2][2], output[i+3][1], output[i+4][0]])
output_plot = np.append(output_plot, tmp)
当我想将预测窗口扩展到 10 个时间步时,我的问题就出现了。然后我手动扩展前面的代码如下
output = trainY
output_plot = np.array([])
output_plot = np.append(output_plot, output[0][0])
output_plot = np.append(output_plot, np.mean([output[0][1], output[1][0]]))
output_plot = np.append(output_plot, np.mean([output[0][2], output[1][1], output[2][0]]))
output_plot = np.append(output_plot, np.mean([output[0][3], output[1][2], output[2][1], output[3][0]]))
output_plot = np.append(output_plot, np.mean([output[0][4], output[1][3], output[2][2], output[3][1], output[4][0]]))
output_plot = np.append(output_plot, np.mean([output[0][5], output[1][4], output[2][3], output[3][2], output[4][1], output[5][0]]))
output_plot = np.append(output_plot, np.mean([output[0][6], output[1][5], output[2][4], output[3][3], output[4][2], output[5][1], output[6][0]]))
output_plot = np.append(output_plot, np.mean([output[0][7], output[1][6], output[2][5], output[3][4], output[4][3], output[5][2], output[6][1], output[7][0]]))
output_plot = np.append(output_plot, np.mean([output[0][8], output[1][7], output[2][6], output[3][5], output[4][4], output[5][3], output[6][2], output[7][1], output[8][0]]))
for i in range (len(output) - predict_steps + 1):
tmp = np.mean([output[i][9], output[i+1][8], output[i+2][7], output[i+3][6], output[i+4][5], output[i+5][4], output[i+6][3], output[i+7][2], output[i+8][1], output[i+9][0]])
output_plot = np.append(output_plot, tmp)
虽然这行得通,但效率极低。我怎样才能最好地重构这些步骤以使代码更适合更广泛的预测窗口?另外,我的问题标题可以做一些改进,所以请编辑掉!
最佳答案
(注意:我对你的神经网络问题一无所知,我只是在解决你的编码/数组遍历问题)
取矩阵的对角线可以用循环来完成——你只需要将循环的参数调整到合适的维度。以下代码是纯 Python 中的简化模型,根据我对数据形状的了解,您将尝试完成这些工作。
from pprint import pprint
def create_mock_data(n):
return [[100 + i] for i in range(n)]
def create_dataset(dataset, look_back = 1, predict_steps = 1):
X, Y = [], []
for i in range(len(dataset) - look_back - predict_steps):
X.append([row[0] for row in dataset[i : i+look_back]])
Y.append([row[0] for row in dataset[i+look_back : i+look_back+predict_steps]])
return X, Y
def antidiagonals(a):
m, n = len(a), len(a[0])
for k in range(0, n):
yield [a[k-i][i] for i in range(k + 1)]
for k in range(n, m):
yield [a[k-i][i] for i in range(n)]
def pp(label, x):
print('---', label, '---')
pprint(x, width = 108)
print()
def test(n, look_back, predict_steps):
print('=' * 72)
print('n =', n)
print('look_back =', look_back)
print('predict_steps =', predict_steps)
print()
dataset = create_mock_data(n)
pp('dataset', dataset)
X, Y = create_dataset(dataset, look_back, predict_steps)
pp('X', X)
pp('Y', Y)
diagonals = list(antidiagonals(Y))
pp('diagonals of Y', diagonals)
print()
test(50, look_back = 10, predict_steps = 5)
test(50, look_back = 10, predict_steps = 10)
# test(50, look_back = 15, predict_steps = 10)
注意:
- 我使用 Python 列表而不是 numpy 数组,所以如果我误解了您的数组索引,尤其是在
create_dataset
函数中,请纠正我。 - 为简单起见,我跳过了将原始数据集拆分为训练和测试数据集的部分。
感兴趣的主要代码在antidiagonals
函数中。对于 MxN
矩阵的每一行,它生成从该行的第一个元素开始的上升对角线。第一个循环产生第一个 N
对角线,它们都有不同的长度。第二个循环产生下一个 M-N
对角线,所有对角线都有 N
元素。当您运行上面的代码时,您可以检查模拟 Y
数组及其对角线的输出。
假设这些是您希望添加到 output_plot
的正确数据系列,您只需修改函数以对 numpy 数组进行操作并取每条对角线的平均值。然后您应该能够调整预测窗口而无需重复太多代码。
让我知道这是否符合您的要求。
关于python - 由于动态变量,在 Python 中高效地创建列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40185061/