2016-10-21 12 views
0

LSTM recurrent neural networkを作成するのにKerasを使用しています。私のコードはうまくいっていますが、深刻なリファクタリングを行うことができます。私は時系列の値を予測していますが、予測したいウィンドウサイズによっては、そのウィンドウサイズにあまりにも固有のように見えるコードを書くことになります。つまり、さまざまなサイズのものを用意するのは難しいです。動的変数のためにPythonでリストを効率的に作成

私は電車の中に私のデータセットを分割&テストを設定します

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

データセットの長さ:列車の長さ1826:1223、テストの長さ: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形状:(1208、10)、trainY形状:(1208、5)

私は、変数trainYに保存されている5つのその後、先にタイムステップ私の予測を、予測したい場合は、かかりますフォーム[[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] 

enter image description here

私は、これらの値を取得したい場合私は10のタイムステップを言うために、予測窓の外を拡張したい場合に戻って論理的な順序、すなわち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) 

を使用しています私の問題が発生します。次に、私は手動で次のように上記のコードを拡張します。

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) 

これは動作しますが、それは恐ろしく非効率です。どのようにしてこれらのステップを最もリファクタリングして、コードをより広い範囲の予測ウィンドウに順応させることができますか?また、私の質問のタイトルはいくらか改善されているので、編集してください!

+1

コードサンプルの最初の部分では、正方形の2Dリストの主対角線の上にある各対角線の平均をとっているようです。しかし、あなたのループが何をしようとしているのか分かりません。 'len(output)'は常に 'predict_steps'と等しくないのですか? 'i'が' 0'以外であれば、ループ内の最初の行は 'IndexError'を送出しませんか? –

+0

データセットに応じて、出力は実際には任意の長さにすることはできません。 't + 6、...、t + 500'から行くかもしれませんが、出力されたものは' predict_steps'に等しい長さのウィンドウで予測されます。それは理にかなっていますか?あるいは、私が意味することの例を使って質問を更新しますか? –

+0

しかし、 'output'は依然として2Dリストの形の正方形の対称行列です、そうですか?たとえば、 'predict_steps'が' '3' '、' 'len(output)' 'が' '5 ''のような例を表示できますか? '出力 'はどのように見えるのですか? –

答えて

1

(注:私はあなたのニューラルネットワークの問題について何も知らない、私はちょうどあなたの符号化/配列トラバーサルの問題に対処しています)ループで行うことができます行列の対角線を取る

- あなただけに持っていますループのパラメータを適切な次元に調整します。次のコードは、純粋な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) 

なお:

  • 私は特にcreate_dataset機能で、あなたの配列インデックスを誤解している場合ので、私を修正してください、Pythonは代わりにnumpyの配列を示しています使用。
  • わかりやすくするために、元のデータセットを分割してトレーニングとテストのデータセットに分割した部分はスキップしました。

メインコードはantidiagonals機能です。 MxN行列の各行に対して、その行の最初の要素から始まる立上り対角が生成されます。最初のループは最初のN対角線を生成します。これはすべて長さが異なります。 2番目のループは次のM-Nの対角線を生成します。これらの対角線はすべてNです。上のコードを実行すると、配列Yの配列とその対角線の出力を調べることができます。

これは、output_plotに追加したい正しい一連のデータであると仮定して、numpy配列で動作するように関数を変更し、各対角の平均をとるだけです。その後、多くのコードを複製せずに予測ウィンドウを調整することができます。

これがあなたの目的と一致するかどうかを教えてください。

+0

それはうまく動作します、ありがとう。何らかの理由で私がこのように実装したとき、返される数値の精度が少し失われました。これは 'yield np.mean([範囲[i] k + 1)]、dtype = np.float64) 'である。 –

関連する問題