目前集成學習有bagging、boosting算法,二者異同能夠參考這篇博客 隨機森林(RandomForest)是一種bagging的方法; Adaboost、GBDT、XGBoost 都是一種boosting方法。html
本文只介紹AdaBoost的基本原理方便本身複習,並附上兩年前寫的matlab程序。算法
參考:李航的《統計學習方法》 AdaBoost經過加大分類偏差率小的弱分類器的權重,使其在表決中起的做用較大,減少分類偏差率大的弱分類器的權重,使其在表決中起較小的做用。微信
adaboost_model.m
模型函數:dom
%%---------- 《提高算法-多維》:建模專用 -------------用於二分類 %說明: % 輸入X=[n*m],Y=[n*1](-1/1二類值); % 輸出CUT=[p*4],CUT(:,1)爲切分點,CUT(:,2:3)爲切分值,CUT(:,4)爲權重係數,CUT(:,5)爲變量標誌位; % ERR爲訓練偏差精度,ECHO爲訓練最大步數; % 使用C_CART函數進行切分。 %例如: % x=[2 4 0 3 1 5 6 7 8 9;2 6 7 22 5 15 4 9 8 1;5 8 12 9 0 11 30 7 6 4;5 4 9 0 0.2 2 7 6 3 1]'; % y=[1 -1 1 -1 1 -1 1 1 1 -1]'; %做者:zlw %時間:2016-07-27 %--------------------------------------------------- %% function [ CUT ] = adaboost_model( x,y,ERR,ECHO) %ADABOOST_MODEL Summary of this function goes here % Detailed explanation goes here %%自適應提高算法(adaboosting)實現多維特徵進行 二分類(-1,1)問題; xy=[x,y]; %-------------------------------------------- [n,m]=size(x); %xy=sortrows(xy,1);%按某列排序; for i=1:m [XY(:,:,i),DI(:,i)]=sortrows(xy,i);%將矩陣按照第i列升序跟着排列 end D=1/n*ones(n,m);%佯本初始權值; %------- ------- y=xy(:,end); echo=1;p_err=1;Fx=0;CUT=[]; while (p_err>ERR && echo<ECHO) G0=zeros(n,1);D0=zeros(n,1); for i=1:m [cut(i),cut_v(i,:),err(i),G(:,i)] = C_cart(XY(:,i,i) ,XY(:,end,i),D(:,i));%計算各個變量分類的最優切分點、偏差、對應的預測值 end min_err=min(err); %最小分類偏差,(須要注意err可能爲0) min_i=find(err==min_err);min_i=min_i(1);%分類偏差最小的變量序號 op_cut=cut(min_i); %最優分類閾值 op_G=G(:,min_i); %分類值 op_cutv=cut_v(min_i,:);%分類值 alpha=0.5*log((1-min_err)/min_err); %G的係數 CUT=[CUT;op_cut,op_cutv,alpha,min_i]; G0(DI(:,min_i))=op_G;%原始序號下的預測值 Fx=alpha*G0+Fx;%決策函數 %計算分類錯誤率 a=Fx>0; b=y>0; p_err=sum(abs(a-b))/n; %---------- 更新權值 ---------- sumD=0; for i=1:n D(i,min_i)=D(i,min_i)*exp(-alpha*XY(i,end,min_i)*op_G(i)); sumD=sumD+D(i,min_i); end D(:,min_i)=D(:,min_i)/sumD; D0(DI(:,min_i))=D(:,min_i);%原始序號下的佯本權值 for k=1:m D(:,k)=D0(DI(:,k)) ;%各列爲列排序後的佯本權值 end echo=echo+1; end end
C_cat.m
切分函數:編輯器
function [ op_cut,op_cutv ,min_err,op_G] = C_cart( x,y,D ) %C_CART Summary of this function goes here % Detailed explanation goes here [n,~]=size(x); class_y=unique(y); pre0=ones(n,1); for i=1:n-1 cut(i)= (x(i)+x(i+1))/2;%分類閾值 %----- %獲得分類偏差 pre(1:i)=class_y(1)*pre0(1:i);%歸爲類1 pre(i+1:n)=class_y(2)*pre0(i+1:n);%歸爲類2 G1=[pre(1:i),pre(i+1:n)]'; err1=0; for j=1:n if y(j)~=pre(j) err1=err1+D(j); end end pre(1:i)=class_y(2)*pre0(1:i);%歸爲類2 pre(i+1:n)=class_y(1)*pre0(i+1:n);%歸爲類1 G2=[pre(1:i),pre(i+1:n)]'; err2=0; for j=1:n if y(j)~=pre(j) err2=err2+D(j); end end if err1<=err2 err(i)=err1;G(:,i)=G1;cut_v(i,:)=[class_y(1),class_y(2)]; else err(i)=err2;G(:,i)=G2;cut_v(i,:)=[class_y(2),class_y(1)]; end %-------------------------- end min_err=min(err); %最小分類偏差 min_i=find(err==min_err);min_i=min_i(1); op_cut=cut(min_i); %最優分類閾值 op_G=G(:,min_i); %分類值 op_cutv=cut_v(min_i,:); end
adaboost_pre.m
預測函數:函數
%%---------- 《提高迴歸樹算法》:預測專用 ------------- %說明: % 輸入:測試數據X=[n*m],生成樹CUT=[p*5],CUT(:,1)爲切分點,CUT(:,2:3)爲切分值,CUT(:,4)爲權重係數,CUT(:,5)爲變量標誌位; % 輸出:預測Y=[n*1]; % %做者:zlw %時間:2016-07-27 %% function [ Y ] = adaboost_pre( x, CUT ) %ADABOOST_PRE Summary of this function goes here % Detailed explanation goes here [n,~]=size(x); Y=[]; for i=1:n y_predict=0; for j=1:size(CUT,1) n_r=CUT(j,end); if x(i,n_r)<CUT(j,1) y_predict=y_predict+CUT(j,4)*CUT(j,2); else y_predict=y_predict+CUT(j,4)*CUT(j,3); end end Y = [Y;y_predict]; end end
test.m
測試文件工具
clc;clear;close all; x=[2 4 0 3 1 5 6 7 8 9;2 6 7 22 5 15 4 9 8 1;5 8 12 9 0 11 30 7 6 4;5 4 9 0 0.2 2 7 6 3 1]'; % x=[2 4 0 3 1 5 6 7 8 9]'; y=[1 -1 1 -1 1 -1 1 1 1 -1]'; ERR=0.08;%最大訓練偏差 ECHO=100;%最大訓練循環次數 [ CUT ] = adaboost_model( x,y ,ERR,ECHO);%訓練 [ Y ] = adaboost_pre( x, CUT );%預測 %計算分類錯誤率 a=Y>0; b=y>0; p_err=sum(abs(a-b))/size(x,1); disp(CUT); disp(p_err);