回測

預測視窗或禁運導致樣本外結果迅速衰減

  • November 16, 2021

因此,我開始涉足量化金融,並試圖驗證一些模型結果,但很難思考他們告訴我的內容。

這是我的情況:我正在嘗試使用 ML 模型來預測回報,並且正在為我的訓練數據嘗試不同的視窗大小,並且正在記錄我的 n 步樣本外預測。我也在嘗試禁運。

因此,例如,如果我的步長是 2,我的禁運是 5,並且我的視窗大小是 252,那麼X是 252 次訓練觀察,我將對接下來的 2 次觀察進行預測(由於步長),並且會有一個差距訓練數據和样本外預測之間的 5 個觀察值。

這是我在 python 中使用的公式的縮寫版本:

def walk_forward_validation(mod, 
                           X,
                           y,
                           window         = 504, 
                           lookahead      = 1, 
                           step           = 1,
                           embargo        = 0):
   
   """
   Parameters:
     -- mod:  model you are going to use for predictions
     -- X  :  input data
     -- y  :  target variable
     -- window: size of training window you will use
     -- lookahead: how many steps ahead will your model predict
     -- step: how much additional data your model will move ahead after a round of fitting
     -- embargo: how many samples to skip when making out of sample predictions
     """
   
   start_idx   = 0
   stop_idx    = window
   pred_start  = window + embargo
   pred_stop   = pred_start + lookahead
   max_idx     = X.shape[0] - 1
   i = 0
   
   # will store results in these, return as a df at the end
   results = {
       'preds':     [],
       'dates':     [],
       'true_vals': []
   }

   fitting = True
   
   # start the training loop
   while fitting:
       
       # define the training window, fit the model
       X_temp = X.iloc[start_idx:stop_idx]
       y_temp = y.iloc[start_idx:stop_idx]
       
       
       mod.fit(X_temp, y_temp)
       
       # make future predictions, store the results
       X_pred               = X.iloc[pred_start:pred_stop]
       
       # means we've gone past the cutoff point
       if X_pred.shape[0] == 0:
           break
       
       results['preds']     += mod.predict(X_pred).tolist()
       dates                = X_pred.index.values.tolist()
       results['dates']     += dates
       results['true_vals'] += y.iloc[pred_start:pred_stop].values.tolist()
       
       # update the new cutoffs
       start_idx   += step
       stop_idx    += step
       pred_start  += step
       pred_stop   += step
       i += 1
       
       # check to see if we've hit a new cutoff point            
       if stop_idx + lookahead > max_idx:
           offset = (lookahead + stop_idx) - (max_idx - 1)
           lookahead -= offset
   
   results = pd.DataFrame(results)
   results['dates'] = pd.to_datetime(results['dates'])
   
   return pd.DataFrame(results)

我所做的是查看不同視窗大小、步長和禁運大小的模型結果。

這是一個總結結果的表格:

在此處輸入圖像描述

顯而易見的是,隨著禁運或步驟的擴大,結果會迅速惡化。我對此的看法是,我的模型可能對我的數據中一些非常臨時的模式非常敏感,這些模式很快就會消失,但是我很難弄清楚以下問題:

  • 我應該如何選擇要通過哪一組結果?一組驗證參數比另一組更穩定,是否有特殊原因?我了解靜態數據,並閱讀了有關禁運的機器學習進展,但我不清楚我是否應該自動選擇給我帶來最差結果的驗證參數。假設我的數據沒有任何前瞻性偏差。
  • 如果我定期修改我的模型以匹配我的樣本外預測的時間跨度,那麼使用更樂觀的驗證參數是否可以?

例如,假設我正在擬合每小時數據,禁運為 0,步長為 1。我的結果的 R2 值為 0.5。即使這些結果本質上是暫時的,如果我每小時都在重新調整我的模型,我不是在利用空間相關性而不是被它們愚弄嗎?

我知道結果會迅速衰減,但如果我無法根據新數據不斷地重新訓練模型,我就會停止它,因為我知道如果我不這樣做,災難就會迫在眉睫。

最後,我處理這個問題的方式有什麼根本錯誤嗎?

謝謝。

無論如何,很抱歉這篇長文,只是想讓我在這些問題上處於正確的位置。

謝謝!

這是一個複雜的問題。讓我重新表述它的主要組成部分,試圖給出一個通用的答案:

  1. 如果一段關係是不穩定的,並且我通過模型來捕捉它,我預計“過時”模型的解釋力會比新模型最差
  2. 一旦我交叉驗證了一個模型,我可以盲目選擇“最佳超參數集”嗎?

從第二個開始:

  • 在機器學習中,您必須考慮 3 組而不是 2 組
    • 學習集
    • 驗證集
    • 測試集
  • 您應該在驗證集(您將其命名為 embargo)上選擇超參數並在測試集上對其進行測試。
  • 如果測試集上的結果不好:**你無能為力,**否則你將面臨過度擬合。

在您的範例中,您以某種方式建議跳過最後一步,這可能是您生氣的原因之一。

現在看看非平穩性方面:這是真的,但是如果模型的效率衰減得很快

  • 你可能會面臨一個資訊洩露問題:你真的確定你沒有將未來的觀察與過去的觀察混為一談嗎?
  • 您可能應該了解會發生什麼:您能否為自己記錄究竟意味著“我的模型可能對我的數據中的一些非常臨時的模式高度敏感,這些模式很快就會消失”並確信這是有意義的事情?

一旦解決了這兩點,那麼您的推理就沒有根本性的錯誤。

引用自:https://quant.stackexchange.com/questions/68771