解決機器學習問題有通法

大資料文摘發表於2017-09-18

前言

本文由Searchmetrics公司高階資料科學家Abhishek Thakur提供。

一箇中等水平的資料科學家每天都要處理大量的資料。一些人說超過60%到70%的時間都用於資料清理、資料處理及格式轉化,以便於在之後應用機器學習模型。這篇文章的重點便在後者—— 應用機器學習模型(包括預處理的階段)。此文討論到的內容來源於我參加的過的數百次的機器學習競賽。請大家注意這裡討論的方法是大體上適用的,當然還有很多被專業人士使用的非常複雜的方法。

接下來會使用到python。

資料

在應用機器學習模型之前,所有的資料都必須轉換為表格形式。如下圖所示,這個過程是最耗時、最困難的部分。

解決機器學習問題有通法


轉換完成之後,便可以將這些表格資料灌入機器學習模型。表格資料是在機器學習或是資料探勘中最常見的資料表示形式。我們有一個資料表,x軸是樣本資料,y軸是標籤。標籤可以是單列可以是多列,取決於問題的形式。我們會用X表示資料,y表示標籤。

標籤的種類

標籤會定義你要解決何種問題,有不同的問題型別。例如:

  • 單列,二進位制值(分類問題,一個樣本僅屬於一個類,並且只有兩個類)

  • 單列,實數值(迴歸問題,只預測一個值)

  • 多列,二進位制值(分類問題,一個樣本屬於一個類,但有兩個以上的類)

  • 多列,實數值(迴歸問題,多個值的預測)

  • 多個標籤(分類問題,一個樣本可以屬於幾個類)



評估指標

對於任何型別的機器學習問題,我們都一定要知道如何評估結果,或者說評估指標和目的是什麼。舉例來說,對於不均衡的二進位制分類問題,我們通常選擇受試者工作特徵曲線下面積(ROC AUC或簡單的AUC);對於多標籤或多類別的分類問題,我們通常選擇分類交叉熵或多類對數損失;對於迴歸問題,則會選擇均方差。

我不會再深入的講解不同的評估指標,因為根據問題的不同會有很多不同的種類。

開始嘗試機器學習庫可以從安裝最基礎也是最重要的開始,像numpy和scipy。

  • 檢視和執行資料操作:pandas(http://pandas.pydata.org/)

  • 對於各種機器學習模型:scikit-learn(http://scikit-learn.org/stable/)

  • 最好的gradient boosting庫:xgboost(https://github.com/dmlc/xgboost)

  • 對於神經網路:keras(http://keras.io/)

  • 資料繪圖:matplotlib(http://matplotlib.org/)

  • 監視進度:tqdm(https://pypi.python.org/pypi/tqdm)


Anaconda操作簡單而且幫你準備好了這些,可是我沒有使用,因為我習慣自己配置和自由使用。當然,決策在你手中。

機器學習總體框架

2015起,我開始製作一個自動機器學習框架,還在完善過程中,很快就會發布。下圖所示的框架圖就是這篇文章中將會提到的基礎框架:



解決機器學習問題有通法


圖片來源:A. Thakur and A. Krohn-Grimberghe, AutoCompete: A Framework for Machine Learning Competitions, AutoML Workshop, International Conference on Machine Learning 2015 

上面的框架圖中,粉色的線代表最常用的路徑。結束提取資料並將其轉化為表格形式,我們就可以開始建造機器學習模型了。

第一步是識別(區分)問題。這個可以透過觀察標籤解決。你一定要知道這個問題是二元分類,還是多種類或多標籤分類,還是一個迴歸問題。當識別了問題之後,就可以把資料分成訓練集和測驗集兩個部分。如下圖所示。 

解決機器學習問題有通法


將資料分成訓練集和驗證集“必須”根據標籤進行。遇到分類問題,使用分層分割就對了。在Python中,用scikit-learn很容易就做到了。

解決機器學習問題有通法


遇到迴歸問題,一個簡單的K-Fold分割就可以了。當然,也還有很多複雜的方法能夠在維持訓練集和驗證集原有分佈的同時將資料分割開來。這個就留給讀者們自己去練習啦。 

解決機器學習問題有通法


相關閱讀: Startup Lessons: This Is Why You Need To Move Quickly

在以上的例子中我選擇用全資料的10%作為驗證集,當然你可以根據手中具體的資料決定取樣的大小。 

分好資料之後,就可以把它放在一邊不要碰了。任何作用於訓練集的運算都必須被儲存並應用於驗證集。驗證集無論如何都不可以和訓練集混為一談。因為混到一起之後雖然回到一個讓使用者滿意的評估指標值,但卻會因為模型過擬合而不能使用。 

下一步是識別資料中不同的變數。通常有三種變數:數值變數、分類變數和文字變數。讓我們用很受歡迎的關於泰坦尼克號的資料集來舉個例子。 (https://www.kaggle.com/c/titanic/data).

解決機器學習問題有通法


在這裡,“survival”(生存)就是標籤。在前一個步驟中我們已經把標籤從訓練集中去掉了。接下來,有pclass,sex, embarked變數這些變數由不同的級別,因此是分類變數。像age, sibsp, parch等就是數值變數。Name是一個含有文字的變數,但我不認為它對預測是否生存有用。

先把數值變數分離出來。這些變數不需要任何形式的處理,所以我們可以開始對其歸一併應用機器學習模型。

處理分類變數有兩種變法:

  • 把分類變數轉化為標籤  

解決機器學習問題有通法

  • 把標籤轉化為二進位制變數  

解決機器學習問題有通法


請記住在應用OneHotEncoder之前要用LabelEncoder把分類變數轉化為數值變數。

既然泰坦尼克資料裡面沒有好的關於文字變數的例子,我們就自己制定一個處理文字變數的一般規則。我們可以把所有文字變數整合在一起然後用一些文字分析的演算法把他們轉換成數字。

文字變數可以如下這樣整合: 


解決機器學習問題有通法


然後就可以應用CoutVectorizer或者TfidfVectorizer在上面啦: 


解決機器學習問題有通法

或者

解決機器學習問題有通法


TfidfVectorizer大多數時候比單純計數效果要好。下面的引數設定在大多數時候都有很好的結果。

解決機器學習問題有通法


如果你在訓練集上做了向量化處理(或者其他操作),請確保將其(相應的處理)轉存在硬碟上,以便以後在驗證集上應用。

解決機器學習問題有通法


接下來,就是堆疊器模組。堆疊器模組不是模型堆疊而是特徵堆疊。上述處理步驟之後得到的不同特徵可以透過堆疊器模組整合到一起。 

解決機器學習問題有通法


你可以水平地堆疊所有的特徵,然後透過使用numpy hstack或sparse hvstack進行進一步處理,具體取決於是否具有密集或稀疏特徵。 

解決機器學習問題有通法


也可以透過FeatureUnion模組實現,以防萬一有其他處理步驟,如PCA或特徵選擇(我們將在後文提到分解和特徵選擇)。 

解決機器學習問題有通法


一旦我們把特徵找齊了,就可以開始應用機器學習模型了。在這個階段,你只需用到基於樹的模型,包括:

  • 隨機森林分類器

  • 隨機森林迴歸器

  • ExtraTrees分類器

  • ExtraTrees迴歸器

  • XGB分類器

  • XGB迴歸器


由於沒有歸一化,我們不能將線性模型應用到上述特徵上。為了能夠應用線性模型,可以從scikit-learn中使用Normalizer或者StandardScaler。

這些歸一化的方法僅限於密集特徵,對稀疏特徵,結果差強人意。當然,也可以在不使用平均值(引數:with_mean=False)的情況下對稀疏矩陣使用StandardScaler。

如果以上步驟得到了一個“好的”模型,我們就可以進一步做超引數的最佳化了。得不到的情況下,可以做如下步驟以改進模型。

接下來的步驟包括分解模型: 解決機器學習問題有通法


簡潔起見,我們跳過LDA和QDA轉化。對高維資料,一般而言,PCA可以用來分解資料。對圖片而言,從10-15個組分起始,在結果質量持續改進的前提下,逐漸增加組分數量。對其它的資料而言,我們挑選50-60個組分作為起點(對於數字型的資料,只要我們能夠處理得了,就不用PCA) 解決機器學習問題有通法

對文字型的資料,把文字轉化為稀疏矩陣後,進行奇異值分解(Singular Value Decomposition (SVD)),可以在scikit-learn中找到一個SVD的變異版叫做TruncatedSVD。 解決機器學習問題有通法

一般對TF-IDF有效的奇異值分解成分(components)是120-200個。更多的數量可能效果會有所改進但不是很明顯,而計算機資源耗費卻很多。

在進一步評價模型的效能以後,我們可以再做資料集的縮放,這樣就可以評價線性模型了。歸一化或者縮放後的特徵可以用在機器學習模型上或者特徵選擇模組裡。 解決機器學習問題有通法

特徵選擇有很多方法。最常用的方法之一是貪心演算法選擇(正向或反向)。具體而言,選擇一個特徵,在一個固定的評價矩陣上訓練一個模型,評價其效能,然後一個一個地往裡面增加或移除特徵,記錄每一步的模型效能。最後選擇效能得分最高時的那些特徵。貪心演算法和其評價矩陣的AUC的一個例子見連結: https://github.com/abhishekkrthakur/greedyFeatureSelection。 需要注意的是,這個應用並非完美,必須根據要求進行修改。

其他更快的特徵選擇方法包括從一個模型中選取最好的特徵。我們可以根據一個邏輯迴歸模型的係數,或者訓練一個隨機森林來選擇最好的特徵,然後把它們用在其它的機器學習模型裡。 解決機器學習問題有通法

記得把估計值或者超引數的數量控制得儘量少,這樣你才不會過擬合。

用Gradient Boosting Machine也可以實現特徵選擇。如果能用xgboost就不要用GBM,因為前者要快得多,可擴充套件性更好。 解決機器學習問題有通法

對稀疏資料集,也可以用隨機森林分類器/隨機森林迴歸器或xgboost做特徵選擇。

從正性稀疏資料集裡選擇特徵的其它流行方法還有基於卡方的特徵選擇,scikit-learn中即可應用。 解決機器學習問題有通法


這裡,我們用卡方聯合SelectKBest的方法從資料中選擇了20個特徵。這個本身也是我們改進機器學習模型的超引數之一。

別忘了把任何中間過程產生的轉化體轉存起來。在驗證集上你會要用它們來評價效能。

下一步(或者說,緊接著)主要的步驟是模型選擇+超引數最佳化。 

一般來說,我們用下面的演算法來選擇機器學習模型:

  • 分類

  • 隨機森林

  • GBM

  • 邏輯迴歸

  • 樸素貝葉斯

  • 支援向量機

  • K最近鄰法

  • 迴歸

  • 隨機森林

  • GBM

  • 線性迴歸

  • Ridge

  • Lasso

  • SVR

我需要最佳化哪個引數?如何選擇最好的引數?這些是人們經常會遇到的問題。沒有大量資料集上不同模型+引數的經驗,無法得到這些問題的答案。有經驗的人又不願意把他們的秘訣公之於眾。幸運的是,我有豐富的經驗,同時願意分享。讓我們來看看不同模型下超引數的秘密: 

解決機器學習問題有通法


RS* =不好說合適的值是多少,在這些超引數裡隨機搜尋一下。

以我個人淺見(原文作者個人意見),上述的這些模型比其他模型好,無需評價其它模型。

再說一次,記得儲存這些轉化體: 解決機器學習問題有通法

然後對驗證集做相同的操作。 解決機器學習問題有通法


上面的規則和框架對我遇到的資料集而言執行良好。當然,在特別複雜的情況下也失敗過。天下沒有完美的東西,我們只能在學習中不斷改進,如同機器學習一樣。

相關文章