最近周圍的小夥伴們都在玩kaggle上進行的IEEE-CIS,做爲常常「地震」的時序題,關於如何選取驗證集的討論天然也很多。究竟如何選擇一個靠譜的線下驗證集?關於這個問題,我也思考過不少,如今將一些看法與你們分享,拋磚引玉。學習
首先,咱們要知道選擇驗證集的意義是什麼。在作表格題時,常常參加比賽的人可能會很是慣性地來套5CV,大力出奇跡,一發LGB,毀天又滅地。若是是時間序列類的,可能會找類似的一天或一段時間做爲驗證,其餘時間段用來訓練等等。不少時候這都是基於直覺或者習慣,並無什麼硬性的道理。但私覺得事情並非那麼簡單。測試
若是用考試來作比方的話,訓練集就像咱們用來學習的有答案的習題集。驗證集像是一張模擬考卷,而測試集就是最終的大考。因此通常一個有效的驗證集每每意味着這題已經成功了一半,而一個錯誤的驗證集意味着南轅北轍。it
對於大多數問題,咱們一般會有個默認的假設,那就是訓練數據與測試數據是知足獨立同分布的(iid)。也就是說訓練數據和測試數據是差很少的兩張卷子,在數據量夠大的狀況下,咱們能夠隨機拿一部分習題集用來學習,另外一部分做爲模擬卷用來試試本身的實力,由此演變而來的就是最多見的帶shuffle的train_test_split和K-Fold(以及Stratified K-Fold)。io
但並不是全部的問題均可以這麼簡單粗暴,在選取驗證集的時候,咱們至少須要考慮3個問題:test
(1)咱們假設數據分佈的相同是基於什麼?方法
(2)咱們但願模型經過訓練學到什麼信息?數據
(3)有什麼是不能在訓練中泄露給模型的(leakage)?分享
基於此3點,咱們主要用3種不一樣的線下驗證集的建立方法,分別是:時間
(1)帶shuffle的K-Fold/Stratified K-Fold思考
(2)順序切分(如時間序列在某個時間點切一刀)
(3)Group K-Fold
接下來分別說說我的對此的理解。
(1)帶shuffle的K-Fold/Stratified K-Fold
假設某個學生巨多的年級咱們抽了一批學生(測試集),想要了解他們的某科成績。咱們的假設是全部學生的成績都服從一個正態分佈,這些學生都是這同一個分佈中抽樣出來的。那麼咱們在剩下的學生中要分割訓練集和測試集的話就很簡單。咱們會認爲:
1) 全部的數據都來源於同一個分佈;
2) 等量(足夠大)但不一樣的抽樣對模型能學到的信息沒有太大影響;
3) 基本不存在信息泄露問題。
在這種狀況下,咱們會採用帶shuffle的K-Fold,由於既然全部的數據都來源於同一個分佈,那麼學習咱們採樣的數據中的信息就可以估計到整個分佈的信息。所以,咱們用交叉驗證(Cross Validation)就能夠保證同分布的問題,而shuffle則表明咱們抽樣的隨機性並不會很大程度地影響模型的學習,這種驗證是很是有效的。在正負樣本極端不平衡的狀況下,咱們須要使用Stratified K-Fold來保證正樣本被模型學習到,從而避免某一折全是負樣本的狀況。
因此,咱們再隨機抽一批學生(最好與測試集等量)作驗證集就行。
(2)順序切分
假設咱們有一羣學生過去幾週上課打瞌睡的數據,咱們想要預測下週什麼狀況下他們會打瞌睡。咱們的假設是學生每週的行爲是穩定的,重複的(按週期重複)。可是在一週以內,他們天天的行爲可能並不相同,好比周一會更困,而週五會更興奮等等。咱們會認爲:
1)每一個週期之間的分佈是相同的(周與周),但每一個週期內部的分佈是不一樣的(天與天);
2)模型要學習一個完整週期內的信息(週一到週日);
3)跨週期的信息不該該泄露(本週與下週)。
在這種狀況下,基於以上三點,咱們通常會採用按時間切分,由於只有按時間切分能知足以上三個要求。
若是用帶shuffle的K-Fold會怎麼樣呢?首先,咱們不能保證模型能學習到一個完整週期內的全部信息。此外,即使數據量達到能夠保證這一點,shuffle的存在會使得下一個週期的信息混入上一個週期,反之亦然,這就致使了泄露。模型在線下驗證集上的得分會很高,但線上會差一截。由於這個「好成績」是因爲信息泄露致使的,而不是模型真的學習到了什麼。
因此,咱們能夠選擇保留最後一週做爲驗證集。
(3) Group K-Fold
假設有五個班級的學生,班級之間的水平良莠不齊,給你一班、二班、三班、五班的一些歷史信息,要你預測四班的學生下次考試的成績。咱們的假設是雖然五個班級的分佈並不相同,但學霸考高分的模式老是相同的。
若是咱們使用帶shuffle的K-Fold會怎麼樣呢?假如一班平均實力特別強,而三班特別弱,咱們會發現班級這個特徵佔的份量會很重,然而測試集的四班模型歷來都沒見過,這明顯會致使過擬合,從而線下虛高,線上崩盤。這裏就須要使用Group K-Fold了。
Group K-Fold比較難解釋,也相對較新,早期的sklearn裏彷佛並無這個功能。它讓你能夠指定某個或某些特徵,而且保證這些特徵的值不跨越每一個Fold,也就是實現特徵值的隔離。
舉個例子,若是你指定班級來進行Group,那麼全部一班相關的內容都出如今某個Fold中,而你在其餘Fold中找不到任何關於一班的內容。也就是說,你把一班的信息隔離在了那個Fold裏。
那麼咱們何時會須要Group K-Fold呢?當咱們認爲:
1)全部數據自己未必同分布(一班三班有差別),但其背後某種潛在的模式是一致的;
2)模型要學習對的是某種跨Group的內容或者模式(不侷限於某個班級的);
3)不一樣Group之間的信息不該該泄露(一班與三班)
使用Group K-Fold將掩蔽用來進行Group的特徵(班級),由於這個特徵是沒法被泛化的。而模型將學習的是跨越該特徵的信息(挖掘學霸),這樣的信息纔是有價值的,能夠被泛化的。
總而言之,線下驗證集的選取並非一件很隨便的事情。它取決於數據自己的構成以及咱們對數據所傳達的信息的假設。因此,要保證線下驗證集靠譜的話,咱們仍是要——多作EDA啊!