這兩種寫法的差異在於它們如何構建 new_row
並更新 last_known_data
。這可能會對結果產生影響,具體差異如下:
方法 1:
new_row = np.append(future_price_scaled, [[0, 0, 0]], axis=1)[:, :-1]
last_known_data = np.append(last_known_data, new_row, axis=0)[1:]
這段代碼的操作是:
- 將
future_price_scaled
的值與一個包含零的數組[[0, 0, 0]]
進行拼接,然後刪除最後一列 ([:, :-1]
)。 - 更新
last_known_data
,將新的new_row
添加到末尾,並移除最早的一行。
問題在於這樣的操作會使得 new_row
包含許多零值,這些零值可能對後續的預測有不良影響,因為LSTM模型將會依賴這些帶有零值的數據進行預測。
方法 2:
new_row = np.append(last_known_data[-1, 1:], future_price_scaled[0]).reshape(1, -1)
last_known_data = np.append(last_known_data, new_row, axis=0)[1:]
這段代碼的操作是:
- 將
last_known_data
的最後一行的所有列(除了第一列)與future_price_scaled[0]
拼接起來,並重塑為1
行。 - 更新
last_known_data
,將新的new_row
添加到末尾,並移除最早的一行。
這種方法保留了原始特徵數據的結構,只是將最新的預測價格作為最後一列,這樣可以更真實地反映數據的變化趨勢。
影響結果的因素:
- 數據完整性:方法 2 保持了數據的連續性,這有助於LSTM模型更好地捕捉數據中的模式。
- 零值影響:方法 1 引入了許多零值,這可能會對模型的預測性能產生負面影響,因為這些零值不代表實際的數據變化。
因此,方法 2 通常會提供更準確和穩定的預測結果。
24cba306-ebaa-4877-9c72-9e9ca642b908
24cba306-ebaa-4877-9c72-9e9ca642b908
我們來看這個具體的數據範例,以及這兩種方法的具體實施過程。假設我們已經完成了對數據的標準化和前處理,並且得到了 last_known_data
和 future_price_scaled
。
方法 1:
new_row = np.append(future_price_scaled, [[0, 0, 0]], axis=1)[:, :-1]
last_known_data = np.append(last_known_data, new_row, axis=0)[1:]
這個方法將 future_price_scaled
拼接上一個包含零的數組,然後刪除最後一列,結果如下:
假設 future_price_scaled
是 [[0.8]]
,原始的 last_known_data
是:
[[0.5, 0.4, 0.3], # 第一行
[0.6, 0.5, 0.4], # 第二行
[0.7, 0.6, 0.5]] # 第三行 (最新的一行)
這時 new_row
會變成:
np.append([[0.8]], [[0, 0, 0]], axis=1)[:, :-1] => [[0.8, 0, 0]]
然後,更新 last_known_data
:
last_known_data = np.append(last_known_data, new_row, axis=0)[1:]
結果會是:
[[0.6, 0.5, 0.4], # 原第二行
[0.7, 0.6, 0.5], # 原第三行
[0.8, 0, 0]] # 新的一行
方法 2:
new_row = np.append(last_known_data[-1, 1:], future_price_scaled[0]).reshape(1, -1)
last_known_data = np.append(last_known_data, new_row, axis=0)[1:]
這個方法將 last_known_data
的最後一行的所有列(除了第一列)與 future_price_scaled
拼接起來,結果如下:
假設 future_price_scaled
還是 [[0.8]]
,原始的 last_known_data
是:
[[0.5, 0.4, 0.3], # 第一行
[0.6, 0.5, 0.4], # 第二行
[0.7, 0.6, 0.5]] # 第三行 (最新的一行)
這時 new_row
會變成:
np.append([0.6, 0.5], 0.8).reshape(1, -1) => [[0.6, 0.5, 0.8]]
然後,更新 last_known_data
:
last_known_data = np.append(last_known_data, new_row, axis=0)[1:]
結果會是:
[[0.6, 0.5, 0.4], # 原第二行
[0.7, 0.6, 0.5], # 原第三行
[0.6, 0.5, 0.8]] # 新的一行
具體差異:
- 方法 1 在新增的數據行中包含大量零值,這些零值會影響後續預測的準確性。特別是對於LSTM模型,這些零值可能會被解釋為數據模式的一部分,從而影響模型的學習效果和預測結果。
- 方法 2 保持了數據的連續性,只將新的預測值作為最後一列,這更符合實際情況,因為新的預測值應該基於之前的數據變化趨勢。
在時間序列預測中,特徵和預測價格放在一起的原因是為了讓模型可以利用之前的預測值作為下一步預測的輸入。這種方法允許模型捕捉到連續時間步的模式,包括任何自回歸特性(即過去的輸出影響未來的輸出)。
以下是具體原因和方法:
1. 為何要把預測的價格放入 X_scaled
中?
當我們預測未來的價格時,我們希望模型能夠利用之前的預測結果來進行下一步的預測。這是因為未來的價格可能受到之前價格變動的影響。通過將預測的價格放入 X_scaled
中,我們可以模擬這種影響,並使模型能夠在多個時間步上進行連續預測。
2. 特徵和預測價格放在一起的目的
將特徵和預測價格放在一起的主要目的是保持數據的連續性。這樣可以讓模型在每一步都使用最新的預測結果作為下一步的輸入。這樣做可以捕捉到時間序列中的趨勢和季節性變化。
具體方法
以下是具體實現方法的示例:
初始化
last_known_data
:last_known_data = np.array([ [0.5, 0.4, 0.3], [0.6, 0.5, 0.4], [0.7, 0.6, 0.5] ])
使用模型進行預測並更新
last_known_data
:future_price_scaled = 0.8 # 假設模型預測的價格是 0.8 # 方法 1: new_row = np.append(future_price_scaled, [[0, 0, 0]], axis=1)[:, :-1] last_known_data = np.append(last_known_data, new_row, axis=0)[1:] # 方法 2: new_row = np.append(last_known_data[-1, 1:], future_price_scaled).reshape(1, -1) last_known_data = np.append(last_known_data, new_row, axis=0)[1:]
在方法 2 中,我們保留了原始特徵的連續性,並在最後一列添加預測的價格。
示例解釋
假設 last_known_data
最初是:
last_known_data = np.array([
[0.5, 0.4, 0.3],
[0.6, 0.5, 0.4],
[0.7, 0.6, 0.5]
])
模型預測的下一個價格是 0.8
,我們將這個預測結果添加到 last_known_data
中,並保留原始特徵的連續性。更新後的 last_known_data
將變成:
last_known_data = np.array([
[0.6, 0.5, 0.4],
[0.7, 0.6, 0.5],
[0.6, 0.5, 0.8] # 0.8 是預測的價格,保留了原始特徵的連續性
])
這樣,我們可以確保模型在每一步都使用最新的預測結果,並捕捉到時間序列中的模式和趨勢。這種方法特別適用於具有自回歸特性的時間序列數據,其中過去的值會影響未來的預測。