今天我給大家盤(pán)點(diǎn)下機(jī)器學(xué)習(xí)中所使用的交叉驗(yàn)證器都有哪些,用最直觀的圖解方式來(lái)幫助大家理解他們是如何工作的。 數(shù)據(jù)集說(shuō)明數(shù)據(jù)集來(lái)源于kaggle M5 Forecasting - Accuracy[1] 該任務(wù)是盡可能精確地預(yù)測(cè)沃爾瑪在美國(guó)銷售的各種產(chǎn)品的單位銷售額(demand)。本文將使用其中的一部分?jǐn)?shù)據(jù)。 該數(shù)據(jù)樣例如下。 數(shù)據(jù)集的劃分需要根據(jù)交叉驗(yàn)證基本原理來(lái)操作。首先需要將所有數(shù)據(jù)集劃分為訓(xùn)練集和測(cè)試集,再再訓(xùn)練集中利用交叉驗(yàn)證劃分訓(xùn)練集和驗(yàn)證集,如下圖所示。 首先按照日期date劃分測(cè)試集和訓(xùn)練集,如下圖所示。 為本次演示需求,創(chuàng)造了一些新的特征,最終篩選并使用了如下幾個(gè)變量。 Training columns: 設(shè)置如下兩個(gè)全局變量,以及用來(lái)存儲(chǔ)每種交叉驗(yàn)證得分結(jié)果的DataFrame
交叉驗(yàn)證交叉驗(yàn)證(Cross Validation) 是在機(jī)器學(xué)習(xí)建立模型和驗(yàn)證模型參數(shù)時(shí)常用的方法。顧名思義,就是重復(fù)的使用數(shù)據(jù),把得到的樣本數(shù)據(jù)進(jìn)行切分,組合為不同的訓(xùn)練集和測(cè)試集。用訓(xùn)練集來(lái)訓(xùn)練模型,測(cè)試集來(lái)評(píng)估模型的好壞。 交叉驗(yàn)證的目的
交叉驗(yàn)證的種類根據(jù)切分的方法不同,交叉驗(yàn)證分為下面三種: 第一種是簡(jiǎn)單交叉驗(yàn)證首先,隨機(jī)的將樣本數(shù)據(jù)分為兩部分(比如:70%的訓(xùn)練集,30%的測(cè)試集),然后用訓(xùn)練集來(lái)訓(xùn)練模型,在測(cè)試集上驗(yàn)證模型及參數(shù)。接著再把樣本打亂,重新選擇訓(xùn)練集和測(cè)試集,繼續(xù)訓(xùn)練數(shù)據(jù)和檢驗(yàn)?zāi)P?。最后選擇損失函數(shù)評(píng)估最優(yōu)的模型和參數(shù)。 第二種是K折交叉驗(yàn)證(K-Fold Cross Validation)和第一種方法不同, 折交叉驗(yàn)證會(huì)把樣本數(shù)據(jù)隨機(jī)的分成 份,每次隨機(jī)的選擇 份作為訓(xùn)練集,剩下的1份做測(cè)試集。當(dāng)這一輪完成后,重新隨機(jī)選擇 份來(lái)訓(xùn)練數(shù)據(jù)。若干輪(小于 )之后,選擇損失函數(shù)評(píng)估最優(yōu)的模型和參數(shù)。 第三種是留一交叉驗(yàn)證(Leave-one-out Cross Validation)它是第二種情況的特例,此時(shí) 等于樣本數(shù) ,這樣對(duì)于 個(gè)樣本,每次選擇 個(gè)樣本來(lái)訓(xùn)練數(shù)據(jù),留一個(gè)樣本來(lái)驗(yàn)證模型預(yù)測(cè)的好壞。此方法主要用于樣本量非常少的情況,比如對(duì)于普通適中問(wèn)題, 小于50時(shí),一般采用留一交叉驗(yàn)證。 下面將用圖解方法詳細(xì)介紹12種交叉驗(yàn)證方法,主要參考scikit-learn官網(wǎng)[2]介紹。 交叉驗(yàn)證器01 K折交叉驗(yàn)證--沒(méi)有打亂折交叉驗(yàn)證器 KFold,提供訓(xùn)練/驗(yàn)證索引以拆分訓(xùn)練/驗(yàn)證集中的數(shù)據(jù)。將數(shù)據(jù)集拆分為 個(gè)連續(xù)的折疊(默認(rèn)情況下不改組)。然后將每個(gè)折疊用作一次驗(yàn)證,而剩余的 個(gè)折疊形成訓(xùn)練集。 from sklearn.model_selection import KFold
不建議使用這種類型的交叉驗(yàn)證來(lái)處理時(shí)間序列數(shù)據(jù),因?yàn)樗雎粤藬?shù)據(jù)的連貫性。實(shí)際的測(cè)試數(shù)據(jù)是將來(lái)的一個(gè)時(shí)期。 如下圖所示,黑色部分為被用作的驗(yàn)證的一個(gè)折疊,而黃色部分為被用作訓(xùn)練的 個(gè)折疊。 另外數(shù)據(jù)分布圖是5折交叉驗(yàn)證中每個(gè)驗(yàn)證數(shù)據(jù)集(黑色部分),及實(shí)際用作驗(yàn)證模型的數(shù)據(jù)集的組合分布圖。 02 K折交叉驗(yàn)證--打亂的K折交叉驗(yàn)證器KFold設(shè)置參數(shù) from sklearn.model_selection import KFold
在每次迭代中,五分之一的數(shù)據(jù)仍然是驗(yàn)證集,但這一次它是隨機(jī)分布在整個(gè)數(shù)據(jù)中。與前面一樣,在一個(gè)迭代中用作驗(yàn)證的每個(gè)示例永遠(yuǎn)不會(huì)在另一個(gè)迭代中用作驗(yàn)證。 如下圖所示,黑色部分為被用作驗(yàn)證的數(shù)據(jù)集,很明顯,驗(yàn)證集數(shù)據(jù)是被打亂了的。 03 隨機(jī)排列交叉驗(yàn)證隨機(jī)排列交叉驗(yàn)證器ShuffleSplit,生成索引以將數(shù)據(jù)拆分為訓(xùn)練集和驗(yàn)證集。 注意:與其他交叉驗(yàn)證策略相反,隨機(jī)拆分并不能保證所有折疊都會(huì)不同,盡管對(duì)于大型數(shù)據(jù)集來(lái)說(shuō)z這是很有可能。 from sklearn.model_selection import ShuffleSplit
ShuffleSplit將在每次迭代過(guò)程中隨機(jī)抽取整個(gè)數(shù)據(jù)集,生成一個(gè)訓(xùn)練集和一個(gè)驗(yàn)證集。 由于部分?jǐn)?shù)據(jù)未包含在訓(xùn)練中,該方法比普通的k倍交叉驗(yàn)證更快。 如下圖所示,黑色部分為被用作驗(yàn)證的數(shù)據(jù)集,橙色是被用作訓(xùn)練的數(shù)據(jù)集,而白色部分為未被包含在訓(xùn)練和驗(yàn)證集中的數(shù)據(jù)集。 04 分層K折交叉驗(yàn)證--沒(méi)有打亂分層 折交叉驗(yàn)證器StratifiedKFold。 提供訓(xùn)練/驗(yàn)證索引以拆分訓(xùn)練/驗(yàn)證集中的數(shù)據(jù)。這個(gè)交叉驗(yàn)證對(duì)象是 from sklearn.model_selection import StratifiedKFold
就跟普通的 折交叉驗(yàn)證類似,但是每折包含每個(gè)目標(biāo)樣本的大約相同的百分比。更好地使用分類而不是回歸。 其中有幾點(diǎn)需要注意:
如下圖所示,在沒(méi)有打亂的情況下,驗(yàn)證集(圖中黑色部分)分布是有一定的規(guī)律的。 且從下面的數(shù)據(jù)分布圖可見(jiàn),5折交叉驗(yàn)證數(shù)據(jù)密度分布曲線基本重合,說(shuō)明雖然劃分的樣本不同,但其分布基本一致。 05 分層K折交叉驗(yàn)證--打亂的對(duì)于每個(gè)目標(biāo),折疊包大約相同百分比的樣本,但首先數(shù)據(jù)被打亂。這里需要注意的是,該交叉驗(yàn)證的拆分?jǐn)?shù)據(jù)方法是一致的,僅僅是在拆分前,先打亂數(shù)據(jù)的排列,再進(jìn)行分層 折交叉驗(yàn)證。 from sklearn.model_selection import StratifiedKFold
如下圖所示,打亂的分層K折交叉驗(yàn)證的驗(yàn)證集是沒(méi)有規(guī)律、隨機(jī)分布的。 該交叉驗(yàn)證的數(shù)據(jù)分布與未被打亂的分層K折交叉驗(yàn)證基本一致。 06 分組K折交叉驗(yàn)證具有非重疊組的 折迭代器變體GroupKFold。 同一組不會(huì)出現(xiàn)在兩個(gè)不同的折疊中(不同組的數(shù)量必須至少等于折疊的數(shù)量)。這些折疊是近似平衡的,因?yàn)槊總€(gè)折疊中不同組的數(shù)量是近似相同的。 可以從數(shù)據(jù)集的另一特定列(年)來(lái)定義組。確保同一組中不同時(shí)處于訓(xùn)練集和驗(yàn)證集中。 該交叉驗(yàn)證器分組是在方法 from sklearn.model_selection import GroupKFold
如下圖所示,由于數(shù)據(jù)集原因(不是包含5個(gè)整年(組)),因此5折交叉驗(yàn)證中,并不能保證沒(méi)次都包含相同數(shù)據(jù)數(shù)量的驗(yàn)證集。 在上一個(gè)示例中,我們使用年作為組,在下一個(gè)示例中使用月作為組。大家可以通過(guò)下面圖可以很明顯地看看有什么區(qū)別。 from sklearn.model_selection import GroupKFold
如下圖所示,每次迭代均是以月為組來(lái)取驗(yàn)證集。 ![]() 07 分組K折交叉驗(yàn)證--留一組留一組交叉驗(yàn)證器LeaveOneGroupOut。 根據(jù)第三方提供的整數(shù)組數(shù)組保留樣本。此組信息可用于編碼任意特定于域的預(yù)定義交叉驗(yàn)證折疊。 因此,每個(gè)訓(xùn)練集由除與特定組相關(guān)的樣本之外的所有樣本構(gòu)成。 例如,組可以是樣本收集的年份、月份等,因此允許針對(duì)基于時(shí)間的拆分進(jìn)行交叉驗(yàn)證。 from sklearn.model_selection import LeaveOneGroupOut
在每次迭代中,模型都使用留一組之外的所有組的樣本進(jìn)行訓(xùn)練。如果以月份為組,則執(zhí)行12次迭代。 由下圖可以看到該分組K折交叉驗(yàn)證的拆分?jǐn)?shù)據(jù)方法。 ![]() 08 分組K折交叉驗(yàn)證--留N組LeavePGroupsOut將 LeavePGroupsOut 和 LeaveOneGroupOut 的區(qū)別在于,前者使用所有樣本分配到 通過(guò)參數(shù) from sklearn.model_selection import LeavePGroupsOut
由下圖可知,因 ![]() 09 隨機(jī)排列的分組K折交叉驗(yàn)證Shuffle-Group(s)-Out 交叉驗(yàn)證迭代器GroupShuffleSplit GroupShuffleSplit迭代器為ShuffleSplit和LeavePGroupsOut的兩種方法的結(jié)合,并生成一個(gè)隨機(jī)分區(qū)序列,其中每個(gè)分區(qū)都會(huì)保留組的一個(gè)子集。 例如,組可以是樣本收集的年份,因此允許針對(duì)基于時(shí)間的拆分進(jìn)行交叉驗(yàn)證。 LeavePGroupsOut 和 GroupShuffleSplit 之間的區(qū)別在于,前者使用大小 例如,與 注意:參數(shù) 定義組,并在每次迭代中隨機(jī)抽樣整個(gè)數(shù)據(jù)集,以生成一個(gè)訓(xùn)練集和一個(gè)驗(yàn)證集。 from sklearn.model_selection import GroupShuffleSplit
從圖中可見(jiàn),斷開(kāi)(白色)部分為未取到的數(shù)據(jù)集,每一行中每段(以白色空白為界)中驗(yàn)證集(黑色)比例及位置都是一致的。而不同行之間驗(yàn)證集的位置是不同的。 ![]() 10 時(shí)間序列交叉驗(yàn)證時(shí)間序列數(shù)據(jù)的特征在于時(shí)間上接近的觀測(cè)值之間的相關(guān)性(自相關(guān))。然而,經(jīng)典的交叉驗(yàn)證技術(shù),例如 KFold 和 ShuffleSplit假設(shè)樣本是獨(dú)立的和同分布的,并且會(huì)導(dǎo)致時(shí)間序列數(shù)據(jù)的訓(xùn)練和測(cè)試實(shí)例之間不合理的相關(guān)性(產(chǎn)生對(duì)泛化誤差的不良估計(jì))。 因此,在“未來(lái)”觀察中評(píng)估我們的模型的時(shí)間序列數(shù)據(jù)非常重要,這與用于訓(xùn)練模型的觀察最不相似。為了實(shí)現(xiàn)這一點(diǎn),提供了一種解決方案TimeSeriesSplit。 TimeSeriesSplit是KFold的變體,它首先返回 折疊成訓(xùn)練集和 第 折疊作為驗(yàn)證集。請(qǐng)注意,與標(biāo)準(zhǔn)交叉驗(yàn)證方法不同,連續(xù)訓(xùn)練集是它們之前的超集。此外,它將所有剩余數(shù)據(jù)添加到第一個(gè)訓(xùn)練分區(qū),該分區(qū)始終用于訓(xùn)練模型。 from sklearn.model_selection import TimeSeriesSplit
這種方法建議用于時(shí)間序列數(shù)據(jù)。在時(shí)間序列分割中,訓(xùn)練集通常分為兩部分。第一部分始終是訓(xùn)練集,而后一部分是驗(yàn)證集。 由下圖可知,驗(yàn)證集的長(zhǎng)度保持不變,而訓(xùn)練集隨著每次迭代的不斷增大。 ![]() 11 封閉時(shí)間序列交叉驗(yàn)證這是自定義的一種交叉驗(yàn)證方法。該方法函數(shù)見(jiàn)文末函數(shù)附錄。 btscv = BlockingTimeSeriesSplit(n_splits=NFOLDS)
由下圖可見(jiàn),訓(xùn)練和驗(yàn)證集在每次迭代中都是唯一的。沒(méi)有值被使用兩次。列車集總是在驗(yàn)證之前。由于在較少的樣本中訓(xùn)練,它也比其他交叉驗(yàn)證方法更快。 ![]() 12 清除K折交叉驗(yàn)證這是基于_BaseKFold的一種交叉驗(yàn)證方法。在每次迭代中,在訓(xùn)練集之前和之后,我們會(huì)刪除一些樣本。 cont = pd.Series(train.index)
由下圖可看出,訓(xùn)練集前后刪除了一些樣本。且其劃分訓(xùn)練集和驗(yàn)證集的方法與基礎(chǔ)不打亂的 ![]() 將 cont = pd.Series(train.index)
由下圖可看出,不僅在訓(xùn)練集前后刪除了部分樣本,在驗(yàn)證集后面也刪除了一些樣本,這些樣本的大小將取決于參數(shù) ![]() 各交叉驗(yàn)證結(jié)果比較cm = sns.light_palette('green', as_cmap=True, reverse=True) ![]() 附錄封閉時(shí)間序列交叉驗(yàn)證函數(shù)
清除K折交叉驗(yàn)證函數(shù)from sklearn.model_selection._split import _BaseKFold 參考資料數(shù)據(jù)集: https://www./c/m5-forecasting-accuracy [2]交叉驗(yàn)證: https:///stable/modules/classes.html |
|
來(lái)自: LibraryPKU > 《機(jī)器學(xué)習(xí)》