一個完整的機器學習專案在Python中演練(三)

磐石001發表於2018-06-04

大家往往會選擇一本資料科學相關書籍或者完成一門線上課程來學習和掌握機器學習。但是,實際情況往往是,學完之後反而並不清楚這些技術怎樣才能被用在實際的專案流程中。就像你的腦海中已經有了一塊塊”拼圖“(機器學習技術),你卻不知道如何講他們拼起來應用在實際的專案中。如果你也遇見過同樣的問題,那麼這篇文章應該是你想要的。本系列文章將介紹一個針對真實世界實際資料集的完整機器學習解決方案,讓你瞭解所有部分如何結合在一起。

 

本系列文章按照一般機器學習工作流程逐步進行:

  1. 資料清洗與格式處理
  2. 探索性資料分析
  3. 特徵工程和特徵選取
  4. 機器學習模型效能指標評估
  5. 微調最佳模型(超引數)
  6. 在測試集上評估最佳模型
  7. 解釋模型結果
  8. 總結分析

 

通過完成所有流程,我們將看到每個步驟之間是怎麼聯絡起來的,以及如何在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 Lab的TPOThttps://epistasislab.github.io/tpot/等專案正試圖使用遺傳演算法等方法優化超引數搜尋。有興趣的可以瞭解一下。本專案中將使用Scikit-Learn實現最優超引數選取。

 

本篇主要介紹了機器學習模型效能指標評估部分模型超引數調整概念,下篇將詳細介紹模型超引數調整模型在測試集上的評估。

 


相關文章