一個完整的機器學習專案在Python中演練(四)
【磐創AI導讀】:本文是一個完整的機器學習專案在python中的演練系列第第四篇。詳細介紹了超引數調整與模型在測試集上的評估兩個步驟。歡迎大家點選上方藍字關注我們的公眾號:磐創AI。
大家往往會選擇一本資料科學相關書籍或者完成一門線上課程來學習和掌握機器學習。但是,實際情況往往是,學完之後反而並不清楚這些技術怎樣才能被用在實際的專案流程中。就像你的腦海中已經有了一塊塊”拼圖“(機器學習技術),你卻不知道如何講他們拼起來應用在實際的專案中。如果你也遇見過同樣的問題,那麼這篇文章應該是你想要的。本系列文章將介紹一個針對真實世界實際資料集的完整機器學習解決方案,讓你瞭解所有部分如何結合在一起。
本系列文章按照一般機器學習工作流程逐步進行:
1. 資料清洗與格式處理
2. 探索性資料分析
3. 特徵工程和特徵選取
4. 機器學習模型效能指標評估
5. 微調最佳模型(超引數)
6. 在測試集上評估最佳模型
7. 解釋模型結果
8. 總結分析
透過完成所有流程,我們將看到每個步驟之間是怎麼聯絡起來的,以及如何在Python中專門實現每個部分。該專案在GitHub上可以找到,附實現過程。本篇文章將詳細介紹第五-六個步驟,剩下的內容將在後面的文章中介紹。前四個步驟詳見:資料清洗與格式處理、探索性資料分析、特徵工程和特徵選取、機器學習模型效能指標評估。
隨機搜尋與交叉驗證
我們透過隨機搜尋與交叉驗證的方法實現超引數調整:
我們使用隨機搜尋(Randam Search:)來為我們的模型選擇最佳超引數。我們定義一個網格(grid)後採用的是隨機抽樣的方式(random search)選取不同的超引數組合而不是像網格搜尋嘗試每一個超引數組合。(值得一提的是,使用隨機搜尋方法選擇超引數的表現幾乎和網格搜尋一樣,同時大大縮短了搜尋時間。)
我們使用交叉驗證(Cross Validation:)的方法來評估所選超引數組合表現。這裡我們選擇使用K-Fold交叉驗證,而不是將訓練集直接分成單獨的訓練集和驗證集,那樣會減少我們可以使用的訓練資料量。在k-折交叉驗證中,原始樣本被隨機劃分為k等份子樣本。在k份子樣本中,保留一個子樣本作為測試模型的驗證集,剩下的k-1子樣本用作模型訓練。重複進行k次(the folds)交叉驗證過程,每一個子樣本都作為驗證資料被使用一次。然後,這些摺疊的k結果可以被平均(或其他組合)產生一個單一的估計。最後,我們將K次迭代的平均誤差作為最終的效能指標。
K = 5的K-fold交叉驗證過程如下所示:
使用隨機搜尋與交叉驗證驗證選擇最優超引數組合的步驟為:
1. 設定一個超引數的網格(grid)用於評估
2. 隨機抽樣一組超引數
3. 用選定的超引數組合建立一個模型
4. 使用K-fold交叉驗證評估模型
5. 確定表現最佳的超引數組合
當然,我們實際上是呼叫Scikit-Learn工具庫中封裝好的RandomizedSearchCV函式來實現上述操作的。
背景介紹:梯度提升法(GBM)
我們先簡單介紹一下我們將要使用的梯度提升迴歸(Gradient Boosted Regression)模型。梯度提升是一種用於迴歸和分類問題的機器學習技術,該技術以弱預測模型(通常為決策樹)的集合的形式產生預測模型。本專案中使用的也是決策樹。雖然諸如隨機森林之類的整合演算法()是透過並行地訓練弱“學習者”並分別“投票”進行預測,但像梯度提升這樣的增強方法(boosting method)則是透過依次訓練“學習者”,並且每個學習者“集中”學習前面“學習者”所不擅長的部分。
增強方法(boosting method)近年來越來越流行,並且頻繁地在各種機器學習競賽中名列前茅。梯度提升法(GBM)是使用梯度下降來最佳化代價函式的一種特定實現。具體來說,它透過基於殘差順序訓練“學習者”來實現。另外,使用scikit-learn工具庫來實現Gradient Boosting的效率通常被認為是低於XGBoost 等其他庫的。但是,它對於我們本專案所用到的小資料集來說是足夠的,並且相當準確。
超引數調整
梯度提升迴歸模型(Gradient Boosted Regressor)有多項超引數,具體可以檢視Scikit-Learn官方文件以瞭解詳細資訊。本專案中將最佳化以下超引數:
loss:損失函式的最小值設定
n_estimators:所使用的弱“學習者”(決策樹)的數量
max_depth:決策樹的最大深度
min_samples_leaf:決策樹的葉節點所需的最小示例個數
min_samples_split:分割決策樹節點所需的最小示例個數
max_features:最多用於分割節點的特徵個數
完全弄懂這些超引數之間的相互作用是比較難的,所以最佳的方式就是去嘗試多種超引數組合。
在下面的程式碼中,我們構建一個超引數網格,建立一個RandomizedSearchCV物件,並使用含有超過25種不同的超引數組合的4折交叉驗證來執行超引數搜尋:
執行搜尋後,我們可以“核查”RandomizedSearchCV物件來找到最佳模型:
然後,我們還可以再次進行網格搜尋,透過選擇接近這些最優值的網格引數來執行網格搜尋。但是,進一步調整不太可能顯著地改善我們的模型。通常來說,合適的特徵工程對模型效能的影響要比廣泛的超引數調整更大。機器學習的收益遞減規律(http://www.picnet.com.au/blogs/guido/2018/04/13/diminishing-returns-machine-learning-projects/):特徵工程可以幫助你實現較大的提升,而超引數調整通常只會帶來很小的收益。
我們可以嘗試單一改變estimators(決策樹)的數量,來看下模型表現。我們可以透過視覺化的方法直觀的看到此時模型表現的變化。具體結果如下:
隨著模型使用的樹的個數增加,訓練集誤差和測試集誤差都會減少。但是,訓練集誤差比測試集誤差下降得快很多。同時也可以直觀的推測出來這樣的模型存在過擬合現象:它在訓練集上表現非常好,但在測試集上無法達到相同的效能。
這可能與我們所期待的不一樣,畢竟我們可以看到:它在訓練集上表現有所提升。但是,對比訓練集上與測試集上的表現的顯著差距表明模型存在過擬合現象。通常來說,我們可以透過獲取更多訓練資料來解決過擬合問題,或者透過調整超引數降低模型的複雜度來解決。對於本專案,我們將保持原先選擇的超引數組合,不再對estimators(決策樹)的數量進行調整。有興趣可以再多去嘗試一下。
對於最終模型,我們設定estimators=800--交叉驗證中最低誤差時的超引數值。接下來,讓我們測試該模型在測試集上的表現。
在測試集上評估最佳模型
在之前的步驟中我們已經確保了模型訓練時不接觸到測試集。因此,我們可以根據模型在測試集上的表現準確客觀的評估模型的最終效能。
在測試集上進行預測並評價效能是相對直接的方式。這裡,我們比較了使用預設超引數的梯度提升迴歸模型與微調後的模型的效能:
從上面可以看出超引數調整將模型表現提高了約10%。某些情況下10%可能算是一個巨大的改進了,但是在一個大的時間成本前提下。
我們也可以使用%timeit命令來比較一下模型訓練花費的時間。首先是預設配置下的模型:
1秒的訓練時間似乎是合理的。最終調整超引數後模型並不是那麼快:
這也說明了機器學習的一個基本特性:它是一種“權衡遊戲”。我們需要不斷地平衡準確性與可解釋性、偏差與方差、準確性與執行時間等表現。正確的混合將最終取決於問題。本專案中,相對而言執行時間增加12倍是恐怖的,但絕對而言又不是顯著(增加了十幾秒)。
我們已經得到了最終的測試集預測值,接下來我們就可以評估他們是否與真實值有著明顯的偏差了。上邊是預測值和實際值的密度圖,下邊是殘差直方圖:
從上面的兩張圖可以看出:雖然模型預測值得密度峰值接近中值在(66)附近,而非真實值的密度峰值(接近100),但模型預測值密度分佈大致接近實際值密度分佈。儘管我們可以看到一些模型預測值遠低於真值的較大的負值,殘差幾乎是符合正態分佈的。我們將在下一篇文章中深入探討分析模型的結果。
結論
在本篇文章中,我們介紹了機器學習工作流程中的以下幾個步驟:
使用隨機網格搜尋和交叉驗證進行超引數調整
在測試集上評估最佳模型
本次工作的結果表明,機器學習適用於本次任務-使用能源資料建立一個模型,可以預測建築物的能源之星評分(ENERGY STAR Score)。使用梯度提升迴歸模型能夠在測試集上的表現達到9.1分左右。此外,超引數調整可以在增加時間成本的情況下顯著提高模型效能。雖然從實際表現來看我們的模型預測是準確的,但是我們也許想要或者應該知道模型可以做出來這種預測的原因和這些表現在針對我們的任務方面,實際上告訴了我們什麼。這些問題將在下一篇文章中詳細探討。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31555081/viewspace-2216052/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 一個完整的機器學習專案在Python中演練(三)機器學習Python
- 一個完整的機器學習專案在Python中的演練(一)機器學習Python
- 一個完整的機器學習專案在Python中的演練(三)機器學習Python
- 一個完整的機器學習專案在Python中的演練(二)機器學習Python
- 機器學習入門系列(2)--如何構建一個完整的機器學習專案(一)機器學習
- 一個完整的scrapy 專案
- 完整的python專案例項-python完整專案Python
- 一個練習專案,好玩的bbs-python-cherrypyPython
- 一個練習專案,好玩的bbs-python-flaskPythonFlask
- 一個練習專案,好玩的bbs-python-bottlePython
- 10個Python練手專案Python
- 泰坦尼克生還預測:完整的機器學習專案(一)機器學習
- 一個練習專案,好玩的bbs-python-tornadoPython
- 一個練習專案,好玩的bbs-python-pyramidPython
- python實戰一個完整的專案-年終課程盤點|16 個 Python 綜合實戰專案合集Python
- [譯]Python中的非同步IO:一個完整的演練Python非同步
- 完整的python專案例項-Python例項練手專案彙總(附原始碼)Python原始碼
- 一個專案完整的管理流程有哪些
- GitHub最著名的20個Python機器學習專案!GithubPython機器學習
- 完整的設計一個專案需要什麼?
- 20 個頂尖的 Python 機器學習開源專案Python機器學習
- 機器學習中演算法與模型的區別機器學習演算法模型
- 開源一個機器學習文字分析專案機器學習
- 一個練習專案,好玩的bbs-1
- 一個練習專案,好玩的bbs-javaJava
- 一個練習專案,好玩的bbs-c#C#
- 最適合練手30個的機器學習開源專案,趕緊收藏!機器學習
- 推薦:一個適合於Python新手的入門練手專案Python
- 使用Express MongoDB開發一個完整MVC專案ExpressMongoDBMVC
- 如何5分鐘跑起來一個完整專案?
- 開源一個功能完整的SpringBoot專案框架Spring Boot框架
- 實戰 | 如何上線一個機器學習專案?機器學習
- 練手專案,實現一個web框架Web框架
- webpack實戰(一):真實專案中一個完整的webpack配置Web
- 一個小而全的Python專案示例Python
- 學python找不到專案練手?別擔心,70個python練手專案給你充實感Python
- 分享一個完整的社群專案(Android端加後臺)Android
- 記一次完整的專案部署