嘗試用sklearn進行adaboost實戰 & SAMME.R算法流程,博客地址
- 初試AdaBoost
- SAMME.R算法流程
- sklearn之AdaBoostClassifier類
- 完整實戰demo
初試AdaBoost
一個簡單的例子,來介紹AdaBoostClassifier。
例子放在Github上,可以直接fork。
#coding=utf-8 #python 3.5 ''' Created on 2017年11月24日 @author: Scorpio.Lu ''' ''' 在scikit-learn庫中,有AdaBoostRegression(回歸)和AdaBoostClassifier(分類)兩個。 在對和AdaBoostClassifier進行調參時,主要是對兩部分進行調參:1) AdaBoost框架調參;2)弱分類器調參 ''' #導包 from sklearn.model_selection import cross_val_score from sklearn.datasets import load_iris from sklearn.ensemble import AdaBoostClassifier #載入數據,sklearn中自帶的iris數據集 iris=load_iris() ''' AdaBoostClassifier參數解釋 base_estimator:弱分類器,默認是CART分類樹:DecisionTressClassifier algorithm:在scikit-learn實現了兩種AdaBoost分類算法,即SAMME和SAMME.R, SAMME就是原理篇介紹到的AdaBoost算法,指Discrete AdaBoost SAMME.R指Real AdaBoost,返回值不再是離散的類型,而是一個表示概率的實數值,算法流程見后文 兩者的主要區別是弱分類器權重的度量,SAMME使用了分類效果作為弱分類器權重,SAMME.R使用了預測概率作為弱分類器權重。 SAMME.R的迭代一般比SAMME快,默認算法是SAMME.R。因此,base_estimator必須使用支持概率預測的分類器。 loss:這個只在回歸中用到,不解釋了 n_estimator:最大迭代次數,默認50。在實際調參過程中,常常將n_estimator和學習率learning_rate一起考慮 learning_rate:每個弱分類器的權重縮減系數v。f_k(x)=f_{k-1}*a_k*G_k(x)。較小的v意味着更多的迭代次數,默認是1,也就是v不發揮作用。 另外的弱分類器的調參,弱分類器不同則參數不同,這里不詳細敘述 ''' #構建模型 clf=AdaBoostClassifier(n_estimators=100) #弱分類器個數設為100 scores=cross_val_score(clf,iris.data,iris.target) print(scores.mean())
SAMME.R算法流程
- 初始化樣本權值:$ w_i=1/N,i=1,2,…,N $
- Repeat for $ m=1,2,…,M $:
- 訓練一個弱分類器,得到樣本的類別預測概率分布 $ p_m(x)=P(y=1|x)∈[0,1] $
- $f_m(x)=\frac{1}{2}log\frac{p_m(x)}{1-p_m(x)}$
- $w_i=w_iexp[-y_if_m(x_i)]$,同時,要進行歸一化使得權重和為1
- 得到強分類模型:$sign{\sum_{m=1}^{M}f_m(x)}$
AdaBoostClassifier類
現在我們來說點理論的東西。關於AdaBoostClassifier。
sklearn.ensemble.AdaBoostClassifier的構造函數如下:
AdaBoostClassifier(base_estimator=None, n_estimators=50, learning_rate=1.0, algorithm=’SAMME.R’, random_state=None)
各個參數已經在代碼里介紹過了,這里不再敘述。有一點要注意,理論上可以選擇任何一個弱分類器,不過需要有樣本權重。
另外有方法:
另外一些方法請見官網sklearn-AdaBoost
完整實戰demo
現在再來一個完整的demo,來看看AdaBoost的分類效果
#coding=utf-8 #python 3.5 ''' Created on 2017年11月27日 @author: Scorpio.Lu ''' import numpy as np import matplotlib.pyplot as plt from sklearn.ensemble import AdaBoostClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.datasets import make_gaussian_quantiles #用make_gaussian_quantiles生成多組多維正態分布的數據 #這里生成2維正態分布,設定樣本數1000,協方差2 x1,y1=make_gaussian_quantiles(cov=2., n_samples=200, n_features=2, n_classes=2, shuffle=True, random_state=1) #為了增加樣本分布的復雜度,再生成一個數據分布 x2,y2=make_gaussian_quantiles(mean=(3,3), cov=1.5, n_samples=300, n_features=2, n_classes=2, shuffle=True, random_state=1) #合並 X=np.vstack((x1,x2)) y=np.hstack((y1,1-y2)) #plt.scatter(X[:,0],X[:,1],c=Y) #plt.show() #設定弱分類器CART weakClassifier=DecisionTreeClassifier(max_depth=1) #構建模型。 clf=AdaBoostClassifier(base_estimator=weakClassifier,algorithm='SAMME',n_estimators=300,learning_rate=0.8) clf.fit(X, y) #繪制分類效果 x1_min=X[:,0].min()-1 x1_max=X[:,0].max()+1 x2_min=X[:,1].min()-1 x2_max=X[:,1].max()+1 x1_,x2_=np.meshgrid(np.arange(x1_min,x1_max,0.02),np.arange(x2_min,x2_max,0.02)) y_=clf.predict(np.c_[x1_.ravel(),x2_.ravel()]) y_=y_.reshape(x1_.shape) plt.contourf(x1_,x2_,y_,cmap=plt.cm.Paired) plt.scatter(X[:,0],X[:,1],c=y) plt.show()
訓練完成后的錯誤率大概是0.116。分類效果圖如下:
作者 Scorpio.Lu
轉載請注明出處!