『機器學習』—應用Sklearn機器學習的建議

作者:量化投資與機器學習優礦研究部 原文鏈接:【sklearn機器學習】——應用機器學習的建議

本文以 Andrew Ng 的《Advice for applying Machine Learning》為基礎進行拓展。

前言

以Bremen大學機器學習課程的教程為基礎的,總結了使用機器學習解決新問題的一些建議。包括:

  • 可視化數據的方法
  • 選擇一個適合當前問題的機器學習方法
  • 鑒別和解決過擬合和欠擬合問題
  • 處理大資料庫問題(注意:不是非常小的)
  • 不同損失函數的利弊

本文以 Andrew Ng 的《Advice for applying Machine Learning》為基礎。

這個筆記的目的是用一個互動的方法解釋這些觀點。有些建議是可以討論的,僅是建議,不是嚴格的規則。

翻譯參考來自『應用機器學習的建議』的學習筆記

數據集

使用 sklearn 的 make_classification 函數來生成一些簡單的玩具數據:

注意到為二分類生成了一個數據集,這個數據集包括1000個數據點,每個特徵20維。我們已經使用pandas的DataFrame類把數據和類別封裝到一個共同的數據結構中。我們來看一看前5個數據點:

通過直接查看原始特徵值,我們很難獲得該問題的任何線索,即使在這個低維的例子中。因此,有很多的提供數據的更容易視圖的方法,其中的小部分將在接下來的部分中討論。

可視化

當你接到一個新的問題,第一步幾乎都是可視化,也就是說,觀察你的數據。

Seaborn 是一個不錯的統計數據可視化包。我們使用它的一些函數來探索數據。

第一步是使用 pairplot 生成散點圖和直方圖。兩種顏色對應了兩個類別,我們使用了特徵的一個子集、僅僅使用前50個數據點來簡化問題。

基於該直方圖,我們可以看到一些特徵比其他特徵對分類更有用。特別地,特徵11和14看起來有豐富的信息量。這兩個特徵的散點圖顯示類別在二維空間中幾乎是線性可分的。要更加註意的是,特徵12和19是高度負相關的。我們可以通過使用corrplot更系統地探索相關性:

我們可以發現之前的觀察結果在這裡得到了確認:特徵11和14與類強相關(他們有豐富的信息量)。更進一步,特徵12和特徵19強負相關,特徵19和特徵14強相關。因此,有一些特徵是冗餘的。這對於有些分類器可能會出現問題,比如,樸素貝葉斯,它假設所有的特徵都是獨立的。剩下的特徵大部分都是雜訊,他們既不相互關聯,也不和類別相關。

注意到如果特徵維數較大、數據點較少的時候,數據可視化會變得更有挑戰性。

方法的選擇

一旦我們已經使用可視化方法對數據進行了探索,我們就可以開始應用機器學習了。機器學習方法數量眾多,通常很難決定先嘗試哪種方法。這個簡單的備忘單(歸功於Andreas Müller和sklearn團隊)可以幫助你為你的問題選擇一個合適的機器學習方法(供選擇的備忘錄見http://dlib.net/ml_guide.svg)

我們有了1000個樣本,要預測一個類別,並且有了標籤,那麼備忘單推薦我們首先使用LinearSVC(LinearSVC代表線性核的支持向量分類,並且對於這類特殊問題使用一個有效的演算法)。所有我們做了個試驗。LinearSVC需要選擇正則化;我們使用標準L2範數懲罰和C=10.我們分別畫出訓練分數和驗證分數的學習曲線(這個例子中分數代表準確率):

注意到訓練數據和交叉驗證數據的錯誤率有很大的差距。這意味什麼我們可能過度擬合訓練數據了!

解決過擬合

有很多方法來減少過擬合:

  • 增加訓練樣本數

可以看到當訓練數據增加時,驗證分數越來越大,差距越來越小;因此現在不再過擬合了。有很多獲得更多數據的方法,比如(a)可以儘力投資收集更多數據,(b)基於現有數據創造一些人為的數據(比如圖像旋轉,平移,扭曲),或者(c)加入人工雜訊。如果以上的這些方法都不可行,就不可能獲得更多的數據,我們或者可以

  • 減少特徵的維數 (從我們可視化中可以知道,特徵11和14是信息量最大的)

注意到,因為是手動的挑選特徵,而且在比我們給分類器更多的數據上,這有一點作弊的意味。我們可以使用自動挑選特徵:

這樣做效果非常好。在這個toy數據集上,特徵選擇是簡單的。應該注意到特徵選擇只是減少模型複雜度的一個特殊種類。其他的方法是:(a)減少線性回歸多項式模型的次數,(b)減少人工神經網路節點的個數/層數,(c)增加RBF核的帶寬等等。

仍然有一個問題:為什麼分類器不能自動的識別有用的特徵?首先讓我們轉向另一種選擇,來減少過擬合:

  • 增加分類器的正則化 (減少線性SVC的C的係數)

這已經有一點點作用了。可以使用基於交叉驗證的網格搜索自動地挑選分類器的正則化:

一般說來,特徵選擇似乎更好。分類器可以自動識別有用的特徵嗎?回想一下,LinearSVC還支持L1範數懲罰,這產生了一個稀疏的解決方案。稀疏解決方案對應一個隱式的特徵選擇。讓我們來試試這個:

這看起來也很好。讓我們來探討學到的係數:

Coefficients learned: [[ 0、 0、 0、 0、 0、 0.0185801

0、 0、 0、 0.00413494、0、 1.0524147

0.01971398、0、0、0、 0、 -0.05665357、0.14106544、0 ]]

nNon-zero coefficients: [ 5 9 11 12 17 18]

大部分係數是0(對應的特徵被忽略),並且目前最大的權重在特徵11上。

不同的數據集

我們生成另外一個二分類的數據集,並且再次應用LinearSVC。

結果很不好,甚至訓練誤差都不如隨機誤差。這個可能的原因是什麼?難道上面的所有方法(更多數據,特徵選擇,增加正則化)都不奏效了嗎?

結果是:No。我們處在一個完全不同的情況:以前,訓練分數一直接近完美,我們不得不解決過擬合。這次,訓練誤差也非常低。是欠擬合。讓我們來看一看數據:

這些數據顯然不是線性可分的;更多的數據或者更少的特徵沒有用了。我們的模型錯了;因此欠擬合。

解決欠擬合

減少欠擬合的方法:

  • 使用更多或更好的特徵(到原點的距離應該有用!)

非常好!但是我們必須要花一些心思來想出這些特徵。或許分類器可以自動的做到這些?

  • 使用更複雜的模型(減少正則化或非線性核)

是的,這也可以達到滿意的效果!

更大的數據集和更高維的特徵空間

回到原始的數據集上,但是這次有更多的特徵和樣本,並且有5類。LinearSVC在這樣大小的數據集上會有一點慢;備忘單上建議使用SGDClassifier。這個分類器學習到一個線性模型(就像LinearSVC或logistic回歸),但是它在訓練中使用隨機梯度下降(就像反向傳播的人工神經網路一樣)。

SGDClassifier允許小批量掃描數據,這對於數據量太大不能放到內存中時有幫助。交叉驗證和這項技術不兼容;使用逐步驗證代替:這裡,估計器總是在訓練數據集的下一塊上進行測試(在用它進行訓練之前)。訓練之後,會再次進行測試來檢查它適應數據的能力。

這個圖告訴我們,在50個mini-batches的數據之後,我們已經不能再提高驗證數據了,因此可以停止訓練了。由於訓練分數不是很高,我們可能是欠擬合而不是過擬合。要是使用rbf核測試一下就更好了,但是SGDClassifier很不幸的不兼容核技巧。替代方法是可以使用一個多層的感知機,它也可以使用隨機梯度下降進行訓練,但是一個非線性模型,或者像備忘單建議的,使用核近似法。

現在在一個機器學習中使用的經典的解決光學字元識別的數據集上:

由1083個樣本組成的數據集,每個樣本由64個特徵組成

因此我們有1083個手寫數字(0,1,2,3,4,5)樣本,每一個樣本由8*8的4bit像素(0,16)灰度圖片組成。因此特徵的維數適中(64);但是,這64維空間的可視化是非常重要的。我們來說明不同的減少維數(至二維)方法,基於Manifold learning on handwritten digits: Locally Linear Embedding, Isomap...

已經隨機投影的二維數據的結果不是太差:

然而,有一個很著名的方法一般來說應該適合,也就是PCA(使用TruncatedSVD來實現,不需要構建協方差矩陣):

PCA給出一個更好的結果,而且在這個數據集上甚至更快。通過允許64維輸入空間到二維目標空間的非線性變換,我們可以得到更好的結果。這有很多種方法;我們這裡只介紹一種方法:t-SNE。

t-SNE唯一的不足是它需要更多的時間來計算,因此不適用於大數據集(在目前的條件下)

損失函數的選擇

損失函數的選擇也非常重要。下面是不同損失函數的說明:

不同的損失函數有不同的優勢:

  • 0-1損失是在分類問題中你實際上需要的。不幸地是,這是非凸優化問題,由於最優化問題會變得或多或少的不好解決,因此並不實用。
  • 合頁損失(使用支持向量分類)導出一個在數據中稀疏的解(由於f(x)>1,它變為0),而且對離群點比較穩健(由於f(x)to?infty,它僅僅成線性增長)。它不提供充分的校準的概率。
  • 對數損失函數(比如,在邏輯回歸中使用)導出很好的概率校準。因此,如果你不僅得到二值預測,還可以得出結果的概率,這個損失函數是一個很好的選擇。缺點是,它的解在數據空間中是不稀疏的,它比合頁損失函數更容易受到離群點的影響。
  • 指數損失函數(在Adaboost中使用)非常容易受離群點的影響(由於當f(x)to?infty時它快速增加)。它主要適用於Adaboost中,因為它在一個簡單有效的boosting演算法中有效果。
  • 感知器損失函數基本上是合頁損失函數的移動版本。合頁損失函數也懲罰非常接近邊界但是在正確一邊的點(間隔最大化準則)。另一方面,感知器損失函數只要數據點在邊界正確的一邊就可以,如果數據是線性可分就使得邊界待定,導致比間隔最大化更差的泛化性。

總結

以上我們討論了一些怎麼讓機器學習在一個新的問題上工作起來的建議。我們考慮了分類問題,回歸和聚類問題也與之類似。然而,專註於人工數據集(為了便於理解)還有點過於簡單化。在很多實際問題中,數據的收集、組織、預處理是極重要的。

歡迎關注量化投資與機器學習公眾號和 量化投資與機器學習研究部探討機器學習相關知識。

其他相關文章推薦:

【動態時間規整演算法】之股指期貨交易策略(一)

基於凱利公式的 21點 倉位管理玩法

MachineLearning-Lib 機器學習庫

python機器學習演算法速查

機器學習法選股

自學成才第八步——機器學習策略-adaboost——Jason的學習筆記

機器學習&量化投資-從入門到放棄全套筆記-LogisticRegression


推薦閱讀:

DeepLearning筆記:Linear regression 線性回歸
《An overview of gradient descent optimization algorithms》

TAG:机器学习 | 量化 | sklearn |