當前位置:
首頁 > 最新 > 機器學習演算法性能比對分析流程

機器學習演算法性能比對分析流程

寫這篇文章的初衷是受到優達學城「機器學習納米學位(進階)」課程中「finding donors」項目的啟發。主要是梳理比對不同的機器學習演算法的流程。

本文章使用的數據集是「Census Income Data Set」,來自UCI Machine Learning Repository(https://link.zhihu.com/?target=https%3A//archive.ics.uci.edu/ml/datasets/Census%2BIncome)。我們的目標是使用多種機器學習演算法預測收入,具體來說,預測一個人的收入是否超過50000美金.

本文所有代碼均在jupyter notebook上運行通過,使用的python版本是2.7.14,源代碼點擊這裡(https://link.zhihu.com/?target=https%3A//github.com/freefrog1986/ML-master-udacity/tree/master/3.%2520Supervised%2520Learning/finding_donors)。


首先,讀入需要的庫。numpy用於處理運算,pandas用於處理數據,time用於計算運行時間,display用於更好的顯示圖片。

首先我們讀入了數據集並顯示前三行,這個數據集有不同類型的特徵值,有連續值例如age,也有離散值例如workclass。

我們的目標是預測收入,也就是數據集中的income變數。下面先看一看income變數的大概情況。

income只有兩類,大於$50000和小於$50000,數據值一共有45222個樣本,我們想要預測的數據(大於$50000)佔24.78%。

注意這裡可以使用.value_counts()屬性得到某一特徵不同類別的數量。

另外值得注意的是,python中使用除法要非常小心,最好使用np.true_divide()來進行傳統意義上的除法運算。


在使用數據之前,通常要經過清理、格式化和重組等步驟——這通常被稱為預處理。幸運的是,這個數據集沒有無效或丟失的樣本。但是,需要對某些特徵進行調整。這種預處理對幾乎所有學習演算法都有很大的幫助。


首先我們來看一下如何處理數值特徵,這類數據最容易出現的問題之一就是分布的偏差和方差過大,也就是說當大部分數據分布在一個固定值周圍時,也會出現很多特別大或者特別小的值。

對於我們要處理的數據集來說capital-gain和capital-loss就是這樣的特徵。我們來畫圖看一下這兩個特徵的分布情況。

我們發現,對於"capital-gain",大部分值分布在0-20000範圍內,也有一些值分布在100000附近。而對於"capital-loss",大部分數值分布在2000附近,另外有很大一部分數值分布在0附近,這種數據分布我們稱為『偏差』。另外,我們觀察數值的分布範圍,"capital-gain"是[0, 100000], 而"capital-loss"是[0, 4000],取值範圍很大。

對於高度偏差的特徵分布,如"capital-gain"和"capital-loss",應用對數變換是很常見的做法,這樣,非常大和非常小的值就不會對演算法的性能產生負面影響。使用對數變換大大縮小了數值的範圍。但是,在應用這種轉換時必須注意:0的對數是未定義的,因此我們必須將數值轉換成大於0的值。

運行下面的代碼,對數據進行轉換並可視化結果。同樣,請注意數值的範圍及分布。

代碼首先將數據轉換為pandas.Dataframe類型,然後將特徵的取值加1後取對數,加1的作用是避免出現0值。我們發現,轉換後的分布由原來的很大的取值區間轉換為現在的[0, 12].


除了在高度偏差的特性上執行轉換之外,在數值特徵上執行某種類型的縮放也是很好的做法。縮放操作不改變特徵的分布(如上面的"capital-gain」或"capital-loss」);然而,正則化確保平等對待每個特徵。需要注意的是,一旦進行縮放,其原始形式的數據的含義將改變(例如0.301370顯然不是這個人的真實年齡),見下面的例子。

觀察結果,所有連續特徵均被轉換到[0,1]區間。

總結以上步驟:

1. 觀察所有數值特徵

2. 對高偏差的特徵進行對數轉換

3. 對所有數值特徵進行正則化

接下來我們來考慮離非數值征值,當然,我們需要將其轉換為數值特徵。一種常用的方法是使用one-hot編碼。One-hot編碼為非數值特徵的每一種可能創建一個_"dummy"_ 變數. 例如, 假設someFeature有三種可能的取值:A,B, 或C. 我們可以將其編碼為someFeature_A,someFeature_B和someFeature_C.

同樣,我們也需要對標籤"income"進行轉換。由於我們的標籤只有兩種取值("50K"), 我們可以不使用one-hot編碼,而是直接使用0或1分別代表.

下面是實戰代碼

這裡主要使用了pd.get_dummies()和LabelEncoder().fit_transform(),前者是將非數值特徵進行one-hot編碼,後者是將標籤特徵進行0,1編碼


現在所有特徵均被轉換為數值並進行了歸一化處理。接下來我們將數據集劃分為訓練集和測試集。


在這一節,我們將探索4個不同的分類器, 並決定哪一個最適合我們的數據. 其中,我們首先打造一個樸素分類器作為比對基準.


我們使用的測量指標是準確率(accuracy)和F-beta得分。

觀察標籤數據的分布不難發現,大部分人的收入沒有超過$50,000. 這種情況很容易影響準確率(accuracy)。假設我們簡單的認為所有人的收入都不超過$50,000,這樣的一個樸素分類器也會有很好的準確率!

接下來我們就先來打造這個樸素分類器。

如果讀者不熟悉這裡使用的測量指標,可以參考這篇文章(https://zhuanlan.zhihu.com/p/31832769/edit)。我們發現,即便是這樣一個簡單的模型,也可以得到準確率0.2478。

接下來就是模型選擇了,一般來說使用選擇模型從以下幾方面考慮:數據量大小,特徵值特點,模型的適用條件等等。我們以樸素貝葉斯,決策樹和支持向量機為例。

先來說說樸素貝葉斯,我們知道樸素貝葉斯基於特徵之間相互獨立的假設,所以我們數據集的特徵越是相互獨立,該模型的表現越好,另外樸素貝葉斯對於數據集的大小不敏感,所以如果數據集較小可以採用樸素貝葉斯。但是樸素貝葉斯也有缺點,一個缺點就是樸素貝葉斯的前提條件:特徵之間相互獨立,換句話說,如果不是相互獨立的話,效果就會打折扣。

再來說說決策樹,使用決策樹的好處是,我們能夠得到一套明確的篩選機制(樹結構)用於預測,如果數據的某些特徵能夠明確的代表某些類的話,那麼使用決策樹是很好的選擇。另外更多的離散值特徵也是我們可以選擇決策樹的理由之一。決策樹的缺點是比較依賴於一些關鍵特徵,如果這些關鍵特徵不能夠很好的用於分類的話,決策樹將會表現的很差。最後一個缺點是過擬合問題,決策樹的特點決定了它容易產生過擬合,所以泛化能力差也是決策樹的缺點之一。

最後說一下支持向量機,支持向量機的優點是有較強的泛化能力,因為它努力找到使不同類別之間的空隙最大化的平面,如果空隙中再出現測試數據,也可以很好的分類。但是支持向量機的缺點是太依賴於核函數。另外計算時間較長也是它的缺點。


這裡我們要打造一個訓練和預測的流程(pipeline),為什麼要這麼做?因為這樣我們就可以輕鬆的測試不同模型的性能。具體代碼見下面

實際上,我們創造了 train_predict函數,函數實現的功能就是利用輸入的模型進行訓練和和預測,並得到模型在訓練集和測試集上的測量指標(我們選用的是準確率和f-beta得分)。另外,我們還計算了每個模型的運行時間,便於後續分析。函數的輸入還包括一個變數sample_size用於控制訓練集的大小,分析不同的模型適用什麼規模的數據。


接下來我們就可以利用上面的函數來測試不同模型在我們的數據集上的表現了。

我們來分析一下結果,結果分為六組圖片,上面三組代表在訓練集的表現,下面三組代表在測試集的表現。從左到右分別是測試時間,準確率,f-beta得分。

先來分析運行時間,很明顯SVC無論在測試集還是在訓練集都是非常消耗時間的,我們發現,SVC對訓練集數據規模比較敏感,當數據集規模增加90%時,svc的運行時間增加了200倍。

再看不同的模型在測試集和訓練集上的準確率表現,首先,在訓練集,無論數據規模大小,決策樹性能優於SVC優於樸素貝葉斯且均優於我們的樸素分類器。然後在測試集上,SVC的性能表現超越了決策樹,這也是之前在模型選擇時我們提到的,決策樹容易產生過擬合,而svc的泛化能力較強。使用f-bata得分作為測量標準也發生了同樣的情況。


接下來需要考慮的是,哪個模型更加適合我們的數據集,很明顯,從運行時時間,準確率和泛化能力來看,決策樹是更優的選擇。


既然已經選定了模型,接下來就是調參數,優化模型。我們使用的方法是傳統的網格搜索(grid search),也就是設定不同的參數值,通過不斷的試驗,得到表現最好的模型。

這裡我們使用的核心函數就是GridSearchCV,該參數有三個輸入,分別是分類器,參數和測量指標,其中測量標準需要使用make_scorer(fbeta_score, beta=0.5)來生成,參數的話使用字典數據類型來表示不同的參數及其取值。

通過測試,我們得到了更好的模型參數,模型的性能得到了提升!


通常來說,不是所有的特徵對模型性能都有同樣的重要性,一般來說,一部分關鍵特徵決定了模型的大部分性能。


在scikit-learn庫中,部分機器學習演算法具有.feature_importances_屬性,通過該屬性,我們既可以得到影響演算法性能的關鍵特徵。我們以AdaBoost模型為例:

這裡展示了前5個影響最大的特徵及其影響權重。


最後,我們來看一下,如果僅使用最有影響力的5個特徵進行訓練,得到什麼結果。

結果是,模型性能下降了,但是下降的不多,也就是說,如果僅使用5個特徵值而不是13個,能得到接近的性能,大大提升了效率!


最後,通過這個案例,我們總結一下機器學習演算法性能比對分析流程:

1. 探索數據:了解數據的基本情況

2. 準備數據:對數據進行清洗,正則化等

3. 評估模型性能:根據經驗選擇比較適合模型以及測量標準進行比對分析

4. 改進結果:根據比對結果選擇最好的模型,並對其進行調參

5. 特徵選擇:考慮使用影響力較大的部分特徵

出處:https://zhuanlan.zhihu.com/p/33044332

版權申明:內容來源網路,版權歸原創者所有。除非無法確認,我們都會標明作者及出處,如有侵權煩請告知,我們會立即刪除並表示歉意。謝謝。

架構文摘

互聯網應用架構丨架構技術丨大型網站丨大數據丨機器學習

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 機器學習 的精彩文章:

生成對抗網路 GAN:讓 AI 有創造力,機器學習十年來最激動人心的點子
谷歌利用機器學習刪除了Google Play中的70萬個垃圾應用,同比2016年增加了70%

TAG:機器學習 |