python 导入模型h20_【机器学习】模型融合方法概述
我理解的Kaggle比賽中提高成績(jī)主要有3個(gè)地方
特征工程
調(diào)參
模型融合
之前每次打比賽都只做了前兩部分,最后的模型融合就是簡(jiǎn)單的加權(quán)平均,對(duì)于進(jìn)階的Stacking方法一直沒(méi)嘗試,這幾天摸索了一下還是把Stacking方法給弄懂了。(本文重點(diǎn)講解Stacking,Bagging和Boosting有很多權(quán)威的好教程,所以不詳細(xì)介紹)最早的Stacking思想早些年就有論文發(fā)表,但是應(yīng)用Stacking方法到比賽中的相關(guān)文章還是少之甚少,這有兩篇https://mlwave.com/kaggle-ensembling-guide/、HUMAN ENSEMBLE LEARNING講的很棒,但是之前因?yàn)槔斫獠坏轿?#xff0c;有幾處卡住了。在@Wille?的文章如何在 Kaggle 首戰(zhàn)中進(jìn)入前 10%中Stacking只是作為一部分提到。因此決定自己寫(xiě)一篇關(guān)于模型融合的文章。本文不涉及到各個(gè)算法原理層次的深度,目的在于從宏觀上幫助理解這幾個(gè)模型融合方法。
一、Voting
模型融合其實(shí)也沒(méi)有想象的那么高大上,從最簡(jiǎn)單的Voting說(shuō)起,這也可以說(shuō)是一種模型融合。假設(shè)對(duì)于一個(gè)二分類問(wèn)題,有3個(gè)基礎(chǔ)模型,那么就采取投票制的方法,投票多者確定為最終的分類。
二、Averaging
對(duì)于回歸問(wèn)題,一個(gè)簡(jiǎn)單直接的思路是取平均。稍稍改進(jìn)的方法是進(jìn)行加權(quán)平均。權(quán)值可以用排序的方法確定,舉個(gè)例子,比如A、B、C三種基本模型,模型效果進(jìn)行排名,假設(shè)排名分別是1,2,3,那么給這三個(gè)模型賦予的權(quán)值分別是3/6、2/6、1/6
這兩種方法看似簡(jiǎn)單,其實(shí)后面的高級(jí)算法也可以說(shuō)是基于此而產(chǎn)生的,Bagging或者Boosting都是一種把許多弱分類器這樣融合成強(qiáng)分類器的思想。
三、Bagging
Bagging就是采用有放回的方式進(jìn)行抽樣,用抽樣的樣本建立子模型,對(duì)子模型進(jìn)行訓(xùn)練,這個(gè)過(guò)程重復(fù)多次,最后進(jìn)行融合。大概分為這樣兩步:重復(fù)K次
有放回地重復(fù)抽樣建模
訓(xùn)練子模型
2.模型融合
分類問(wèn)題:voting
回歸問(wèn)題:average
Bagging算法不用我們自己實(shí)現(xiàn),隨機(jī)森林就是基于Bagging算法的一個(gè)典型例子,采用的基分類器是決策樹(shù)。R和python都集成好了,直接調(diào)用。
四、Boosting
Bagging算法可以并行處理,而B(niǎo)oosting的思想是一種迭代的方法,每一次訓(xùn)練的時(shí)候都更加關(guān)心分類錯(cuò)誤的樣例,給這些分類錯(cuò)誤的樣例增加更大的權(quán)重,下一次迭代的目標(biāo)就是能夠更容易辨別出上一輪分類錯(cuò)誤的樣例。最終將這些弱分類器進(jìn)行加權(quán)相加。引用加州大學(xué)歐文分校Alex Ihler教授的兩頁(yè)P(yáng)PT
同樣地,基于Boosting思想的有AdaBoost、GBDT等,在R和python也都是集成好了直接調(diào)用。
PS:理解了這兩點(diǎn),面試的時(shí)候關(guān)于Bagging、Boosting的區(qū)別就可以說(shuō)上來(lái)一些,問(wèn)Randomfroest和AdaBoost的區(qū)別也可以從這方面入手回答。也算是留一個(gè)小問(wèn)題,隨機(jī)森林、Adaboost、GBDT、XGBoost的區(qū)別是什么?
五、Stacking
Stacking方法其實(shí)弄懂之后應(yīng)該是比Boosting要簡(jiǎn)單的,畢竟小幾十行代碼可以寫(xiě)出一個(gè)Stacking算法。我先從一種“錯(cuò)誤”但是容易懂的Stacking方法講起。
Stacking模型本質(zhì)上是一種分層的結(jié)構(gòu),這里簡(jiǎn)單起見(jiàn),只分析二級(jí)Stacking.假設(shè)我們有3個(gè)基模型M1、M2、M3。
1. 基模型M1,對(duì)訓(xùn)練集train訓(xùn)練,然后用于預(yù)測(cè)train和test的標(biāo)簽列,分別是P1,T1
對(duì)于M2和M3,重復(fù)相同的工作,這樣也得到P2,T2,P3,T3。
2. 分別把P1,P2,P3以及T1,T2,T3合并,得到一個(gè)新的訓(xùn)練集和測(cè)試集train2,test2.
3. 再用第二層的模型M4訓(xùn)練train2,預(yù)測(cè)test2,得到最終的標(biāo)簽列。
Stacking本質(zhì)上就是這么直接的思路,但是這樣肯定是不行的,問(wèn)題在于P1的得到是有問(wèn)題的,用整個(gè)訓(xùn)練集訓(xùn)練的模型反過(guò)來(lái)去預(yù)測(cè)訓(xùn)練集的標(biāo)簽,毫無(wú)疑問(wèn)過(guò)擬合是非常非常嚴(yán)重的,因此現(xiàn)在的問(wèn)題變成了如何在解決過(guò)擬合的前提下得到P1、P2、P3,這就變成了熟悉的節(jié)奏——K折交叉驗(yàn)證。我們以2折交叉驗(yàn)證得到P1為例,假設(shè)訓(xùn)練集為4行3列
將其劃分為2部分
用traina訓(xùn)練模型M1,然后在trainb上進(jìn)行預(yù)測(cè)得到preb3和pred4
在trainb上訓(xùn)練模型M1,然后在traina上進(jìn)行預(yù)測(cè)得到pred1和pred2
然后把兩個(gè)預(yù)測(cè)集進(jìn)行拼接
對(duì)于測(cè)試集T1的得到,有兩種方法。注意到剛剛是2折交叉驗(yàn)證,M1相當(dāng)于訓(xùn)練了2次,所以一種方法是每一次訓(xùn)練M1,可以直接對(duì)整個(gè)test進(jìn)行預(yù)測(cè),這樣2折交叉驗(yàn)證后測(cè)試集相當(dāng)于預(yù)測(cè)了2次,然后對(duì)這兩列求平均得到T1。
或者直接對(duì)測(cè)試集只用M1預(yù)測(cè)一次直接得到T1。
P1、T1得到之后,P2、T2、P3、T3也就是同樣的方法。理解了2折交叉驗(yàn)證,對(duì)于K折的情況也就理解也就非常順利了。所以最終的代碼是兩層循環(huán),第一層循環(huán)控制基模型的數(shù)目,每一個(gè)基模型要這樣去得到P1,T1,第二層循環(huán)控制的是交叉驗(yàn)證的次數(shù)K,對(duì)每一個(gè)基模型,會(huì)訓(xùn)練K次最后拼接得到P1,取平均得到T1。這下再把@Wille博文中的那張圖片放出來(lái)就很容易看懂了。
該圖是一個(gè)基模型得到P1和T1的過(guò)程,采用的是5折交叉驗(yàn)證,所以循環(huán)了5次,拼接得到P1,測(cè)試集預(yù)測(cè)了5次,取平均得到T1。而這僅僅只是第二層輸入的一列/一個(gè)特征,并不是整個(gè)訓(xùn)練集。再分析作者的代碼也就很清楚了。也就是剛剛提到的兩層循環(huán)。
python實(shí)現(xiàn)
用了一個(gè)泰坦尼克號(hào)的嘗試了一下代碼,從頭到尾都是可以運(yùn)行的。代碼放在Github,針對(duì)其中一段關(guān)鍵的稍作分析
def get_oof(clf, x_train, y_train, x_test):
oof_train = np.zeros((ntrain,))
oof_test = np.zeros((ntest,))
oof_test_skf = np.empty((NFOLDS, ntest)) #NFOLDS行,ntest列的二維array
for i, (train_index, test_index) in enumerate(kf): #循環(huán)NFOLDS次
x_tr = x_train[train_index]
y_tr = y_train[train_index]
x_te = x_train[test_index]
clf.fit(x_tr, y_tr)
oof_train[test_index] = clf.predict(x_te)
oof_test_skf[i, :] = clf.predict(x_test) #固定行填充,循環(huán)一次,填充一行
oof_test[:] = oof_test_skf.mean(axis=0) #axis=0,按列求平均,最后保留一行
return oof_train.reshape(-1, 1), oof_test.reshape(-1, 1) #轉(zhuǎn)置,從一行變?yōu)橐涣?/p>
這里只實(shí)現(xiàn)了針對(duì)一個(gè)基模型做K折交叉驗(yàn)證,因?yàn)镻1和T1都是多行一列的結(jié)構(gòu),這里是先存儲(chǔ)為一行多列,最后進(jìn)行轉(zhuǎn)置。
但是Stacking方法其實(shí)在R中也有集成好的可以調(diào)用。
caretEnsemble包下的caretStack()方法
關(guān)鍵代碼如下:
algorithmList
stackControl
stack.glm
有一篇博文講的比較詳細(xì)
h2o包的h2o.stack()方法
關(guān)鍵代碼如下:
nfolds
glm1
training_frame = train,
nfolds = nfolds,
fold_assignment = "Modulo",
keep_cross_validation_predictions = TRUE)
gbm1
training_frame = train,
seed = 1,
nfolds = nfolds,
fold_assignment = "Modulo",
keep_cross_validation_predictions = TRUE)
rf1
training_frame = train,
seed = 1,
nfolds = nfolds,
fold_assignment = "Modulo",
keep_cross_validation_predictions = TRUE)
dl1
training_frame = train,
nfolds = nfolds,
fold_assignment = "Modulo",
keep_cross_validation_predictions = TRUE)
models
metalearner
stack
response_frame = train[,y],
metalearner = metalearner,
seed = 1,
keep_levelone_data = TRUE)
# Compute test set performance:
perf
詳情見(jiàn)h2o的Github網(wǎng)站
最后放一張H2O分享的圖片總結(jié)一下
總結(jié)
以上是生活随笔為你收集整理的python 导入模型h20_【机器学习】模型融合方法概述的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: k近邻回归算法python_K近邻算法用
- 下一篇: python中all函数的用法_pyth