模型评价 - 机器学习与建模中怎么克服过拟合问题?
上一篇博客鏈接: 機器學習與建模中 - 判斷數據模型擬合效果的三種方法
在上一篇博客中,我們談到了使用損失函數來判斷模型的擬合效果。但是擬合效果比較好的模型不一定是最好的模型,建模的最終目的是為了預測,因此預測最精準的模型才是最好的模型。
提到預測,我們引入一個新的概念,叫作“泛化能力”(泛化能力是指機器學習算法對新鮮樣本的適應能力。學習的目的是學到隱含在數據對背后的規律,對具有同一規律的學習集以外的數據,經過訓練的網絡也能給出合適的輸出。)
比如在多項式回歸的例子上(下圖),對于同樣的訓練數據,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情況下的損失值一般是用平均損失函數計算。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
下圖給出了奧運會男子100米短跑數據在LOOCV情況下的平均損失值,圖中曲線表明 3 階多項式模型才是損失值最小的。這個結論顯然與方法一中取1980年后的數據作為驗證集的結論不一樣,這樣的分歧并不是異常的。但是兩種方法一致的結論就是,高于 3 階的模型都是不合適的。
?
方法三:K折交叉驗證的計算縮放
留一交叉驗證似乎已經是評估模型好壞的一種好方法,他幾乎可以評估各種可選擇的模型。然而在工作中,我們往往要考慮成本問題,對于 LOOCV 的實現,需要訓練模型 N 次,這比簡單的模型選擇方法要多耗費約 N 倍的時間。對于一些復雜度比較高的模型,比如高階多項式、對數函數、三角函數等,或者對于數據量比較大的模型,這顯然并不可行。
解決這個難題的方法就是限制 K 的值,令 K << N ,由此可以大大縮減訓練模型的次數。
經歷多年的嘗試,業界習慣的令 K = 10,在 10 折交叉驗證中,我們用數據集中的 10% 作為驗證集,剩下的 90% 作為訓練集,模型的訓練只循環 10 次。特別是當數據條數 N 遠遠大于10 的情況下,這將會是很大的一筆節省。
?
方法四:清洗噪點
有時候,能影響模型泛化能力的可能是某幾個噪點引起的過擬合,因此只要在數據清洗的過程中,刪除噪點,或者用均值代替,或者用鄰近值代替即可,數據清洗的方法請點擊下面鏈接:
文章鏈接:Python數據預處理 - 數據清洗 - 洗什么?怎么洗?看完就明白了
?
總結
以上是生活随笔為你收集整理的模型评价 - 机器学习与建模中怎么克服过拟合问题?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 缺失值处理 - 获取一段时间内所有日期的
- 下一篇: linux防火墙的复规则,Centos下