集成学习-Bagging原理与实现 西瓜书
Bagging簡介
Bagging是并行式集成學(xué)習(xí)的最著名代表,名字是由Bootstrap AGGregatING縮寫而來,看到Bootstrap我們就會聯(lián)想到boostrap的隨機模擬法和它對應(yīng)的樣本獲取方式,它是基于自助采樣法(Boostrap sampleing),Bagging也是同理.給定包含m個樣本的數(shù)據(jù)集,先隨機抽取一個樣本放入采樣集中,再把該樣本放回,使得下次采樣時該樣本仍有機會被選中,這樣經(jīng)過m次采樣,我們便從原始是數(shù)據(jù)集中抽取樣本得到一個數(shù)據(jù)量同為m的數(shù)據(jù)集.說簡單一點就是統(tǒng)計里的有放回抽樣,且每個樣本被抽取的概率相同,均為總樣本數(shù)分之一.
1)樣本抽取方式
假設(shè)一個樣本被抽取的概率是1/m,有:
????????????????????????????????????????????????????????????????????????
意味著抽樣次數(shù)足夠大時,一個樣本不被抽到的概率為36.8%,由此可知,初始樣本約有63.2%的樣本出現(xiàn)在采樣集中.這樣我們可以采樣T次,從而得到T個含m個訓(xùn)練樣本的采樣集,基于每個訓(xùn)練集樣本訓(xùn)練一個學(xué)習(xí)器,最后結(jié)合這些學(xué)習(xí)器的結(jié)果,預(yù)測總結(jié)果,這就是Bagging的大致實現(xiàn)過程,針對最后的預(yù)測,Bagging一般采取投票法,若票數(shù)相同,則最簡單的方法是是隨機選擇一個,當(dāng)然也可以進一步考察學(xué)習(xí)器的投票置信度,或者使用加權(quán)投票法等處理最終結(jié)果.
2)時間復(fù)雜度
這里基學(xué)習(xí)器可以選擇DT,LR,NB,SVM,神經(jīng)網(wǎng)絡(luò)等等,假定基學(xué)習(xí)期的時間復(fù)雜度為O(m),則bagging的復(fù)雜度大約為T(O(m)+O(s)),考慮到采樣與投票的平均過程復(fù)雜度O(s)很小,而T通常是一個不太大的常數(shù),所以Bagging的集成與直接使用基學(xué)習(xí)器算法訓(xùn)練一個學(xué)習(xí)器的時間復(fù)雜度同階,這說明Bagging是一個很高效的集成學(xué)習(xí)算法,另外,與AdaBoost只適用于二分類任務(wù)不同,Bagging可以用于多分類,回歸的任務(wù).
3)優(yōu)缺點
Bagging的個優(yōu)點是對泛化性能的估計,這得益于自助采樣法,由于訓(xùn)練只使用了63.2%的樣本,因此剩下約36.8%的樣本可當(dāng)做測試集來對泛化性能進行‘包外估計’,為此需記錄每個基學(xué)習(xí)器所使用的訓(xùn)練樣本,不放令Dt表示學(xué)習(xí)器ht實際使用的訓(xùn)練樣本集,令H_oob(x)表示對有樣本x的包外預(yù)測,即測試集不包含數(shù)據(jù)集中用于訓(xùn)練的部分:
????????????????????????????????????????????????????
則Bagging的泛化誤差的包外估計為:
????????????????????????????????????????????????????
利用包外估計的優(yōu)點,我們可以在基學(xué)習(xí)器的訓(xùn)練過程中及時調(diào)整訓(xùn)練模型,例如在使用決策樹為基學(xué)習(xí)器時,可以根據(jù)泛化性能來輔助剪枝,而當(dāng)使用神經(jīng)網(wǎng)絡(luò)時,則可利用包外樣本來輔助早停從而減少過擬合的風(fēng)險.
自助采樣法優(yōu)點比較明顯,但在數(shù)學(xué)上也有一定的缺陷,重復(fù)有放回采樣的道德樣本集改變了數(shù)據(jù)原有的分布,因此在一定程度上引入了偏差,對最終的結(jié)果預(yù)測會造成一定程度的影響.
Bagging實現(xiàn)
????????????
這是西瓜書上給出的Bagging偽代碼,我們需要做的很簡單,確定基學(xué)習(xí)算法,訓(xùn)練輪數(shù)T,利用自助法提取訓(xùn)練集,最后選擇使誤差最小的y作為預(yù)測樣本的標(biāo)簽.
導(dǎo)入所需庫
from numpy import * import matplotlib.pyplot as plt import random from sklearn import tree這里常用的num庫和mattplot庫就不多贅述了,random庫負(fù)責(zé)隨機選取樣本實現(xiàn)自助采樣法,sklearn.tree負(fù)責(zé)使用決策樹作為基學(xué)習(xí)器.
讀取數(shù)據(jù)
def loadDataSet(fileName):#讀取數(shù)據(jù)numFeat = len(open(fileName).readline().split('\t')) dataMat = []; labelMat = []fr = open(fileName)for line in fr.readlines():lineArr =[]curLine = line.strip().split('\t')for i in range(numFeat-1):#添加數(shù)據(jù)lineArr.append(float(curLine[i]))dataMat.append(lineArr)labelMat.append(float(curLine[-1]))#添加數(shù)據(jù)對應(yīng)標(biāo)簽return dataMat,labelMat這里的數(shù)據(jù)來源《機器學(xué)習(xí)實戰(zhàn)》第七章的病馬數(shù)據(jù),數(shù)據(jù)包含多匹患有疝氣病的1馬的多項特征指標(biāo),而標(biāo)簽值對應(yīng)病馬的死亡率預(yù)測,+1對應(yīng)存活,-1對應(yīng)死亡,通過決策樹和Bagging,來預(yù)測病馬的生存情況.
自助法采樣
def rand_train(dataMat,labelMat):#自助法采樣len_train = len(labelMat)#獲取樣本1數(shù)train_data = [] ; train_label = []for i in range(len_train):#抽取樣本數(shù)次樣本index = random.randint(0,len_train-1)#隨機生成樣本索引train_data.append(dataMat[index])#添加對應(yīng)數(shù)據(jù)與標(biāo)簽train_label.append(labelMat[index])return train_data,train_label#返回訓(xùn)練集與訓(xùn)練集標(biāo)簽通過random.randint隨機生成樣本數(shù)范圍內(nèi)的索引,構(gòu)造Bagging數(shù)據(jù)集.
決策樹基學(xué)習(xí)器
def bagging_by_tree(dataMat,labelMat,t=10):#默認(rèn)并行生成十個基學(xué)習(xí)器test_data,test_label = loadDataSet('horseColicTest2.txt') #獲取測試樣本與標(biāo)簽 predict_list = []for i in range(t):#并行生成T個train_data,train_label = rand_train(dataMat,labelMat)#自主采樣1得到樣本clf = tree.DecisionTreeClassifier()#初始化決策樹模型clf.fit(train_data,train_label)#訓(xùn)練模型total = []y_predicted = clf.predict(test_data)#預(yù)測數(shù)據(jù)total.append(y_predicted)predict_list.append(total)#結(jié)果添加到預(yù)測列表中return predict_list,test_label默認(rèn)t=10,即產(chǎn)生十個基學(xué)習(xí)器,這里基學(xué)習(xí)器對應(yīng)決策樹Tree,通過t次采樣,獲得t個樣本,訓(xùn)練t個決策樹,將每次預(yù)測的結(jié)果添加到predict_list中,供之后計算準(zhǔn)確率.
匯總結(jié)果計算準(zhǔn)確率
def calc_error(predict_list,test_label):#計算錯誤率m,n,k = shape(predict_list)#提取預(yù)測集信息predict_label = sum(predict_list,axis = 0)predict_label = sign(predict_label)for i in range(len(predict_label[0])):if predict_label[0][i] == 0:#如果票數(shù)相同,則隨機生成一個標(biāo)簽tip = random.randint(0,1)if tip == 0:predict_label[0][i] = 1else:predict_label[0][i] =-1error_count = 0#初始化預(yù)測錯誤數(shù)for i in range(k):if predict_label[0][i] != test_label[i]:#判斷預(yù)測精度error_count += 1error_rate = error_count/kreturn error_rate針對十個基學(xué)習(xí)器的預(yù)測結(jié)果,將結(jié)果累加,并使用sign函數(shù)進行類別預(yù)測,對于投票數(shù)相同的樣例,按照最簡單的解決方式,隨機選擇一個類別添加,最終統(tǒng)計預(yù)測不對的類別,最終計算錯誤率.
主函數(shù)
if __name__ == "__main__":fileName = 'horseColicTraining2.txt'dataMat,labelMat = loadDataSet(fileName)train_data,train_label = rand_train(dataMat,labelMat)predict_list , test_label = bagging_by_tree(dataMat,labelMat)print("Bagging錯誤率:",calc_error(predict_list,test_label))運行結(jié)果
Bagging錯誤率: 0.26865671641791045 [Finished in 0.9s]改為單學(xué)習(xí)器
def bagging_by_Onetree(dataMat,labelMat,t=10):test_data,test_label = loadDataSet('horseColicTest2.txt') train_data,train_label = rand_train(dataMat,labelMat)clf = tree.DecisionTreeClassifier()clf.fit(train_data,train_label)y_predicted = clf.predict(test_data)error_count = 0for i in range(67):if y_predicted[i] != test_label[i]:error_count += 1return error_count/67將bagging_by_tree函數(shù)稍微修改,取消學(xué)習(xí)器個數(shù)t,得到單一學(xué)習(xí)器,訓(xùn)練樣本,計算錯誤率看看如何.
Bagging錯誤率: 0.22388059701492538 單一學(xué)習(xí)器錯誤率: 0.3582089552238806 [Finished in 0.9s]總結(jié)
將上述過程多次計算,每次結(jié)果都會有所不同,這是因為隨機抽樣造成的樣本擾動所致,而且針對此樣本集,雖然集成后會提升性能,但Bagging最后的泛性能并不是很理想,因此還有更好的分類模型去預(yù)測,這里只是大概實現(xiàn)Bagging的過程,從而加深集成學(xué)習(xí)的印象.接下來主要介紹隨機森林RF,隨機森林在Bagging樣本擾動的基礎(chǔ)上,還對屬性進行了隨機選取,大大提升了模型泛化能力,是當(dāng)前集成學(xué)習(xí)特別常見的模型.
總結(jié)
以上是生活随笔為你收集整理的集成学习-Bagging原理与实现 西瓜书的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: orcad中添加图片
- 下一篇: jpg图片转为pdf?图片生成pdf的步