一個完整的機器學習項目在Python中演練(三)
來自專欄 TensorFlowNews8 人贊了文章
歡迎大家關注我們的網站和系列教程:http://www.tensorflownews.com/,學習更多的機器學習、深度學習的知識!也可以搜索公眾號:磐創AI,關注我們的文章。
作者:磐石
大家往往會選擇一本數據科學相關書籍或者完成一門在線課程來學習和掌握機器學習。但是,實際情況往往是,學完之後反而並不清楚這些技術怎樣才能被用在實際的項目流程中。就像你的腦海中已經有了一塊塊」拼圖「(機器學習技術),你卻不知道如何講他們拼起來應用在實際的項目中。如果你也遇見過同樣的問題,那麼這篇文章應該是你想要的。本系列文章將介紹一個針對真實世界實際數據集的完整機器學習解決方案,讓你了解所有部分如何結合在一起。
本系列文章按照一般機器學習工作流程逐步進行:
- 數據清洗與格式處理
- 探索性數據分析
- 特徵工程和特徵選取
- 機器學習模型性能指標評估
- 微調最佳模型(超參數)
- 在測試集上評估最佳模型
- 解釋模型結果
- 總結分析
通過完成所有流程,我們將看到每個步驟之間是怎麼聯繫起來的,以及如何在Python中專門實現每個部分。該項目在GitHub上可以找到,附實現過程。本篇文章將詳細介紹第四-五個步驟,剩下的內容將在後面的文章中介紹。前三個步驟詳見:數據清洗與格式處理、探索性數據分析、特徵工程和特徵選取。
模型評估和模型選擇
需要時刻注意的是,我們正在解決的是一項有監督回歸任務:使用紐約市建築的能源數據,開發一個能夠預測建築物能源之星評分的模型。預測的準確性和模型的可解釋性是最重要的兩個指標。
從大量現有的機器學習模型中選擇出適用的模型並不是一件容易的事。儘管有些「模型分析圖表」(如下圖)試圖告訴你要去選擇哪一種模型,但親自去嘗試多種演算法,並根據結果比較哪種模型效果最好,也許是更好的選擇。機器學習仍然是一個主要由經驗(實驗)而不是理論結果驅動的領域,事先就知道哪種模型最好,幾乎是不可能的。
(來源:https://docs.microsoft.com/en-us/azure/machine-learning/studio/algorithm-cheat-sheet)
一般來說,可以從簡單的可解釋模型(如線性回歸)開始嘗試,如果發現性能不足再轉而使用更複雜但通常更準確的模型。一部分模型的準確性與可解釋性關係(無科學依據)如下:
(來源:http://blog.fastforwardlabs.com/2017/09/01/LIME-for-couples.html)
我們將評估涵蓋複雜模型的五種不同模型:
- 線性回歸(LR)
- K-近鄰(KNN)
- 隨機森林(RF)
- 梯度提升(GBM)
- 支持向量機(SVM)
在這篇文章中,我們將重點介紹這些方法的使用,而不是其背後的理論。對於想學習模型背後理論的朋友,可以看這兩本書–「統計學習簡介」(在線免費:http://www-bcf.usc.edu/~gareth/ISL/)或「Hands-On Machine Learning with Scikit-Learn and TensorFlow」(http://shop.oreilly.com/product/0636920052289.do)。
缺失值填補
雖然我們在數據清洗的時候丟棄了含有超過50%缺失值的列,但仍有不少值缺失。機器學習模型無法處理任何含缺失值的數據,因此我們必須設法天秤那個它們。這個過程被稱作「插補」。
首先,讀入所有數據並輸出數據規模:
每一個NaN代表一個缺失對象。有著多種方法可以填補缺失數據(https://www.omicsonline.org/open-access/a-comparison-of-six-methods-for-missing-data-imputation-2155-6180-1000224.php?aid=54590),這裡使用一種一種相對簡單的方法–中值插補法。通過使用這個方法,每一列中的缺失對象都會被該列的中值所替換列。
在下面的代碼中,我們借用Scikit-Learn庫中封裝好的函數創建了一個以「中值替換」(median)為填補策略的Imputer對象。然後,在訓練集上(使用imputer.fit函數)上訓練這個對象,並用imputer.transform函數填充所有數據(訓練集+測試集)中的缺失值。也就是說,測試集中的缺失值也會被相對應訓練集中的中值所填充。
(以這樣的方式做「插補」是很有必要的,若是對所有數據進行訓練以得出中值可能造成「測試數據泄漏」(詳見:https://www.kaggle.com/dansbecker/data-leakage)問題–測試集中的信息有可能溢出到訓練數據中。)
過處理後,所有特徵都不再含有缺失值。
特徵縮放
特徵縮放是一種用於標準化自變數或數據特徵範圍的方法。在數據處理中,它也被稱為數據標準化。數據中的各項特徵是以不同單位測量得到的,因此涵蓋了不同的範圍,所以進行特徵縮放是很有必要的。諸如支持向量機和K近鄰這些會考慮各項特徵之間距離的方法顯著地受到這些特徵範圍的影響,特徵縮放對這些模型來說是很重要的,進行特徵縮放使得他們能夠學習數據特徵。儘管像線性回歸和隨機森林等方法實際上並不需要特徵縮放,但在比較多種演算法時進行這一步驟仍然是最佳選擇。
接下來通過「將每個特徵值放置在0到1之間」來縮放特徵。具體來說,我們先獲取每個特徵的每一個值,然後減去對應特徵的最小值併除以特徵值區間(區間=最大值減最小值)來完成。這種操作在特徵縮放中通常被稱為歸一化(normalization),另一個主要方法是標準化(standardization)。
儘管這個過程很容易手動實現,但這裡我們可以使用Scikit-Learn中的MinMaxScale函數實現。此方法的代碼與插補相似。同樣地,我們僅使用訓練數據進行訓練,然後轉換所有數據(訓練集+測試集)。
現在,數據中每個特徵值最小為0最大為1。缺失值填補和特徵縮放幾乎在完成所有機器學習任務中都需要做的兩個步驟。
在Scikit-Learn中實現機器學習模型
在完成所有數據清洗與格式化工作後,實際模型創建、訓練和預測工作反而相對簡單。這裡在Python中使用Scikit-Learn庫完成接下來的工作。Scikit-Learn有著完善的幫助文檔和統一的模型構建語法。一旦你了解如何在Scikit-Learn中創建模型,那麼很快就可以快速實現各種演算法。
接下來以梯度提升法(Gradient Boosting Regressor)為例演示模型創建、訓練(使用.fit函數)和預測(使用.predict函數)。代碼如下:
模型創建、訓練和測試都是通過一行代碼就可以實現。同理,我們構造了其它模型,只改變名稱。結果如下:
我們之前使用目標中值計算的基線(baseline)為24.5,從上圖中可以很清晰的對比模型表現。顯然,機器學習的表現比基線(baseline)有了顯著的改進,它適用於我們的問題。
梯度增加法(GBM)的平均絕對誤差(MAE = 10.013)微小的領先擊敗了隨機森林(RF:MAE=10.014)。值得注意的是,由於我們使用超參數的默認值,所以這些結果並不完全代表模型最終的表現。尤其是諸如支持向量機(SVM)這類模型,它們的性能高度依賴於這些超參數設置。儘管如此,通過上圖中的表現對比分析,我們還是選擇梯度提升回歸模型並在接下來的步驟中對其進行優化處理。
模型優化之超參數調整
對於機器學習任務,在選擇了一個模型後我們可以針對我們的任務調整模型超參數來優化模型表現。
首先,超參數是什麼,它們與普通參數有什麼不同?
- 模型超參數通常被認為是數據科學家在訓練之前對機器學習演算法的設置。例如:隨機森林演算法中樹的個數或K-近鄰演算法中設定的鄰居數。
- 模型參數是模型在訓練期間學習的內容,例如線性回歸中的權重。
超參數的設定影響著模型「欠擬合」與「過擬合」的平衡,進而影響模型表現。欠擬合是指我們的模型不足夠複雜(沒有足夠的自由度)去學習從特徵到目標特徵的映射。一個欠適合的模型有著很高的偏差(bias),我們可以通過增加模型的複雜度來糾正這種偏差(bias)。
過擬合是指我們的模型過渡記憶了訓練數據的情況。過擬合模型具有很高的方差(詳見:https://en.wikipedia.org/wiki/Bias%E2%80%93variance_tradeoff)。針對這種情況,我們可以通過正則化來限制模型的複雜度來糾正。「欠擬合」和「過擬合」在測試集上都不會有較好的表現。
對於每一個機器學習問題,都有著特有的最優超參數組合。因此,找到最佳超參數設置的唯一方法就是嘗試多種超參數設置來分析哪一個表現最佳。幸運的是,Scikit-Learn中有多種方法可以讓我們高效地評估超參數。此外,也有一些其他的方式選取最優超參數,例如Epistasis https://epistasislab.github.io/tpot/)等項目正試圖使用遺傳演算法等方法優化超參數搜索。有興趣的可以了解一下。本項目中將使用Scikit-Learn實現最優超參數選取。
最後,對深度學習感興趣,熱愛Tensorflow的小夥伴,歡迎關注我們的網站!http://www.tensorflownews.com。我們的公眾號:磐創AI。
推薦閱讀:
TAG:Python | 數據挖掘 | 深度學習DeepLearning |