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