EDA365电子论坛网

标题: 决策树算法简介及其MATLAB、Pyhton实现 [打印本页]

作者: pulbieup    时间: 2020-11-20 17:10
标题: 决策树算法简介及其MATLAB、Pyhton实现
目录( R+ t& G# W& n, i9 r) m/ o
' F4 ^& |' Y1 o4 V6 ?: l9 u- x
决策树原理概述
- m/ A0 q8 o# f; x* S& d+ b% F5 t. Q* @% O
决策树的经典算法:ID3算法
( F, B8 D( L' X, L. k
+ {; m# ?6 s* U' W% \* V改进:C4.5算法+ k3 P1 i) n( a6 ^
& [8 O& L8 ]8 o; v  @4 M
Hunt算法
* ^+ }% k( K8 H/ }) f& u
7 ]5 \0 W9 b- N  J8 P" [决策树的优缺点
. s, t0 X' _# Y
4 i9 e$ e  q* B$ AMATLAB实现决策树分类算法2 T1 K9 {' s4 i/ U1 r

5 P; X6 O- `& u( n基于python实现决策树
( J9 a8 n) g6 ~4 x* v" d$ y2 i! V: N1 ~$ n% H3 a  l) f! B/ j" G9 R
+ K2 {  K% x; c( T
2 G! v, ~6 `- O7 s  u. D
决策树原理概述# L1 B7 R$ `& o$ {6 n
9 O% j/ K9 r  {, n# e3 P

* ?: M8 d# m% H% w- m+ q! Z* B1 G
5 h. y+ |# X8 }1 k$ d  s
1 s7 b' ?/ g; X8 a' l2 y

, i8 J4 L! ~8 X, e
' U9 P( r: p9 n. a: f) ?" u
# V, z4 R5 m4 W. y/ k; r4 l, g2 j上图是一个区分动物类型的例子。
3 @9 h0 F$ T% r& j* Z
! ]2 _  Y0 f7 H, Y" P9 f3 ?' f; X6 Q) E! F: _

: p7 C, h5 g% n% s! m
4 K- i+ V; ]: B4 |3 H1 {
6 x5 x& x8 m! c5 b6 k+ \3 t) ]# L3 W& ?& G9 S6 a
# ~3 G& C! P* S; b' q' I  }
决策树的经典算法:ID3算法: z6 A9 v: g: m. L0 g4 P2 y/ t

; m8 F" |3 T* d; J, `/ x% j- ]1 e原则上讲,对给定的数据集,可构造的决策树数目达到指数级。但是由于算力优先,我们只能在一定条件下构造出具有一定准确率的较优的决策树。这些算法通常都是采用贪心策略,在选择划分数据的属性时,采取一系列局部最优决策来构造决策树。
6 u6 Z* P& E/ Z6 f0 n, U4 i7 U% Q$ T0 t; {8 n2 @
Hunt算法是许多决策树算法的基础,包括ID3、C4.5和CART。5 ^0 b# G! T, u0 I) i
1 p! |3 }) }) Q* S, I6 C
4 Z8 G3 z( R( S! m  d; N

7 x7 \* H1 h& a ! `% h/ |7 ]; w: R) B7 z5 \

! y$ M+ J- j% d: R
/ a2 V; M/ @* P0 ~% }; o3 X
/ N3 g" I7 e  l! F信息增益越大代表这个属性中包含的信息量越多。因为它的定义式实际上是熵的变化。
2 C$ F/ [$ G* ?* i/ @7 |/ A. E) \2 E% m/ N
9 k; X0 M- N9 U2 I
改进:C4.5算法
5 d; w8 n- O) e0 j1 Q- g% |- T( f* W( M3 Y

/ x3 a( A0 u9 M5 e针对ID3算法中可能存在的问题,学者提出了一些改进。
# g8 g, u% H4 O7 v! v, a9 i- r, Q: X0 K# d4 a# [+ M
- h7 z' A1 o$ @7 u4 N

+ B) h3 `1 ]! O4 t' B针对上述两种算法,具体解释和举例可以参考:《数据挖掘系列(6)决策树分类算法》,此处不再赘述。* B! }: `. o! B. ]4 @5 `

( x8 @8 l# }9 h
6 S8 t; F$ S7 A" O' wHunt算法
0 u; O7 n4 V4 z6 d
8 a- t# F1 x) t' J; n7 ^& b) ~6 I# f6 x9 F0 v" r( L& [2 H
在 Hunt 算法中,通过递归的方式建立决策树。3 F0 U/ I# M  r$ _1 s: ]
1)如果数据集 D 中所有的数据都属于一个类,那么将该节点标记为为节点。
$ C& H* v- L( k" V) u5 \2)如果数据集 D 中包含属于多个类的训练数据,那么选择一个属性将训练数据划分为较小的子集, 对于测试条件的每个输出,创建一个子女节点,并根据测试结果将 D 中的记录分布到子女节点中, 然后对每一个子女节点重复 1,2 过程,对子女的子女依然是递归的调用该算法,直至最后停止。
1 b$ m: k; N1 p( `+ K) \5 X8 x4 A! q/ V5 o- g; {! |% W
. Z4 V- @+ u- G4 Q8 N. S# X
决策树的优缺点/ v" N. j) ~  N& [. W
+ U( E; v; r4 p: Z

( `+ ~9 d$ Q. w" c% L优点:
( M- W: h# _: h7 ?
4 w" ]. R/ k0 O3 V0 b–  决策树易于理解和实现。 人们在通过解释后都有能力去理解决策树所表达的意义。
+ F3 ?( y1 C8 a: i6 a4 _1 Y! z- R# k' k9 K8 {/ P3 N
–  对于决策树,数据的准备往往是简单或者是不必要的。其他的技术往往要求先把数据归一化,比如去掉多余的 或者空白的属性。2 k: Q$ Y9 e1 @# B5 x
  w. v. s; F2 {1 g& ~% Z% O
–  能够同时处理数据型和常规型属性。 其他的技术往往要求数据属性的单一。/ S) \  Y, w. M/ \7 `4 E2 Z
: i& m, v" N, I7 d* J# k
–  是一个白盒模型。如果给定一个观察的模型,那么根据所产生的决策树很容易推出相应的逻辑表达式。& {5 A" K3 M# P6 ~& E/ k
3 W1 S% B8 j& E3 U
缺点:
: D2 h& Z+ o8 j: d( m
& H# F& S, P! ?2 M2 S' W– 对于各类别样本数量不一致的数据,在决策树当中信息增益的结果偏向于那些具有更多数值的特征。0 D8 F+ p* v$ r, K' ]

- f* u% v4 d' S; B– 决策树内部节点的判别具有明确性,这种明确性可能会带来误导。6 u6 g) x$ O1 ]% }8 g+ ~6 \

1 X0 ^' O, s$ a$ L/ x+ Z/ Q" |MATLAB实现决策树分类算法) G( T0 q) L6 D+ G# Z. h2 {: N! q
5 M8 C' c' A8 m5 e/ D. [& w! I
%% I. 清空环境变量
4 q( k8 }3 G8 W' Qclear all
; R/ K, _# r9 e2 X% h& Cclc
# H9 W$ A6 A$ ]5 bwarning off
6 D& c3 V$ y) ?1 h& K
- ~. ]8 D/ S9 }9 o$ L1 k! j%% II. 导入数据
& F+ V3 F) Z% B( c5 B0 Sload data.mat
. m2 Y" }3 H# { 6 h- z) p' E  F& |$ k6 C
%%6 A6 p; L- i1 D4 Q/ I$ }
% 1. 随机产生训练集/测试集
( e6 d1 x  f! U2 M5 N$ x& p, _6 za = randperm(569);( K0 C6 |' r! ^7 h
Train = data(a(1:500),: );
% Z$ w6 B3 Q7 }* `5 U: QTest = data(a(501:end),: );
& c$ H6 G9 a; b1 h, v" a 4 o0 ~$ I8 f6 Y0 |. P& }
%%
; p( i: G9 R8 e- |0 e. v5 I% 2. 训练数据9 F' H* V! V) d/ ]4 J9 H* [# z
P_train = Train(:,3:end);
0 S3 {7 H5 L! OT_train = Train(:,2);
" L& b. C$ s. ]. ^3 O8 r
0 b9 N  x! t- l0 Q$ j%%! {& [6 P- q# `, b1 s( @
% 3. 测试数据( B" r  P9 u1 O5 l9 ?) }
P_test = Test(:,3:end);6 [8 a! f. [4 D& M$ j* w. B' C
T_test = Test(:,2);
1 e, N/ G$ ~+ p' Z& j
9 m: Y: o1 F* s( N; ^( [0 D%% III. 创建决策树分类器' n5 w! s) [9 \2 O- V  k* x" k! R) L
ctree = ClassificationTree.fit(P_train,T_train);
! |% L2 J: e- W' W- y
' p; z, T, \; l3 n7 w0 `" ~%%
( n, {. O4 v6 i+ n8 l3 a0 r% 1. 查看决策树视图
1 O+ g  t$ y2 [/ r2 Zview(ctree);1 n6 k+ p# S7 t; m
view(ctree,'mode','graph');; x/ q0 O# T2 V/ L# e- j6 _
; n" K- @- R# J% W5 r
%% IV. 仿真测试
& g. r: P3 R5 w" u$ FT_sim = predict(ctree,P_test);1 f% X" G; C7 T

( C; e- F+ N; q%% V. 结果分析
- h3 a- v8 {4 @2 U& J! Gcount_B = length(find(T_train == 1));
8 T: g* C. {* Bcount_M = length(find(T_train == 2));. `: ]7 g% t4 J/ I! H7 J
rate_B = count_B / 500;
5 s. x! X+ |8 i5 g  Xrate_M = count_M / 500;( Y4 j! a8 `! f( r
total_B = length(find(data(:,2) == 1));% W" J. ~* p) P! z
total_M = length(find(data(:,2) == 2));9 `+ Q& _  P  F+ {3 e& K0 c& {2 I' S
number_B = length(find(T_test == 1));3 @7 S( j( o# [' O/ c
number_M = length(find(T_test == 2));
$ S2 t2 l6 Q" V7 Z: inumber_B_sim = length(find(T_sim == 1 & T_test == 1));9 H  n2 `# @6 j2 q
number_M_sim = length(find(T_sim == 2 & T_test == 2));3 m; R/ W( W$ V) ^, x
disp(['病例总数:' num2str(569)...9 E+ s9 G* z, y
      '  良性:' num2str(total_B)...
) N5 M# ^" ?+ u  b/ O3 T, r! C" t/ c1 W      '  恶性:' num2str(total_M)]);
: N, N9 g9 G: c( @disp(['训练集病例总数:' num2str(500)...
$ ?/ h$ K& v3 w8 v% N) o% ?1 @5 ]7 N      '  良性:' num2str(count_B)...
8 ^2 ~/ ?8 F: F& L: q6 e      '  恶性:' num2str(count_M)]);1 a: T$ |( R5 n: z
disp(['测试集病例总数:' num2str(69)...
. N1 f6 D: v0 d* L* I9 Z      '  良性:' num2str(number_B)...
$ f9 I# Z* o8 w% {      '  恶性:' num2str(number_M)]);
! h" d( `# a& y5 P6 D3 A; @disp(['良性乳腺肿瘤确诊:' num2str(number_B_sim).../ X6 L6 t+ Q& \2 B
      '  误诊:' num2str(number_B - number_B_sim)...
: R0 ~5 b' w- l8 ?; e0 z      '  确诊率p1=' num2str(number_B_sim/number_B*100) '%']);
( o6 m, v( c3 N6 Z0 ~) Y1 Zdisp(['恶性乳腺肿瘤确诊:' num2str(number_M_sim)...( E6 p  y: S5 k$ U
      '  误诊:' num2str(number_M - number_M_sim)...; c3 z$ u; X" T8 v0 V2 f/ w* M7 ?
      '  确诊率p2=' num2str(number_M_sim/number_M*100) '%']);5 l# x. A( }# R, S" Q4 ^3 b
  
% F) {0 ]6 t! Z- Z& G%% VI. 叶子节点含有的最小样本数对决策树性能的影响; T2 v3 i; V$ H  ^$ W# m, v3 l5 K0 i
leafs = logspace(1,2,10);; G6 ?$ Q4 J2 ~1 n

% f( k1 J  k  w) i" W5 H0 KN = numel(leafs);
$ y+ D* b- l7 N + ]" F4 x9 e4 w3 _2 M( r: M
err = zeros(N,1);
! K% V' a% L4 l9 x- M! z5 |for n = 1:N
6 e* ?% P8 i+ b6 W* `% z; x7 }    t = ClassificationTree.fit(P_train,T_train,'crossval','on','minleaf',leafs(n));
7 u2 T; _/ s* `    err(n) = kfoldLoss(t);
( d, g& c9 i3 J4 zend
0 y2 M% m; Q, w" c" Lplot(leafs,err);5 K  \4 P3 s, O
xlabel('叶子节点含有的最小样本数');- a2 h' T6 Z# ]( l, K
ylabel('交叉验证误差');
+ L/ u9 `4 K& m/ [title('叶子节点含有的最小样本数对决策树性能的影响')
# X+ x! b8 Q; [
) k0 f. u) g6 c$ L5 V%% VII. 设置minleaf为13,产生优化决策树
+ y$ c0 E$ ?. |. b3 rOptimalTree = ClassificationTree.fit(P_train,T_train,'minleaf',13);
  l$ y& E; x) y( b8 Jview(OptimalTree,'mode','graph')0 I* o/ N' c2 w6 S

( K/ J7 ]( \& h- J. x$ M* }%%
4 T- M' W) [- X% W% 1. 计算优化后决策树的重采样误差和交叉验证误差
( i; A& n9 ~8 ?$ _1 c' H, uresubOpt = resubLoss(OptimalTree)3 X: N) C/ R* N% i4 d/ M& R9 G) E
lossOpt = kfoldLoss(crossval(OptimalTree))! m( M8 N: F9 |2 ^* m$ G! T: F2 O
6 i& m% Z& E( B
%%
, S' H9 m7 C. q& Z% W% 2. 计算优化前决策树的重采样误差和交叉验证误差
& c) r9 I3 P& a- r, T1 S$ _resubDefault = resubLoss(ctree)
) @# C! P, V/ j# J! n6 `lossDefault = kfoldLoss(crossval(ctree))+ d$ r  H) D5 S

( Q4 H$ k% Y  g9 e%% VIII. 剪枝  t! n3 c' s: i- K
[~,~,~,bestlevel] = cvLoss(ctree,'subtrees','all','treesize','min')
  j3 }( k- W, S. U. N! @; ucptree = prune(ctree,'Level',bestlevel);6 `: k' y7 }! P! g$ B' O  b
view(cptree,'mode','graph')
4 N) N1 N( K4 H
$ M* Z% @5 [- E0 u%%: A2 k; G3 y8 z, t' v1 q
% 1. 计算剪枝后决策树的重采样误差和交叉验证误差
3 D" X0 [# U+ E* {( o0 z; o- D. b% HresubPrune = resubLoss(cptree)
8 f0 g+ Z  z6 \. clossPrune = kfoldLoss(crossval(cptree))
' @+ f- ]7 M. \: k
  g/ [6 [" g4 s0 T0 b% x% L
7 ^+ ?7 c" X4 g- h5 k0 z4 w+ H, y7 h基于python实现决策树
9 a" r# E5 _/ J) o. n. m. h
' {& f: e. V4 A! G1 f. d
7 p. y/ {* @! ~. a, l' ]9 w1)python实现熵计算:
2 C0 Q  U$ g2 d! R
2 v6 A/ ^& A  D- E1 Xdef calcShannonEnt(dataSet):
* A& ?: Q6 e5 ~    numEntries = len(dataSet) , N; }' ]; _. U& Z3 C8 @5 `
    labelCounts = {}, X% ?1 y; M2 q
    for featVec in dataSet:
$ U  }. ~- Z9 k% a        currentLabel = featVec[-1]
% |# L( I0 r" s3 l/ ]: ]        if currentLabel not in labelCounts.keys():
  H! a2 V) }- q* L* _            labelCounts[currentLabel] = 0
  \% u# v; _/ ]  B        labelCounts[currentLabel] += 15 B& E* M1 x) f7 R4 |
    shannonEnt = 0.0
" M' i, N$ f( b( {; D    for key in labelCounts:$ v, o  E# Y! F- z
        prob = float(labelCounts[key])/numEntries
% M; R2 @# K6 c2 L        shannonEnt -= prob*log(prob,2) 5 C( F+ U) J+ ^
    return shannonEnt. Q1 ~- a7 S" m& q9 g- K

0 \4 T# k' V) ^# z( n3 C
4 o6 q# d4 W; C8 `  y3 ^& F2)SKlearn.tree介绍及使用建议:. K- d0 Q6 o, }
. X, b- \: o7 o
官网:http://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html
/ E* _+ x9 a6 w1 {
0 Z1 C- i8 [; [# y4 xclass sklearn.tree.DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=None, min_samples_split=2,min_samples_leaf=1, max_f eatures=None, random_state=None, min_density=None, compute_importances=None,max_leaf_nodes=None)
: r8 i" h, |; D4 T8 R4 z* O: y
, d4 s# ?  H/ n# l  M9 Y. `6 G$ A重要参数:% g$ J" a; d5 U6 }, e
4 R0 T/ w8 l4 N# U. z
criterion :规定了该决策树所采用的的最佳分割属性的判决方法,有两种:“gini”,“entropy”。/ f5 N+ L5 c+ w2 Q: I  t
- l, N9 l. F* J/ Y# P( I
max_depth :限定了决策树的最大深度,对于防止过拟合非常有用。
1 e9 O+ D5 X$ t5 N% F$ U9 L% k" s; @
+ k* O$ `1 F" ^4 E' C/ M' Q% Tmin_samples_leaf :限定了叶子节点包含的最小样本数,这个属性对于防止上文讲到的数据碎片问 题很有作用5 q9 o7 Y  i( H6 h( H: T% ^

7 q) H# q( \% b5 i重要属性方法:
9 C$ B2 s$ p7 T) F" q! K6 e- [$ ]& j1 C  `/ ]6 D8 e9 T
n_classes_ :决策树中的类数量。classes_ :返回决策树中的所有种类标签。
7 q. z1 U9 ?2 P7 u) F& d0 vfeature_importances_ :feature 的重要性,值越大那么越重要。
9 U+ {3 X5 z" h7 afit(X, y, sample_mask=None, X_argsorted=None, check_input=True, sample_weight=None):将数据集 x,和标签集 y 送入分类器进行训练,这里要注意一个参数是:sample_weright,它和样本的数量一样长,所携带的是每个样本的权重。; q3 {  ?6 F, z9 a. M
get_params(deep=True):得到决策树的各个参数。# I0 l2 m+ R% @+ Q8 B
set_params(**params):调整决策树的各个参数。/ A/ |8 C" R6 d
predict(X):送入样本 X,得到决策树的预测。可以同时送入多个样本。% T, x, U( c# L' s) S2 C3 w
transform(X, threshold=None):返回 X 的较重要的一些 feature,相当于裁剪数据。, `/ u( {& i+ I6 o3 `
score(X, y, sample_weight=None):返回在数据集 X,y 上的测试分数,正确率。: N* R0 n2 }" I7 x6 t
, |8 t% h8 Z" O9 P5 `4 F* F& V
使用建议:4 n4 l+ O! m% S# q. q6 q
9 h; ?6 K# ~; a% C  I: o

! p+ A# c/ M9 C. C$ c$ H# p: p; \+ w  Z  ~+ \# t

5 V. \' `3 K& y- m3 u- i% @* ^9 [
9 t4 Z2 z1 F2 v2 [- T
; f# I  ~: J# t% K$ T
, X1 @  _# @% ]: t

作者: NingW    时间: 2020-11-20 17:42
决策树算法简介及其MATLAB、Pyhton实现




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2