Python實現Adaboost

1.Adaboost概念

提升方法的思路是綜合多個分類器,得到更準確的分類結果。 即“三個臭皮匠頂個諸葛亮”。《統計學習方法》稱AdaBoost是提升算法的代表,所謂提升算法,指的是一種常用的統計學習方法,應用廣泛且有效。在分類問題中,它通過改變訓練樣本的權重,學習多個分類器,并將這些分類器進行線性組合,提髙分類的性能。
AdaBoost算法的基本思想:
1)多輪訓練,多個分類器
2)每輪訓練增加錯誤分類樣本的權值,降低正確分類樣本的權值
3)降低錯誤率高的分類器的權值,增加正確率高的分類器的權值

2.Adaboost算法流程

給定一個二類分類的訓練數據集,T={(x1,y1),(x2,y2),…(xn,yn)}T=\{({x_1},y_1),({x_2},y_2),\dots({x_n},y_n)\}T={(x1?,y1?),(x2?,y2?),(xn?,yn?)},其中χi∈X?Rnχ_i∈X? R^nχi?X?Rn表示實例的特征向量,yi∈Y∈{+1,?1}y_i∈Y\in\{+1,-1\}yi?Y{+1,?1},XXX是實例空間,YYY是標記集合。AdaBoost利用以下算法,從訓練數據中學習一系列弱分類器或基本分類器,并將這些弱分類器線性組合成為一個強分類器。
AdaBoost算法
輸入:訓練數據集T={(x1,y1),(x2,y2),…(xn,yn)}T=\{({x_1},y_1),({x_2},y_2),\dots({x_n},y_n)\}T={(x1?,y1?),(x2?,y2?),(xn?,yn?)},其中χi∈X?Rnχ_i∈X? R^nχi?X?Rn,yi∈Y∈{+1,?1}y_i∈Y\in\{+1,-1\}yi?Y{+1,?1};弱學習算法;
輸出:最終分類器G(x)G(x)G(x)
(1)初始化訓練數據的權值分布

D1=(W11,...,W1i,...,W1n)D_1=(W_{11},...,W_{1i},...,W_{1n})D1?=(W11?,...,W1i?,...,W1n?)

每個w的下標由兩部分構成,前一個數表示當前迭代次數,與D的下標保持一致,后一個數表示第幾個權值,與位置保持一致。初始情況下,每個權值都是均等的。
(2)對m=1,2,...Mm=1,2,...Mm=1,2,...M
(這里的M表示訓練的迭代次數,是由用戶指定的。每輪迭代產生一個分類器,最終就有M個分類器,當然我們也可以設置一些條件,滿足某些條件時跳出迭代,例如,所有樣本都分對了,誤差為0時,跳出迭代):
(a)使用具有權值分布的訓練數據集學習,得到基本分類器

Gm(x):X→{+1,?1}G_m(x):X{\rightarrow} \{+1,-1\}Gm?(x):X{+1,?1}

(b)在Gm(x)G_m(x)Gm?(x)訓練數據集上的分類誤差率

em=∑iNP(Gm(xi)≠yi)=∑iNwmiI(Gm(xi)≠yi))e_m=\sum_i^NP(G_m(x_i){\neq}y_i)=\sum_i^Nw_{mi}I(G_m(x_i){\neq}y_i))em?=iN?P(Gm?(xi?)??=yi?)=iN?wmi?I(Gm?(xi?)??=yi?))

分類誤差率這個名字可能產生誤解,這里其實是個加權和。
(c)計算Gm(x)G_m(x)Gm?(x)的系數

αm=12log1?emem\alpha_m = \frac{1}{2}log{\frac{1-e_m}{e_m}}αm?=21?logem?1?em??

這里的對數是自然對數。ama_mam?表示Gm(x)G_m(x)Gm?(x)在最終分類器中的重要性。由式αm=12log1?emem\alpha_m = \frac{1}{2}log{\frac{1-e_m}{e_m}}αm?=21?logem?1?em??可知,當em&lt;=1/2e_m&lt;=1/2em?<=1/2時,am&gt;=0a_m&gt;=0am?>=0,并且ama_mam?隨著eme_mem?的減小而增大,所以分類誤差率越小的基本分類器在最終分類器中的作用越大。

(d)更新訓練數據集的權值分布

Dm+1=(Wm+1,1,...,Wm+1,i,...,Wm+1,n)D_{m+1}=(W_{m+1,1},...,W_{m+1,i},...,W_{m+1,n})Dm+1?=(Wm+1,1?,...,Wm+1,i?,...,Wm+1,n?)

wm+1,i=wm,iZme?αmyiGm(xi)w_{m+1, i}=\frac{w_{m, i}}{Z_m}e^{-\alpha_my_iG_m(x_i)}wm+1,i?=Zm?wm,i??e?αm?yi?Gm?(xi?)

y只有正負一兩種取值,所以上式可以寫作:

wm+1,i={wmiZme?am,Gm(xi)=yiwmiZmeam,Gm(xi)≠yiw_{m+1,i}=\begin{cases} \frac{w_{mi}}{Z_m}e^{-a_m},G_m(x_i)=y_i \\ \frac{w_{mi}}{Z_m}e^{a_m},G_m(x_i){\neq}y_i \end{cases}wm+1,i?={Zm?wmi??e?am?,Gm?(xi?)=yi?Zm?wmi??eam?,Gm?(xi?)??=yi??

這里,ZmZ_mZm?是規范化因子

Zm=∑i=1Nwmiexp(?αmyiGm(xi))Z_m=\sum_{i=1}^Nw_{m i}exp({-\alpha_my_iG_m(x_i)})Zm?=i=1N?wmi?exp(?αm?yi?Gm?(xi?))

它使Dm+1D_{m+1}Dm+1?成為一個概率分布。
由此可知,被基本分類器誤分類樣本的權值得以擴大,而被正確分類樣本的權值卻得以縮小。兩相比較,誤分類樣本的權值被放大e2am=1?ememe^{2am} = {\frac{1-e_m}{e_m}}e2am=em?1?em??倍。因此,誤分類樣本在下一輪學習中起更大的作用。不改變所給的訓練數據,而不斷改變訓練數據權值的分布,使得訓練數據在基本分類器的學習中起不同的作用,這是AdaBoost的一個特點。

(3)構建基本分類器的線性組合:

f(x)=∑m=1MamGm(x)f(x)=\sum_{m=1}^{M}a_mG_m(x)f(x)=m=1M?am?Gm?(x)

得到最終分類器:

G(x)=sign(f(x))=sign(∑m=1MamGm(x))G(x)=sign(f(x))=sign(\sum_{m=1}^{M}a_mG_m(x))G(x)=sign(f(x))=sign(m=1M?am?Gm?(x))
這里需要注意的是,我們得到的是M個f(x)方程,需要將每個方程的結果求和,最好只取結果的正負號,在Adaboost中我們的預測結果與數值是無關的。

3.完整代碼

代碼運行結果:
在這里插入圖片描述

# -*- coding: utf-8 -*-
"""@Time    : 2018/12/04 13:58@Author  : hanzi5@Email   : hanzi5@yeah.net@File    : Adaboost.py@Software: PyCharm
"""
import numpy as np
#import pandas as pd
import matplotlib
import matplotlib.pyplot as pltmatplotlib.rcParams['font.family']='SimHei'  # 用來正常顯示中文
plt.rcParams['axes.unicode_minus']=False     # 用來正常顯示負號def splitDataSet(dataSet, i, value,types='lt'):"""
#劃分數據集,只進行一次劃分的樹,將劃分后的結果返回:param dataSet: 數據:param i: 特征的下標:param value: 閾值:param types: 大于或小于:return: 分類結果,注意返回的直接就是1,-1分類結果"""retArray = np.ones((np.shape(dataSet)[0],1))     # 默認類型都為1if types=='lt':   # 使用(小于等于value)劃分數據,滿足條件的將結果值改為-1retArray[dataSet[:,i]<=value]= -1.0  elif types=='gt': # 使用(大于value)劃分數據,滿足條件的將結果值改為-1retArray[dataSet[:,i]>value]= -1.0  return retArray def bulidSimpleTree(dataSet,y,D):"""
創建一個最簡單的樹,只進行一次劃分,相當于一個樹樁:param dataSet: 數據特征矩陣:param y: 標簽向量:param D: 訓練數據的權重向量:return: 最佳決策樹,最小的錯誤率加權和,最優預測結果"""m,n=dataSet.shape                      # 樣本行數及列數numFeatures = len(dataSet[0]) - 1      # 最后一列為y,計算x特征列數numSteps=10                            # 用于計算步長,進行numSteps等分minError=np.inf                        # 初始化損失值bestTree={}                            # 使用dict存儲最優的一系列樹for i in range(numFeatures):           # 遍歷所有x特征列# i=0rangeMin = dataSet[:, i].min()     # 該xi維的最小值rangeMax = dataSet[:, i].max()     # 該xi維的最大值stepSize = (rangeMax - rangeMin) / numSteps # 步長for j in range(-1,int(numSteps) + 1):    # 循環尋找最優切分點# j=-1for inequal in ['lt', 'gt']:         # 遍歷(lt小于等于)及(gt大于)# inequal=1value = (rangeMin + float(j) * stepSize) # 切分值predictedVals = splitDataSet(dataSet, i, value, inequal)  # 獲取切分后的數據errArr = np.mat(np.ones((m, 1)))errArr[predictedVals == y] = 0  # 預測正確的樣本對應的錯誤率為0,否則為1weightedError=D.T*errArr        # 《統計學習方法》李航P138,8.1,計算訓練數據上的分類誤差率if weightedError < minError:    # 記錄最優樹樁決策樹分類器minError = weightedError    # 計算錯誤率加權和bestClasEst = predictedVals.copy() # 最好的預測結果bestTree['column'] = i             # 維度xbestTree['splitValue'] = value     # 切分值bestTree['ineq'] = inequal         # 切分方法(lt小于等于)及(gt大于)return bestTree, minError, bestClasEst# 基于單層決策樹的adaboost分類器
def adaboost(dataSet,maxLoop=100):"""
基于單層決策樹的ada訓練:param dataSet: 樣本x及y:param maxLoop: 迭代次數:return: 一系列弱分類器及其權重,樣本分類結果"""adaboostTree=[]m,n=dataSet.shape                     # 樣本行數及列數y=dataSet[:,-1].reshape((-1,1))       # 將y提取出來,方便進行計算D = np.array(np.ones((m,1))/m)        # 將每個樣本的權重初始化為均等,有多少條數據就有多少個daggClassEst = np.mat(np.zeros((m,1))) # 每個數據點的類別估計累計值for i in range(maxLoop):              # maxLoop超參數,總迭代次數bestTree, minError, bestClasEst=bulidSimpleTree(dataSet,y,D)alpha=0.5*np.log((1-minError)/(minError+0.00001)) # 《統計學習方法》李航P139,8.2,計算Gm的系數,分母加一個小數避免除數為0bestTree['alpha'] = alpha.getA()[0][0]            # 將matrix中的值提取出來,并加入到bestTree中adaboostTree.append(bestTree)                     # 將樹存入list中存儲D=D*np.exp(-alpha.getA()[0][0]*y*bestClasEst)     # 更新權重D,《統計學習方法》李航P139,8.3-8.5,計算Gm(x)的系數D=D/D.sum()                                       # 歸一化權重值,統計學習方法》李航P139,8.5,計算Zm# 計算所有分類器的誤差,如果為0則終止訓練aggClassEst += alpha.getA()[0][0]*bestClasEst     # 分類估計累計值,adaboost是線性運行的,需要將每次的樹預測結果相加aggErrors = np.multiply(np.sign(aggClassEst) != np.mat(y),np.ones((m,1))) # aggClassEst每個元素的符號代表分類結果,如果與y不等則表示錯誤,統計學習方法》李航P138,8.8errorRate = aggErrors.sum()/m                     # 平均分類誤差print( "total error: ",errorRate)if errorRate == 0.0:                              # 平均分類誤差等于0的,說明數據已經全部分類正確,跳出循環breakreturn adaboostTree,aggClassEstdef adaClassify(data, adaboostTree):"""
對預測數據進行分類:param data: 預測樣本x及y:param adaboostTree: 使用訓練數據,訓練好的決策樹:return: 預測樣本分類結果"""dataMatrix = np.mat(data)  m = np.shape(dataMatrix)[0]aggClassEst = np.mat(np.zeros((m, 1)))for i in range(len(adaboostTree)):                     # 遍歷所有adaboostTree,將估計值累加classEst = splitDataSet(dataMatrix, adaboostTree[i]['column'], adaboostTree[i]['splitValue'], adaboostTree[i]['ineq'])  aggClassEst += adaboostTree[i]['alpha'] * classEst # 分類估計累計值,adaboost是線性運行的,需要將每次的樹預測結果相加result = np.sign(aggClassEst)                          # 只取正負號,《統計學習方法》李航P139,8.8return resultdef plotData(dataSet):"""
數據畫圖"""type1_x1 = []type1_x2 = []type2_x1 = []type2_x2 = []# 取兩類x1及x2值畫圖type1_x1 = dataSet[dataSet[:,-1] == -1][:,:-1][:,0].tolist()type1_x2 = dataSet[dataSet[:,-1] == -1][:,:-1][:,1].tolist()type2_x1 = dataSet[dataSet[:,-1] == 1][:,:-1][:,0].tolist()type2_x2 = dataSet[dataSet[:,-1] == 1][:,:-1][:,1].tolist()# 畫點fig = plt.figure()ax = fig.add_subplot(111)ax.scatter(type1_x1,type1_x2, marker='s', s=90)ax.scatter(type2_x1,type2_x2, marker='o', s=50, c='red')plt.title('Adaboost訓練數據')if __name__ == '__main__':print('\n1、Adaboost,開始')dataSet = np.array([[ 1. , 2.1, 1 ],[ 2. , 1.1, 1 ],[ 1.3, 1. , -1],[ 1. , 1. , -1],[ 2. , 1. , 1 ]])#classLabels = [1.0, 1.0, -1.0, -1.0, 1.0]# 畫圖print('\n2、Adaboost數據畫圖')plotData(dataSet)print('\n3、計算Adaboost樹')adaboostTree,aggClassEst=adaboost(dataSet)# 對數據進行分類print('\n4、對[5,5],[0, 0]點,使用Adaboost進行分類:')print( adaClassify([[5,5],[0, 0]], adaboostTree))    

參考資料:
1、《機器學習實戰》Peter Harrington著
2、《機器學習》西瓜書,周志華著
3、 斯坦福大學公開課 :機器學習課程
4、機器學習視頻,鄒博
5、《統計學習方法》李航
6、提升方法
7、分類——組合算法之提升1:AdaBoost提升算法以及Python實現

轉載于:https://www.cnblogs.com/hanzi5/p/10105613.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/450441.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/450441.shtml
英文地址,請注明出處:http://en.pswp.cn/news/450441.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java List<T>去重方法,引用類型集合去重

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、實體類中要重寫比較方法equals&#xff0c;最好也重寫hashcode方法 public class WorkWeightDto implements Serializable {privat…

MyBatis知識點

一、MyBatis簡介 1.1 框架概念 框架&#xff0c;就是軟件的半成品&#xff0c;完成了軟件開發過程中的通用操作&#xff0c;程序員只需很少或者不用進行加工就能夠實現特定的功能&#xff0c;從而簡化開發人員在軟件開發中的步驟&#xff0c;提高開發效率。 1.2 常用框架 MVC…

android studio : clang++.exe: error: invalid linker name in argument '-fuse-ld=bfd

公司jenkins上的C編譯器最近換成了clang&#xff0c;今天更新了代碼發現本地的C/C代碼用NDK編譯不過了&#xff0c;提示&#xff1a; “clang.exe: error: invalid linker name in argument -fuse-ldbfd” 解決辦法&#xff1a; 將Android.mk文件中的“LOCAL_LDFLAGS -fuse-ld…

Git知識點

一、Git簡介 1.1 項目的版本管理 在項目開發過程中&#xff0c;項目沒開發到一個節點就會對當前項目進行備份&#xff0c;這個備份就是項目的一個版本&#xff1b;當我們繼續開發一個階段后&#xff0c;再次進行備份&#xff0c;就生成新的版本——多個版本的集合就是項目的版…

(1)初始化項目

2019獨角獸企業重金招聘Python工程師標準>>> &#xff08;1&#xff09;初始化項目 1 使用vue-cli初始化項目 vue init webpack my-renren得到以下輸出&#xff1a; ? Project name my-renren ? Project description A Vue.js project ? Author neumeng <4048…

C語言變量

C語言二進制、八進制、十六進制詳解 什么是二制制? 在數學計算中&#xff0c;二進制計數系統的公分母是最小的&#xff0c;它以2為基數。你還記得在小學或中學時所學的不同的計數系統嗎?筆者在上小學時&#xff0c;曾在一堂數學課中學過以6為基數的計數系統&#xff1b;你先…

Spring Data JPA - 參考文檔 地址

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Spring Data JPA - 參考文檔 文檔地址

JS內置方法(Array)

concat() 用于連接兩個或多個數組&#xff0c;該方法不會改變現有的數組&#xff0c;而是返回被連接數組的一個副本。join() 把數組中的所有元素放入一個字符串&#xff0c;元素是通過指定的分隔符進行分隔的。若省略了分隔符參數&#xff0c;則使用逗號作為分隔符。push() 向…

模切ERP和免費OA系統是互相結合提高效率

模切ERP和免費OA系統是互相結合提高效率在模切行業中&#xff0c;模切ERP在管理上的作用占了很大的比重&#xff0c;但是免費OA在管理上的地位都不容忽視的。點晴OA的核心問題是如何提高日常的辦公效率問題。因此點晴OA系統里包含的功能是非常全面&#xff0c;如&#xff1a;辦…

maven知識點

一、Maven簡介 1.1 在項目中如何導入jar包&#xff1f; 下載jar包 &#xff08;mvn&#xff09;將下載的jar包拷貝到項目中&#xff08;WEB-INF/lib&#xff09;選擇jar文件–右鍵–Add as Library 1.2 傳統導入jar包的方式存在什么問題&#xff1f; 步驟多&#xff08;相對…

使用SpringBoot yml配置文件

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1.上一次我們已經使用SpringBoot實現了一個簡單的HelloWord程序&#xff0c;辣么接下來我們簡單的使用一下他的yml格式的配置文件。 2.在…

軟件行業資訊

為什么只有設計師才能發明流行的新語言 先回顧一下知名編程語言的作者和創造時間&#xff1a;Fortran 語言&#xff0c;50年代&#xff0c;IBM 研究員&#xff1b;Lisp 語言&#xff0c;50年代&#xff0c;MIT 的教授和學生&#xff1b;C語言&#xff0c;70年代&#xff0c;貝爾…

spring知識點

一、Spring概述 1.1 web項目開發中的耦合度問題 在Servlet中需要調用service中的方法&#xff0c;則需要在Servlet類中通過new關鍵字創建Service的實例 public interface ProductService{public List<Product> listProducts(); }public class ProductServiceImpl1 imple…

Linux系統下的權限試題測試

不會做的留言&#xff0c;到時在發布答案&#xff01;一、 有兩個參賽團隊team1、team2&#xff0c;兩個團隊各3人, 這兩個團隊互相競爭&#xff0c;各需提交一份報告&#xff0c;每組成員可以修改自己團隊內的所有文件&#xff0c;且不能讓其他團隊的人修改自己的文件內容&…

電子科大軟件系統架構設計——軟件建模詳細設計

文章目錄 軟件建模詳細設計概述軟件建模詳細設計目標軟件建模詳細設計原則開閉原則里氏 (Liskov) 替換原則依賴倒置原則接口分離原則單一職責原則最少知識原則&#xff08;迪米特法則&#xff09;高內聚原則松耦合原則可重用原則 軟件建模詳細設計內容 UML 軟件靜態結構視圖建模…

YAML文件解析

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 YAML是“另一種標記語言”的外語縮寫,YAML 是一種比JSON&#xff08;json多層次{ 與 [ 會被搞暈的&#xff09;更直觀的表現形式&#xf…

120分鐘React快速掃盲教程

在教程開端先說些題外話&#xff0c;我喜歡在學習一門新技術或讀過一本書后&#xff0c;寫一篇教程或總結&#xff0c;既能幫助消化&#xff0c;也能加深印象和發現自己未注意的細節&#xff0c;寫的過程其實仍然是一個學習的過程。有個記錄的話&#xff0c;在未來需要用到相關…

springmvc知識點

一、SpringMVC概述 Spring MVC 是由Spring官方提供的基于MVC設計理念的web框架。 SpringMVC是基于Servlet封裝的用于實現MVC控制的框架&#xff0c;實現前端和服務端的交互。 1.1 SpringMVC優勢 嚴格遵守了MVC分層思想 采用了松耦合、插件式結構&#xff1b;相比較于我們封裝的…

spring @component的作用

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1、controller 控制器&#xff08;注入服務&#xff09; 2、service 服務&#xff08;注入dao&#xff09; 3、repository dao&#xff…

微信小程序 懸浮按鈕

2019獨角獸企業重金招聘Python工程師標準>>> 效果視頻 https://pan.baidu.com/s/1yfrDaG9YAX0--v0EA3awZA 布局需要按照圓形排列&#xff0c;所以我們需要計算每個點的坐標 代碼部分 <view styleposition:fixed; wx:for"{{list}}" wx:for-index"i…