# v M. S% I4 I7 x2 C, c& |/ G& r0 ?+ z3 i6 L
对于随机森林中决策树的个数应该为多少个呢,我们看这个图,可以发现当决策树达到一定的数量,准确率就趋于稳定了。 ( F6 }1 g) ~ f8 A/ i6 a' S4 |! a" T+ B- q
8 i% A" R* B, f) ]4 h% @
) @* D4 D7 V( a# Q, D, [6 I9 C
2.3、随机森林的分类过程9 n% w, f9 h4 E9 H8 {( Z3 v2 g
训练随机森林的过程就是训练各个决策树的过程,由于各个决策树的训练是相互独立的,因此随机森林的训练可以通过并行处理来实现,这将大大提高生成模型的效率。当输入待分类样本时,随机森林输出的分类结果由每个决策树的分类结果简单投票决定,随机森林的思想是:随机选取样本构造决策树,随机选取特征进行分裂。 ! ]# U% l4 M. u, Q3 W; E9 i 3 s! Q6 r& O4 d6 U( _5 m+ { . [+ O8 n7 \; b S% I4 e6 @9 R 0 a3 {) n' @% T3 H. ^随机森林的最终分类结果是取众数的方式,或者理解为取平均的方式。: L" ^1 x! I$ g7 W$ f" u
- w8 b& ?9 f" A4 {; M8 k. E 6 D4 X4 h! Z) p6 A, O/ M. j* L4 X# Q( p. X- n
分类过程可以近似表示为如下:) t4 D2 w+ P/ c& J& Q& K# l$ }
* z% ^& E6 U! v6 e" `
9 h2 g0 y: x8 E( B a$ }( a6 I
. v; G! }' C" }4 ]0 {, N$ ]0 o' c( N# q$ K5 L( n, y: t
$ w0 ~8 o# I/ Q+ e
2.4、随机森林的实验案例及分析' b/ u) D) @& m
我们先看一下我用的数据集,我用的还是上面决策树案例用到的根据环境状况判断是否打球的数据集合,14组数据。, `1 l, G, i/ c3 ?8 ]( X9 A# U
( [ W# N$ N" k! u' _2 a) |# \, J& ?
) {2 `/ ?' f! X$ K& w
4 n! A+ U7 F8 i% A
" A" [ n' n. |! A' Q, `! r; v2 u- A+ E
第一步:确定决策树的个数和决策树叶子节点数量,其中,RFOptimizationNum是为了多次循环,防止最优结果受到随机干扰;大家如果不需要,可以将这句话删除。. `, H* h2 z& T
) l6 q! e$ y. o$ A 这里决策树的个数设置1~500,在这个范围内寻找最合适的决策树个数。* S p! F+ I; r+ g8 M
RFLeaf定义初始的叶子节点个数,我这里设置了从5到500,也就是从5到500这个范围内找到最优叶子节点个数。 - M- d G4 L$ @$ N: t, t3 w3 x Input与Output分别是我的输入(自变量)与输出(因变量),大家自己设置即可。" W. _% ^( G+ Y! Z( @) s
( R- f9 M7 B* g5 J% @6 J6 q: a- M& W. {0 ?# v( X0 D8 c, D
clc1 q$ }/ E) v Z6 d3 J0 P* w
clear) n$ ?) S2 o6 N1 y& B/ |" L
load('data1.mat')' n. u: m6 \) i* B# F1 j
Input = data1(2:end,1:end-1) " l# ~( ^4 C0 B2 T$ z: P% ~, zOutput = data1(2:end,end) 5 o* K4 N8 r) v# t# U6 I
%% 确定叶子节点和决策树的数量 * s8 u4 V3 E e8 N/ A: \% e+ Ofor RFOptimizationNum=1:5 ! H+ |' K3 H0 A. U# F. ~3 c2 T. }RFLeaf=[5,10,20,50,100,200,500];) T o1 U+ X; ~8 I) m7 l8 Q
col='rgbcmyk'; Z2 S- P$ H: p& w% s1 {) A
figure('Name','RF Leaves and Trees'); 7 [$ p& |6 j+ A# D1 U) Jfor i=1:length(RFLeaf)& M4 ^+ P5 b4 \ j! I9 L, ?
RFModel=TreeBagger(500,Input,Output,'Method','R','OOBPrediction','On','MinLeafSize',RFLeaf(i));9 {: U. }7 J8 o2 e: \7 f, a1 Q* t
plot(oobError(RFModel),col(i));3 B# `# V' V9 s" g# S& g
hold on " U/ Z) P: }) j2 Send 2 r, o# D! d( ^, Xxlabel('Number of Grown Trees');) l5 g5 @, Q% J: G3 e0 ~
ylabel('Mean Squared Error') ;$ k' v9 `" }' k/ g: h; m, y5 Q
LeafTreelgd=legend({'5' '10' '20' '50' '100' '200' '500'},'Location','NorthEast');& e* Y1 \4 ^' P/ B
title(LeafTreelgd,'Number of Leaves');3 v0 ]" C' f; h% |" e
hold off;/ [, M6 z4 k; c) `5 a+ l: Y: C
disp(RFOptimizationNum);+ w0 k: m) B/ D" }* t8 ^3 c
end 8 G0 W. {# N* S8 F8 w( ^0 l( z4 d/ D
我们从图中分析可以发现这个数据集选5个叶子节点,决策树的数量选取200左右就可以。其实由于该数据集数量较少,总的来说,决策树的叶子数量选取产生的误差相差不大。1 s5 \0 R+ p3 @
8 b) m( N! I* F; ?9 d6 O' q9 x1 @/ p; n
, e# A5 t0 y2 q. X& s( ?: F; F选择好决策树的个数和叶子节点数,后面就可以对数据集进行划分,然后建立随机森林进行分类预测,可以计算出预测误差和每个特征的重要性排名,重要性越大,说明该特征对分类的作用越好。 & d/ P4 F$ J+ f0 E8 I! t' H( Y( S; k1 }1 T+ `% |, m
clc 2 R9 e1 d/ i* [+ jclear9 R, H; L9 q2 @$ }; e
load('data1.mat')9 v5 O: x+ `% Q" Q
Input = data1(2:end,1:end-1) ;1 y! D M; U/ u* r
Output = data1(2:end,end) ;7 m( V: x: `, M$ R
% %% 确定叶子节点和决策树的数量 & U- {' i& F- l- z0 n- A3 q' |# m% for RFOptimizationNum=1:5+ m6 C4 S1 k: r r- P
% RFLeaf=[5,10,20,50,100,200,500]; 1 g0 s1 k/ s4 x" b" h% col='rgbcmyk';' ~+ U' K6 T/ z& `8 r
% figure('Name','RF Leaves and Trees');1 L$ E3 B: Y) }( q. V9 q
% for i=1:length(RFLeaf)& ^: @1 _) n# T- k5 [
% RFModel=TreeBagger(500,Input,Output,'Method','R','OOBPrediction','On','MinLeafSize',RFLeaf(i));1 j0 N3 Z$ z$ C n5 m
% plot(oobError(RFModel),col(i)); + g" q: e7 Q3 `; G9 |$ Y- x; y% hold on6 N/ X0 s+ i. D G& h* G
% end 0 W; y% s0 v' G L% xlabel('Number of Grown Trees');$ e6 ~; E+ U0 C( Q' o- F9 ]
% ylabel('Mean Squared Error') ;; U2 a' C5 q+ R) Y+ i, c
% LeafTreelgd=legend({'5' '10' '20' '50' '100' '200' '500'},'Location','NorthEast');) b) A! N* R, B' T/ t& T' P& o
% title(LeafTreelgd,'Number of Leaves');/ y% Z6 I( q0 r9 O# O6 ^: E! `
% hold off;% I1 S; D+ h# ^
% disp(RFOptimizationNum); / F2 }7 k. G) _+ K/ N* ]7 S, |% end * k7 r, ? k. Q* U% u%% 循环准备 0 W, R# q( N" B [0 vRFScheduleBar=waitbar(0,'Random Forest is Solving...'); 0 Z! ]9 s) p! ]RFRMSEMatrix=[];: {1 \3 ]& O: J) n; V% D7 J
RFrAllMatrix=[];9 {5 w; g6 r$ Z: P+ G9 n
RFRunNumSet=5000; / l, E ], M. O0 Q# D/ Y' Ifor RFCycleRun=1:RFRunNumSet : a$ a) u6 [, Y%% 训练集和测试集的划分 9 D4 M/ `5 M* X# o' NRandomNumber=(randperm(length(Output),floor(length(Output)*0.2)))'; ; |5 b l9 y+ a" ]" VTrainYield=Output; 9 l E2 j. O: }+ M" E( WTestYield=zeros(length(RandomNumber),1); % a% p) B5 m8 T" Q8 t* xTrainVARI=Input;* O0 t; |) I1 g! O0 r! s2 {/ z
TestVARI=zeros(length(RandomNumber),size(TrainVARI,2)); ! S6 }1 J$ y+ v+ z7 ^1 {9 v7 efor i=1:length(RandomNumber)# Q% S! q+ A3 m( ]( E$ ]% W; S
m=RandomNumber(i,1); 1 _8 a2 W( m" e- N- `% q: K TestYield(i,1)=TrainYield(m,1); 1 W' [5 T3 U% x TestVARI(i,=TrainVARI(m,;" i1 z8 m+ v3 n7 R3 C# t
TrainYield(m,1)=0;2 U! \ u! t& r! W; U- @ t
TrainVARI(m,=0; ; W! H! X' @. t# K- ~end / }( `5 r% @6 s$ F9 f& K1 [+ J8 DTrainYield(all(TrainYield==-2,2),=[];: f3 x' I5 S" N, E1 x
TrainVARI(all(TrainVARI==-2,2),=[]; $ |' ]% @* I' _0 N# u( rend 2 L% n7 _- i2 c: z I, P%% 随机森林 6 G1 E; c g* V2 cnTree=200; ! n) V. A# x; j, ]1 m, J- l2 pnLeaf=5; 4 P% B) T+ P* {# ~RFModel=TreeBagger(nTree,TrainVARI,TrainYield,... % G1 W; V ~$ C* f% _) f) T- @ 'Method','regression','OOBPredictorImportance','on', 'MinLeafSize',nLeaf);1 c- r3 ?0 R {" A. F
[RFPredictYield,RFPredictConfidenceInterval]=predict(RFModel,TestVARI);; h5 f I, C; v8 \& {
disp('预测结果:') ; & W- j2 ]& q) R: W4 s& Tdisp(RFPredictYield) ;* H+ K$ J# }$ w8 h& S
%% 计算误差 6 @ F: L( [0 a7 V! \5 ?1 U eRFRMSE=sqrt(sum(sum((RFPredictYield-TestYield).^2))/size(TestYield,1));. L# G+ T5 `6 W% @6 H
RFrMatrix=corrcoef(RFPredictYield,TestYield);1 A' F* r. m+ x9 v S
RFr=RFrMatrix(1,2); 3 Z; Z( i: S4 c. g, O, qRFRMSEMatrix=[RFRMSEMatrix,RFRMSE];$ s# D$ X. M3 H) Y
RFrAllMatrix=[RFrAllMatrix,RFr]; ! w$ ]$ t P% a+ D# y& Qif RFRMSE<1000 , g% O. {. b* F; _5 }$ t' Q& p' _ disp('RFRMSE') ;% ^. C" s: n+ L& c4 R" D' j2 t
disp(RFRMSE); ! T9 ]. U3 E# R+ ~! R0 d- [4 Iend 0 @2 Z4 P. o* L; Z%% 比较特征的重要性 % \ T% G2 A+ z$ J4 m! A& Gfigure ! [/ |1 [$ |) {% ~bar(RFModel.OOBPermutedVarDeltaError) 1 I: Z8 d+ I" F0 C: F- j) T5 t9 uxlabel('Feature Number') 5 e% r7 B+ P1 } f( Z0 L1 l. Aylabel('Out-of-Bag Feature Importance') % ~0 N1 L4 ~0 W6 m, P[mae,rmse,r2,mape] = EvlMetrix(TestYield,RFPredictYield)8 c% B ?' i4 }; t) Z
figure& u; n) E5 M1 Z0 J3 e
plot(TestYield,'b-d') % T( ^. n8 k' S9 m9 a3 @ X% nhold on5 g3 S; i2 {- a! s+ D3 Y. j* S) B
plot(RFPredictYield,'r-d') ! Y2 o! ]! m8 uhold off7 J B$ C$ d- q2 l" l) @+ j
legend('GroundTruth','Prediction') : `( s/ Q9 `& v0 w7 P- b6 O. i# pxlabel('Sample Number') 9 R% c& O- n5 M/ ^ylabel('target Value') 4 T! }' z: S9 O/ E" u* Y7 v3 b0 i" O" R
我就用了两个测试数据,效果不是特别明显。; f: n* y# K( [
# H: Y$ T8 Q* O1 v4 B: S! e8 G5 Y5 u! f. n, ?2 k" r
7 q/ E" C' R; q0 n8 r
下面的是每个特征对分类的重要性,1>3>4>2,这个数据量越大,越准确,因为我的数据量很小,所有效果不是很明显。# z- e9 A, a4 x, B