機器學習與建模中 - 怎麼克服過擬合問題?

上一篇博客鏈接: 機器學習與建模中 - 判斷數據模型擬合效果的三種方法

在上一篇博客中,我們談到了使用損失函數來判斷模型的擬合效果。但是擬合效果比較好的模型不一定是最好的模型,建模的最終目的是爲了預測,因此預測最精準的模型纔是最好的模型。

提到預測,我們引入一個新的概念,叫作“泛化能力”(泛化能力是指機器學習算法對新鮮樣本的適應能力。學習的目的是學到隱含在數據對背後的規律,對具有同一規律的學習集以外的數據,經過訓練的網絡也能給出合適的輸出。)

比如在多項式迴歸的例子上(下圖),對於同樣的訓練數據,8階多項式的損失比1階多項式小很多,但是對於未來的預測,8階多項式顯得非常糟糕(下右圖)。由於8階多項式的模型過於關注訓練數據(過擬合),因此不能很好的泛化新數據。

 

 爲了克服過擬合,能夠更好的泛化,我們一般採取以下四種方法:

方法一:驗證集

方法二:交叉驗證

方法三:K折交叉驗證的計算縮放

方法四:清洗噪點


 

方法一:驗證集

克服過擬合問題的一般方法是使用第二個數據集,即驗證集。用驗證集來驗證模型的泛化能力。驗證集可以單獨提供或者從原始數據中抽取一部分作爲驗證集。比如奧運會男子100米短跑數據,抽取1980年之後的數據作爲驗證集,1980年之前的數據用於訓練模型。

在訓練集上訓練出 N 個模型,爲了判斷模型的泛化能力,我們計算他們在驗證集上的損失函數,損失函數越小則泛化能力越好。下圖表明,1階多項式模型的泛化能力最好,8階和6階的泛化能力較差。

下圖給出了 1 階、4 階、8 階多項式模型的泛化能力圖,可以很直觀的看出來模型的好壞。

 


 

方法二:交叉驗證

交叉驗證與驗證相差“交叉”兩個字,所謂交叉驗證就是把原始數據集分爲大小儘可能相等的 K 塊數據集,每一塊數據集輪流作爲驗證集,剩餘的 K-1 塊作爲訓練集訓練模型。在計算損失值得時候,將K個驗證集上計算出的損失值的平均數作爲最後的損失值。

特殊的,當 K = N 時,即把數量爲 N 的原始數據集分成了 N 份,這就使得每一次的驗證集都只有一條數據。K 折交叉驗證的這種特殊情況稱之爲留一交叉驗證(Leave-One-Out Cross Validation, LOOCV),LOOCV情況下的損失值一般是用平均損失函數計算。

                                                           L = \frac{1}{N}\Sigma \left ( t_{n} - \omega _{-n}^{T}x_{n}\right )^{2}

下圖給出了奧運會男子100米短跑數據在LOOCV情況下的平均損失值,圖中曲線表明 3 階多項式模型纔是損失值最小的。這個結論顯然與方法一中取1980年後的數據作爲驗證集的結論不一樣,這樣的分歧並不是異常的。但是兩種方法一致的結論就是,高於 3 階的模型都是不合適的。


 

方法三:K折交叉驗證的計算縮放

留一交叉驗證似乎已經是評估模型好壞的一種好方法,他幾乎可以評估各種可選擇的模型。然而在工作中,我們往往要考慮成本問題,對於 LOOCV 的實現,需要訓練模型 N 次,這比簡單的模型選擇方法要多耗費約 N 倍的時間。對於一些複雜度比較高的模型,比如高階多項式、對數函數、三角函數等,或者對於數據量比較大的模型,這顯然並不可行。

解決這個難題的方法就是限制 K 的值,令 K << N ,由此可以大大縮減訓練模型的次數。

經歷多年的嘗試,業界習慣的令 K = 10,在 10 折交叉驗證中,我們用數據集中的 10% 作爲驗證集,剩下的 90% 作爲訓練集,模型的訓練只循環 10 次。特別是當數據條數 N 遠遠大於10 的情況下,這將會是很大的一筆節省。


 

方法四:清洗噪點

有時候,能影響模型泛化能力的可能是某幾個噪點引起的過擬合,因此只要在數據清洗的過程中,刪除噪點,或者用均值代替,或者用鄰近值代替即可,數據清洗的方法請點擊下面鏈接:

文章鏈接:Python數據預處理 - 數據清洗 - 洗什麼?怎麼洗?看完就明白了

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章