正常來講是不會一天有兩篇文章的,但是我剛剛突然發現了驚人的事實
以下講的完全是我個人理解,我也只是剛學,所以有錯歡迎糾正
其實也不算驚人的事實,就只是我沒有去想這件事而已
我所採用的預測方法是參考一篇論文,他的目標是用S&P500的所有成分股作為input,features有開高低收加上一些基本面技術面因子,還有分析師rating等
他將2016-2019的data用sklearn裡面的train_test_split這個function來切資料
這個function有幾個參數:
- test_size: float or int, default=None,選擇妳要將資料以多少比例切割
- random_state: int, RandomState instance or None, default=None,有點類似seed,假設你每次切得時候都用同一個random state,會切出一樣的資料
- shuffle: bool, default=True,決定切的時候是否要將資料順序打亂再切
- stratify: array-like, default=None,我的理解是有些資料的label不平衡,例如0、1差距很大,可以用這個確保切出來的Label不會差太多
論文裡面有提到,他以7:3的比例將data切成training和testing,再將testing的資料拿去做回測,大概是250天左右
以比較嚴謹的方式來看,資料應該要切成train、validation和test,training data用來訓練模型,validation data用來驗證訓練後的模型成效如何,再根據成效去調整超參數>調整好後用testing data來測試泛化性
白話來說,training就是給電腦一本題庫並附上答案,要他回去練習,練習好後,用validation data給他考模考,如果考得不好再回去檢討一下哪邊沒學好,而testing就是最後的正式考試,無論考得怎麼樣,考了就是考了
那應該可以猜到會有甚麼問題,就是如果沒有分出validation data的話,你就只能用testing的結果來調參數,但是你難道可以考完學測後跟他說我考得不好,再讓我回去念一下再考嗎?
所以看起來很棒的結果有可能只是你作弊了
我不確定這樣講會不會太重,但就是類似感覺
接著附上他的train_test_split程式碼,可以想一下還有甚麼問題
X_train, X_test, y_train, y_test = train_test_split(features, labels.iloc[:,i], test_size=0.3,random_state=0)
沒錯,他的shuffle=default,也就是True
個股資料大家都知道是時間序列,那這邊的話是很多個股的資料排再一起,看似不是隨機序列,但在每一支股票內仍有極強關聯性,且不同股票之間的相關係數基本上也非0
所以這裡等於是把未來資料的特徵當成訓練集,應該算是典型的資料洩漏,這就像為甚麼做scaling時,test data只能用train的scaling,不能用test自己的
所以我認為這就是為甚麼他可以用FAANG在250日內的資料,去獲得70~100%的報酬率
因為他有通天眼,看得到未來
Maybe我現在一直做不出來也是這個原因,只能禮拜一再去找人談談了,當然我也在想會不會有理論可以證明在資料集長這樣的情況下,shuffle與否並不影響模型的公正性
不過是還沒看到,如果真的如我所想,那我做了兩個月只是在驗證別人的模型是錯的。