每個數據科學家每天都要處理成噸的數據,而他們60%~70%的時間都在進行數據清洗和數據格式調整,將原始數據轉變為可以用機器學習所識別的形式。本文主要集中在數據清洗后的過程,也就是機器學習的通用框架。這個框架是我在參加了百余場機器學習競賽后的一個總結。盡管這個框架是非常籠統和概括的,但是絕對能發揮強大的作用,仍然可以在專業人員的運用下變成復雜、高效的方法。
整個過程使用Python來實現。
數據
在用機器學習的方法之前,我們應該先把數據轉變為表格的形式,這個過程是最耗時、最復雜的。我們用下圖來表示這一過程。

這一過程也就是將原始數據的所有的變量量化,進一步轉變為含數據(Data)和標簽(Labels)的數據框形式。這樣處理過的數據就可以用來機器學習建模了。數據框形式的數據是機器學習和數據挖掘中最為通用的數據表現形式,它的行是數據抽樣得到的樣本,列代表數據的標簽Y和特征X,其中標簽根據我們要研究的問題不同,有可能是一列或多列。
標簽的類型
根據我們要研究的問題,標簽的類型也不一:
- 單列0-1值(二分類問題,一個樣本只屬于一類并且一共只有兩類)
- 單列連續值(單回歸問題,要預測的值只有一個)
- 多列0-1值(多分類問題,同樣是一個樣本只屬于一類但是一共有多類)
- 多列連續值(多回歸問題,能夠預測多個值)
- 多標簽(多標簽分類問題,但是一個樣本可以屬于多類)
評價指標
對于多個機器學習方法,我們必須找到一個評價指標來衡量它們的好壞。比如一個二元分類的問題我們一般選用AUC ROC或者僅僅用AUC曲線下面的面積來衡量。在多標簽和多分類問題上,我們選擇交叉熵或對數損失函數。在回歸問題上我們選擇常用的均方誤差(MSE)。
Python庫
在安裝機器學習的幾個庫之前,應該安裝兩個基礎庫:numpy和scipy。
- Pandas 處理數據最強大的庫
- scikit-learn 涵蓋機器學習幾乎所有方法的庫
- xgboost 優化了傳統的梯度提升算法
- keras 神經網絡
- matplotlib用來作圖的庫
- tpdm 顯示過程
機器學習框架
2015年我想出了一個自動式機器學習的框架,直到今天還在開發階段但是不久就會發布,本文就是以這個框架作為基礎的。下圖展示了這個框架:

上面展示的這個框架里面,粉紅色的線就是一些通用的步驟。在處理完數據并把數據轉為數據框格式后,我們就可以進行機器學習過程了。
確定問題
確定要研究的問題,也就是通過觀察標簽的類別確定究竟是分類還是回歸問題。
劃分樣本
第二步是將所有的樣本劃分為訓練集(training data)和驗證集(validation data)。過程如下:

劃分樣本的這一過程必須要根據標簽來做。比如對于一個類別不平衡的分類問題,必須要用分層抽樣的方法,比如每種標簽抽多少,這樣才能保證抽出來的兩個樣本子集分布類似。在Python中,我們可以用scikit-learn輕松實現。

對于回歸問題,那么一個簡單的K折劃分就足夠了。但是仍然有一些復雜的方法可以使得驗證集和訓練集標簽的分布接近,這個問題留給讀者作為練習。

上面我用了樣本全集中的10%作為驗證集的規模,當然你可以根據你的樣本量做相應的調整。
劃分完樣本以后,我們就把這些數據放在一邊。接下來我們使用的任何一種機器學習的方法都要先在訓練集上使用然后再用驗證集檢驗效果。驗證集和訓練集永遠都不能摻和在一起。這樣才能得到有效的評價得分,否則將會導致過擬合的問題。
識別特征
一個數據集總是帶有很多的變量(variables),或者稱之為特征(features),他們對應著數據框的維度。一般特征的值有三種類型:數值變量、屬性變量和文字變量。我們用經典的泰坦尼克號數據集來示例。

在這里生還(survival)就是標簽,船艙等級(pclass)、性別(sex)和登船港口(embarked)是屬性變量。而像年齡(age)、船上兄弟姐妹數量(sibsp)、船上父母孩子數量(parch)是數值變量。而姓名(name)這種文字變量我們認為這和生還與否沒什么關系,所以我們決定不考慮。
首先處理數值型變量,這些變量幾乎不需要任何的處理,常見的方式是正規化(normalization)。
處理屬性變量通常有兩步:
- 把屬性變量轉變為標簽

- 把標簽轉變為二元數值
由于泰坦尼克號數據集沒有很好的文字變量來示范,那么我們就制定一個通用的規則來處理文字變量。把所有的文字變量組合到一起,然后用某種算法來處理并轉變為數字。

我們可以用
CountVectorizer
或者TfidfVectorizer
來實現


一般來說第二種方法往往比較優越,下面代碼框中所展示的參數長期以來都取得了良好的效果。

如果你對訓練集數據采用了上述處理方式,那么也要保證對驗證及數據做相同處理。

特征融合
特征融合是指將不同的特征融合,要區別對待密集型變量和稀疏型變量。


當我們把特征融合好以后,可以開始機器學習的建模過程了,在這里我們都是選擇以決策樹為基學習器的集成算法,主要有:
- RandomForestClassifier
- RandomForestRegressor
- ExtraTreesClassifier
- ExtraTreesRegressor
- XGBClassifier
- XGBRegressor
但是不能直接把沒有經過規范化的數值變量直接用線性模型擬合,可以用scikitlearn里面的規范化(Normalized)和標準化(StandardScaler)命令分別對密集和稀疏的數據進行相應的處理。
特征降維和特征選擇
如果以上方式處理后的數據可以產生一個優秀的模型,那就可以直接進行參數調整了。如果不行則還要繼續進行特征降維和特征選擇。降維的方法有以下幾種:

簡單起見,這里不考慮LDA和QDA。對于高維數據來說,PCA是常用的降維方式,對于圖像數據一般我們選用1015組主成分,當然如果模型效果會提升的話也可以選擇更多的主成分。對于其他類型的數據我們一般選擇5060個主成分。

文字變量轉變為稀疏矩陣后進行奇異值分解,奇異值分解對應scikit learn庫中的TruncatedSVD語句。

一般在TF-IDF中SVD主成分的數目大約在120~200之間,但是也可以采用更多的成分,但是相應的計算成本也會增加。
在特征降維之后我們可以進行建模的訓練過程了,但是有的時候如果這樣降維后的結果仍不理想,可以進行特征選擇:

特征選擇也有很多實用的方法,比如說常用的向前或向后搜索。那就是一個接一個地把特征加入模型訓練,如果加入一個新的特征后模型效果不好,那就不加入這一特征。直到選出最好的特征子集。對于這種方法有一個提升的方式是用AUC作為評價指標,當然這個提升也不是盡善盡美的,還是需要實際應用進行改善和調整的。
還有一種特征選擇的方式是在建模的過程中就得到了最佳特征子集。比如我們可以觀察logit模型的系數或者擬合一個隨機森林模型從而直接把這些甄選后的特征用在其它模型中。

在上面的處理中應該選擇一個小的estimator數目這樣不會導致過擬合。還可以用梯度提升算法來進行特征選擇,在這里我們建議用xgboost的庫而不是sklearn庫里面的梯度提升算法,因為前者速度快且有著更好的延展性。

對于稀疏的數據集我們可以用隨機森林、xgboost或卡方等方式來進行特征選擇。下面的例子中我們用了卡方的方法選擇了20個特征出來。當然這個參數值20也是可以進一步優化的。

同樣,以上我們用的所有方法都要記錄儲存用以交叉驗證。
模型選擇和參數調整
一般而言,常用的機器學習模型有以下幾種,我們將在這些模型中選擇最好的模型:
- 分類問題
- 隨機森林
- 梯度提升算法(GBM)
- Logistic 回歸
- 樸素貝葉斯分類器
- 支持向量機
- k臨近分類器
- 回歸問題
- 隨機森林
- 梯度提升算法(GBM)
- 線性回歸
- 嶺回歸
- Lasso
- 支持向量回歸
下表中展示了每種模型分別需要優化的參數,這其中包含的問題太多太多了。究竟參數取什么值才最優,很多人往往有經驗但是不會甘愿把這些秘密分享給別人。但是在這里我會把我的經驗跟大家分享。

RS*是指沒有一個確切的值提供給大家。
在我看來上面的這些模型基本會完爆其他的模型,當然這只是我的一家之言。下面是上述過程的一個總結,主要是強調一下要保留訓練的結果用來給驗證集驗證,而不是重新用驗證集訓練!


在我長時間的實踐過程中,我發現這些總結出來的規則和框架還是很有用的,當然在一些極其復雜的工作中這些方法還是力有不逮。生活從來不會完美,我們只能盡自身所能去優化,機器學習也是一樣。

原文作者:Abhishek Thakur
原文鏈接:http://blog.kaggle.com/2016/07/21/approaching-almost-any-machine-learning-problem-abhishek-thakur/?sukey=3997c0719f151520eec92d4e7022d429d473ec41dadc46d670acc94d1f94abd4231fd776bc3c18126eea39e6b5a67350
譯者:Cup