寫一個個人認為比較詳細的adaboost演算法
阿新 • • 發佈:2019-02-18
最近在看機器學習中adaboost(adaptive boostint)演算法部分的內容,在csdn上面查詢一番發現,好像沒有講的特別的詳盡的,當然可能是我人品不佳,所以沒有找到,為了防止同樣的事情發生在其他人的身上,所以就寫了這篇博文,儘量多的解釋演算法的推演過程更方便的大家去理解這個演算法。
介紹adaboost演算法之前,首先介紹一下學習演算法的強弱,這個是PAC定義的:弱學習演算法---識別錯誤率小於1/2(即準確率僅比隨機猜測略高的學習演算法),強學習演算法---識別準確率很高並能在多項式時間內完成的學習演算法。
接著我就用我所理解的例子來介紹一下adaboost演算法,相信看過這個計算過程大家對這個演算法肯定有更深刻的理解,由於csdn插入公式比較困難,所以下面的步驟我就用word截圖來表示了,對了先敘述一下adaboost演算法的迭代過程吧,這樣對後面的計算會理解的更深刻一些。
adaboost演算法迭代過程:
有了adaboost演算法的迭代過程,那麼我們就可以利用已知的公式對上面的式子進行簡化了,下面的公式應用的會更多一 些
推導部分就到這裡好了,接下來就是用例子來幫助大家理解adaboost演算法的過程了,恩,見證奇蹟的時刻到來了
好了到了這裡對adaboost演算法的過程肯定是理解了吧,那麼我接著來放一個code來實現一下這個過程,必定會加深大家對這個演算法的理解,OK,開始。
先試驗下《統計學習方法》裡面那個最簡單的例子:01.# coding: UTF-8 02.from __future__ import division 03.import numpy as np 04.import scipy as sp 05.from weakclassify import WEAKC 06.from dml.tool import sign 07.class ADABC: 08. def __init__(self,X,y,Weaker=WEAKC): 09. ''''' 10. Weaker is a class of weak classifier 11. It should have a train(self.W) method pass the weight parameter to train 12. pred(test_set) method which return y formed by 1 or -1 13. see detail in <統計學習方法> 14. ''' 15. self.X=np.array(X) 16. self.y=np.array(y) 17. self.Weaker=Weaker 18. self.sums=np.zeros(self.y.shape) 19. self.W=np.ones((self.X.shape[1],1)).flatten(1)/self.X.shape[1] 20. self.Q=0 21. #print self.W 22. def train(self,M=4): 23. ''''' 24. M is the maximal Weaker classification 25. ''' 26. self.G={} 27. self.alpha={} 28. for i in range(M): 29. self.G.setdefault(i) 30. self.alpha.setdefault(i) 31. for i in range(M): 32. self.G[i]=self.Weaker(self.X,self.y) 33. e=self.G[i].train(self.W) 34. #print self.G[i].t_val,self.G[i].t_b,e 35. self.alpha[i]=1/2*np.log((1-e)/e) 36. #print self.alpha[i] 37. sg=self.G[i].pred(self.X) 38. Z=self.W*np.exp(-self.alpha[i]*self.y*sg.transpose()) 39. self.W=(Z/Z.sum()).flatten(1) 40. self.Q=i 41. #print self.finalclassifer(i),'===========' 42. if self.finalclassifer(i)==0: 43. 44. print i+1," weak classifier is enough to make the error to 0" 45. break 46. def finalclassifer(self,t): 47. ''''' 48. the 1 to t weak classifer come together 49. ''' 50. self.sums=self.sums+self.G[t].pred(self.X).flatten(1)*self.alpha[t] 51. #print self.sums 52. pre_y=sign(self.sums) 53. #sums=np.zeros(self.y.shape) 54. #for i in range(t+1): 55. # sums=sums+self.G[i].pred(self.X).flatten(1)*self.alpha[i] 56. # print sums 57. #pre_y=sign(sums) 58. t=(pre_y!=self.y).sum() 59. return t 60. def pred(self,test_set): 61. sums=np.zeros(self.y.shape) 62. for i in range(self.Q+1): 63. sums=sums+self.G[i].pred(self.X).flatten(1)*self.alpha[i] 64. #print sums 65. pre_y=sign(sums) 66. return pre_y
可以看到也是三個分類器就沒有誤分點了,權值的選擇也是差不多的 其中後面那個-1 表示大於threshold分為負類,小於分為正類。1則相反
加一些其它資料試試:
結果: 我們把圖畫出來就是:
基本還是正確的,這是四個子分類器的圖,不是最後總分類器的圖啊~~~