解決機(jī)器學(xué)習(xí)問(wèn)題有通法!看這一篇就夠了!
作者:Abhishek Thakur
編譯:Cathy,黃文暢,姜范波,寒小陽(yáng)
一、前言
本文由Searchmetrics公司高級(jí)數(shù)據(jù)科學(xué)家Abhishek Thakur提供。
一個(gè)中等水平的數(shù)據(jù)科學(xué)家每天都要處理大量的數(shù)據(jù)。一些人說(shuō)超過(guò)60%到70%的時(shí)間都用于數(shù)據(jù)清理、數(shù)據(jù)處理及格式轉(zhuǎn)化,以便于在之后應(yīng)用機(jī)器學(xué)習(xí)模型。這篇文章的重點(diǎn)便在后者—— 應(yīng)用機(jī)器學(xué)習(xí)模型(包括預(yù)處理的階段)。此文討論到的內(nèi)容來(lái)源于我參加的過(guò)的數(shù)百次的機(jī)器學(xué)習(xí)競(jìng)賽。請(qǐng)大家注意這里討論的方法是大體上適用的,當(dāng)然還有很多被專業(yè)人士使用的非常復(fù)雜的方法。
接下來(lái)會(huì)使用到python。
二、數(shù)據(jù)
在應(yīng)用機(jī)器學(xué)習(xí)模型之前,所有的數(shù)據(jù)都必須轉(zhuǎn)換為表格形式。如下圖所示,這個(gè)過(guò)程是最耗時(shí)、最困難的部分。
轉(zhuǎn)換完成之后,便可以將這些表格數(shù)據(jù)灌入機(jī)器學(xué)習(xí)模型。表格數(shù)據(jù)是在機(jī)器學(xué)習(xí)或是數(shù)據(jù)挖掘中最常見(jiàn)的數(shù)據(jù)表示形式。我們有一個(gè)數(shù)據(jù)表,x軸是樣本數(shù)據(jù),y軸是標(biāo)簽。標(biāo)簽可以是單列可以是多列,取決于問(wèn)題的形式。我們會(huì)用X表示數(shù)據(jù),y表示標(biāo)簽。
1. 標(biāo)簽的種類
標(biāo)簽會(huì)定義你要解決何種問(wèn)題,有不同的問(wèn)題類型。例如:
- 單列,二進(jìn)制值(分類問(wèn)題,一個(gè)樣本僅屬于一個(gè)類,并且只有兩個(gè)類)
- 單列,實(shí)數(shù)值(回歸問(wèn)題,只預(yù)測(cè)一個(gè)值)
- 多列,二進(jìn)制值(分類問(wèn)題,一個(gè)樣本屬于一個(gè)類,但有兩個(gè)以上的類)
- 多列,實(shí)數(shù)值(回歸問(wèn)題,多個(gè)值的預(yù)測(cè))
- 多個(gè)標(biāo)簽(分類問(wèn)題,一個(gè)樣本可以屬于幾個(gè)類)
2. 評(píng)估指標(biāo)
對(duì)于任何類型的機(jī)器學(xué)習(xí)問(wèn)題,我們都一定要知道如何評(píng)估結(jié)果,或者說(shuō)評(píng)估指標(biāo)和目的是什么。舉例來(lái)說(shuō),對(duì)于不均衡的二進(jìn)制分類問(wèn)題,我們通常選擇受試者工作特征曲線下面積(ROC AUC或簡(jiǎn)單的AUC);對(duì)于多標(biāo)簽或多類別的分類問(wèn)題,我們通常選擇分類交叉熵或多類對(duì)數(shù)損失;對(duì)于回歸問(wèn)題,則會(huì)選擇均方差。
我不會(huì)再深入的講解不同的評(píng)估指標(biāo),因?yàn)楦鶕?jù)問(wèn)題的不同會(huì)有很多不同的種類。
3. 庫(kù)
開(kāi)始嘗試機(jī)器學(xué)習(xí)庫(kù)可以從安裝最基礎(chǔ)也是最重要的開(kāi)始,像numpy和scipy。
- 查看和執(zhí)行數(shù)據(jù)操作:pandas(http://pandas.pydata.org/)
- 對(duì)于各種機(jī)器學(xué)習(xí)模型:scikit-learn(http://scikit-learn.org/stable/)
- 最好的gradient boosting庫(kù):xgboost(https://github.com/dmlc/xgboost)
- 對(duì)于神經(jīng)網(wǎng)絡(luò):keras(http://keras.io/)
- 數(shù)據(jù)繪圖:matplotlib(http://matplotlib.org/)
- 監(jiān)視進(jìn)度:tqdm(https://pypi.python.org/pypi/tqdm)
Anaconda操作簡(jiǎn)單而且?guī)湍銣?zhǔn)備好了這些,可是我沒(méi)有使用,因?yàn)槲伊?xí)慣自己配置和自由使用。當(dāng)然,決策在你手中。
4. 機(jī)器學(xué)習(xí)總體框架
2015起,我開(kāi)始制作一個(gè)自動(dòng)機(jī)器學(xué)習(xí)框架,還在完善過(guò)程中,很快就會(huì)發(fā)布。下圖所示的框架圖就是這篇文章中將會(huì)提到的基礎(chǔ)框架:
圖片來(lái)源:
A. Thakur and A. Krohn-Grimberghe, AutoCompete: A Framework for Machine Learning Competitions, AutoML Workshop, International Conference on Machine Learning 2015
上面的框架圖中,粉色的線代表最常用的路徑。結(jié)束提取數(shù)據(jù)并將其轉(zhuǎn)化為表格形式,我們就可以開(kāi)始建造機(jī)器學(xué)習(xí)模型了。
第一步是識(shí)別(區(qū)分)問(wèn)題。這個(gè)可以通過(guò)觀察標(biāo)簽解決。你一定要知道這個(gè)問(wèn)題是二元分類,還是多種類或多標(biāo)簽分類,還是一個(gè)回歸問(wèn)題。當(dāng)識(shí)別了問(wèn)題之后,就可以把數(shù)據(jù)分成訓(xùn)練集和測(cè)驗(yàn)集兩個(gè)部分。如下圖所示。
將數(shù)據(jù)分成訓(xùn)練集和驗(yàn)證集“必須”根據(jù)標(biāo)簽進(jìn)行。遇到分類問(wèn)題,使用分層分割就對(duì)了。在Python中,用scikit-learn很容易就做到了。
遇到回歸問(wèn)題,一個(gè)簡(jiǎn)單的K-Fold分割就可以了。當(dāng)然,也還有很多復(fù)雜的方法能夠在維持訓(xùn)練集和驗(yàn)證集原有分布的同時(shí)將數(shù)據(jù)分割開(kāi)來(lái)。這個(gè)就留給讀者們自己去練習(xí)啦。
相關(guān)閱讀: Startup Lessons: This Is Why You Need To Move Quickly
在以上的例子中我選擇用全數(shù)據(jù)的10%作為驗(yàn)證集,當(dāng)然你可以根據(jù)手中具體的數(shù)據(jù)決定取樣的大小。
分好數(shù)據(jù)之后,就可以把它放在一邊不要碰了。任何作用于訓(xùn)練集的運(yùn)算都必須被保存并應(yīng)用于驗(yàn)證集。驗(yàn)證集無(wú)論如何都不可以和訓(xùn)練集混為一談。因?yàn)榛斓揭黄鹬箅m然回到一個(gè)讓用戶滿意的評(píng)估指標(biāo)值,但卻會(huì)因?yàn)槟P瓦^(guò)擬合而不能使用。
下一步是識(shí)別數(shù)據(jù)中不同的變量。通常有三種變量:數(shù)值變量、分類變量和文本變量。讓我們用很受歡迎的關(guān)于泰坦尼克號(hào)的數(shù)據(jù)集來(lái)舉個(gè)例子。
(https://www.kaggle.com/c/titanic/data).
在這里,“survival”(生存)就是標(biāo)簽。在前一個(gè)步驟中我們已經(jīng)把標(biāo)簽從訓(xùn)練集中去掉了。接下來(lái),有pclass,sex, embarked變量這些變量由不同的級(jí)別,因此是分類變量。像age, sibsp, parch等就是數(shù)值變量。Name是一個(gè)含有文本的變量,但我不認(rèn)為它對(duì)預(yù)測(cè)是否生存有用。
先把數(shù)值變量分離出來(lái)。這些變量不需要任何形式的處理,所以我們可以開(kāi)始對(duì)其歸一并應(yīng)用機(jī)器學(xué)習(xí)模型。
處理分類變量有兩種變法:
請(qǐng)記住在應(yīng)用OneHotEncoder之前要用LabelEncoder把分類變量轉(zhuǎn)化為數(shù)值變量。
既然泰坦尼克數(shù)據(jù)里面沒(méi)有好的關(guān)于文本變量的例子,我們就自己制定一個(gè)處理文本變量的一般規(guī)則。我們可以把所有文本變量整合在一起然后用一些文本分析的算法把他們轉(zhuǎn)換成數(shù)字。
文本變量可以如下這樣整合:
然后就可以應(yīng)用CoutVectorizer或者TfidfVectorizer在上面啦:
或者
TfidfVectorizer大多數(shù)時(shí)候比單純計(jì)數(shù)效果要好。下面的參數(shù)設(shè)置在大多數(shù)時(shí)候都有很好的結(jié)果。
如果你在訓(xùn)練集上做了向量化處理(或者其他操作),請(qǐng)確保將其(相應(yīng)的處理)轉(zhuǎn)存在硬盤(pán)上,以便以后在驗(yàn)證集上應(yīng)用。
接下來(lái),就是堆疊器模塊。堆疊器模塊不是模型堆疊而是特征堆疊。上述處理步驟之后得到的不同特征可以通過(guò)堆疊器模塊整合到一起。
你可以水平地堆疊所有的特征,然后通過(guò)使用numpy hstack或sparse hvstack進(jìn)行進(jìn)一步處理,具體取決于是否具有密集或稀疏特征。
也可以通過(guò)FeatureUnion模塊實(shí)現(xiàn),以防萬(wàn)一有其他處理步驟,如PCA或特征選擇(我們將在后文提到分解和特征選擇)。
一旦我們把特征找齊了,就可以開(kāi)始應(yīng)用機(jī)器學(xué)習(xí)模型了。在這個(gè)階段,你只需用到基于樹(shù)的模型,包括:
- 隨機(jī)森林分類器
- 隨機(jī)森林回歸器
- ExtraTrees分類器
- ExtraTrees回歸器
- XGB分類器
- XGB回歸器
由于沒(méi)有歸一化,我們不能將線性模型應(yīng)用到上述特征上。為了能夠應(yīng)用線性模型,可以從scikit-learn中使用Normalizer或者StandardScaler。
這些歸一化的方法僅限于密集特征,對(duì)稀疏特征,結(jié)果差強(qiáng)人意。當(dāng)然,也可以在不使用平均值(參數(shù):with_mean=False)的情況下對(duì)稀疏矩陣使用StandardScaler。
如果以上步驟得到了一個(gè)“好的”模型,我們就可以進(jìn)一步做超參數(shù)的優(yōu)化了。得不到的情況下,可以做如下步驟以改進(jìn)模型。
接下來(lái)的步驟包括分解模型:
簡(jiǎn)潔起見(jiàn),我們跳過(guò)LDA和QDA轉(zhuǎn)化。對(duì)高維數(shù)據(jù),一般而言,PCA可以用來(lái)分解數(shù)據(jù)。對(duì)圖片而言,從10-15個(gè)組分起始,在結(jié)果質(zhì)量持續(xù)改進(jìn)的前提下,逐漸增加組分?jǐn)?shù)量。對(duì)其它的數(shù)據(jù)而言,我們挑選50-60個(gè)組分作為起點(diǎn)(對(duì)于數(shù)字型的數(shù)據(jù),只要我們能夠處理得了,就不用PCA)
對(duì)文本型的數(shù)據(jù),把文本轉(zhuǎn)化為稀疏矩陣后,進(jìn)行奇異值分解(Singular Value Decomposition (SVD)),可以在scikit-learn中找到一個(gè)SVD的變異版叫做TruncatedSVD。
一般對(duì)TF-IDF有效的奇異值分解成分(components)是120-200個(gè)。更多的數(shù)量可能效果會(huì)有所改進(jìn)但不是很明顯,而計(jì)算機(jī)資源耗費(fèi)卻很多。
在進(jìn)一步評(píng)價(jià)模型的性能以后,我們可以再做數(shù)據(jù)集的縮放,這樣就可以評(píng)價(jià)線性模型了。歸一化或者縮放后的特征可以用在機(jī)器學(xué)習(xí)模型上或者特征選擇模塊里。
特征選擇有很多方法。最常用的方法之一是貪心算法選擇(正向或反向)。具體而言,選擇一個(gè)特征,在一個(gè)固定的評(píng)價(jià)矩陣上訓(xùn)練一個(gè)模型,評(píng)價(jià)其性能,然后一個(gè)一個(gè)地往里面增加或移除特征,記錄每一步的模型性能。最后選擇性能得分最高時(shí)的那些特征。貪心算法和其評(píng)價(jià)矩陣的AUC的一個(gè)例子見(jiàn)鏈接:
https://github.com/abhishekkrthakur/greedyFeatureSelection。
需要注意的是,這個(gè)應(yīng)用并非完美,必須根據(jù)要求進(jìn)行修改。
其他更快的特征選擇方法包括從一個(gè)模型中選取最好的特征。我們可以根據(jù)一個(gè)邏輯回歸模型的系數(shù),或者訓(xùn)練一個(gè)隨機(jī)森林來(lái)選擇最好的特征,然后把它們用在其它的機(jī)器學(xué)習(xí)模型里。
記得把估計(jì)值或者超參數(shù)的數(shù)量控制得盡量少,這樣你才不會(huì)過(guò)擬合。
用Gradient Boosting Machine也可以實(shí)現(xiàn)特征選擇。如果能用xgboost就不要用GBM,因?yàn)榍罢咭斓枚啵蓴U(kuò)展性更好。
對(duì)稀疏數(shù)據(jù)集,也可以用隨機(jī)森林分類器/隨機(jī)森林回歸器或xgboost做特征選擇。
從正性稀疏數(shù)據(jù)集里選擇特征的其它流行方法還有基于卡方的特征選擇,scikit-learn中即可應(yīng)用。
這里,我們用卡方聯(lián)合SelectKBest的方法從數(shù)據(jù)中選擇了20個(gè)特征。這個(gè)本身也是我們改進(jìn)機(jī)器學(xué)習(xí)模型的超參數(shù)之一。
別忘了把任何中間過(guò)程產(chǎn)生的轉(zhuǎn)化體轉(zhuǎn)存起來(lái)。在驗(yàn)證集上你會(huì)要用它們來(lái)評(píng)價(jià)性能。
下一步(或者說(shuō),緊接著)主要的步驟是模型選擇+超參數(shù)優(yōu)化。
一般來(lái)說(shuō),我們用下面的算法來(lái)選擇機(jī)器學(xué)習(xí)模型:
(1) 分類
- 隨機(jī)森林
- GBM
- 邏輯回歸
- 樸素貝葉斯
- 支持向量機(jī)
- K最近鄰法
(2) 回歸
- 隨機(jī)森林
- GBM
- 線性回歸
- Ridge
- Lasso
- SVR
我需要優(yōu)化哪個(gè)參數(shù)?如何選擇最好的參數(shù)?這些是人們經(jīng)常會(huì)遇到的問(wèn)題。沒(méi)有大量數(shù)據(jù)集上不同模型+參數(shù)的經(jīng)驗(yàn),無(wú)法得到這些問(wèn)題的答案。有經(jīng)驗(yàn)的人又不愿意把他們的秘訣公之于眾。幸運(yùn)的是,我有豐富的經(jīng)驗(yàn),同時(shí)愿意分享。讓我們來(lái)看看不同模型下超參數(shù)的秘密:
RS* =不好說(shuō)合適的值是多少,在這些超參數(shù)里隨機(jī)搜索一下。
以我個(gè)人淺見(jiàn)(原文作者個(gè)人意見(jiàn)),上述的這些模型比其他模型好,無(wú)需評(píng)價(jià)其它模型。
再說(shuō)一次,記得保存這些轉(zhuǎn)化體:
然后對(duì)驗(yàn)證集做相同的操作。
上面的規(guī)則和框架對(duì)我遇到的數(shù)據(jù)集而言運(yùn)行良好。當(dāng)然,在特別復(fù)雜的情況下也失敗過(guò)。天下沒(méi)有完美的東西,我們只能在學(xué)習(xí)中不斷改進(jìn),如同機(jī)器學(xué)習(xí)一樣。
原文:
http://www.iamwire.com/2016/10/approaching-almost-any-machine-learning-problem/142291?from=groupmessage&isappinstalled=0
【本文是51CTO專欄機(jī)構(gòu)大數(shù)據(jù)文摘的原創(chuàng)譯文,微信公眾號(hào)“大數(shù)據(jù)文摘( id: BigDataDigest)”】