机器学习-多元分类/回归决策树模型(tree包) ( Y" E4 ~5 H- p# ?" r( x % d2 E1 v( e. c( p2 u9 z决策树(Decision Tree):Tree-Based方法用于多元数据的分类和回归。决策树点是再现了人类做决策的过程,树可以图形化显示,很容易解释。但是树的分类和回归准确度比不上其他分类和绘图模型。决策树是随机森林、boosting等组合方法的基本组件,组合大量的树通常会显著提高模型的预测准确度,但会损失一些解释性。定性与定量变量均可用于Tree-Based方法。tree\rpart\mvpart均可进行多元树分析及绘图。此文介绍如何使用tree包进行多元分类/回归决策树分析。 % z1 B8 z, ^7 f- L% R& s* m$ O1 a, W1 ^# k0 O
一、 准备数据 # r! f* J* Z. c' q2 R + C' X! K6 c% A W8 F- p$ a' k7 Q虚构微生物组和环境因子数据,包含75个样本。: I1 T1 n9 G9 f4 O- y
. h) h0 u+ R9 t$ v e& F
# 1.1 导入数据' g: U9 n" y0 Q" a# X# I
## 微生物组数据 0 W/ Z) o- }. w# u/ z2 j; a' |, Rspe = read.csv("spe.csv",row.names = 1,header = TRUE,check.names = TRUE,stringsAsFactors = TRUE) 3 R0 _1 H6 T( b' z, B0 \
dim(spe)! I; L* ^- D* i5 \
head(spe)+ A+ d9 K7 z2 ~) {/ d1 K; v6 p( t
& b. C& D5 c+ N3 e## 环境因子数据1 E! I% d3 `6 h, R3 c& @
env = read.csv("env.csv",row.names = 1,header = TRUE,check.names = TRUE,stringsAsFactors = TRUE) & e0 h4 j7 F5 u
dim(env) 5 A& c" B: ]- t* A4 a" u# t2 Ihead(env) ; m4 X1 w# h4 f0 ?7 H6 t- }# F1 _+ [ t' {! c4 k
9 b! x' h9 \- d( K r4 e) o
图1|原始otu表,spe.csv。前两列为分类信息。 $ x6 n( ?" Z: t' C2 F) [0 `& l/ h" x# C
" ~8 `' p9 L2 {$ \$ b* d $ r+ E6 o4 N" t) I/ A' b图2|环境因子数据,env.csv。- l7 c5 @# p0 ?& ~
) v. n( D R5 E8 x L% i8 C/ L) b+ s
二、决策树回归模型7 J+ K) q8 w. i7 o1 l$ E4 V
当因变量为定量变量时,决策树进行回归分析。分析时先基于自变量划分预测空间Rj,此时残差平方和(residual sum of squares,RSS)值最小,然后对于落入某一预测空间的样本,做相同的预测。$ p9 x9 F' n D0 S3 h0 B: a
$ e* o0 {0 j/ w' L9 b( [6 R , C; u0 Z$ S& C. y9 m8 [- P0 J2 {# r$ y9 h$ ]" C
但是考虑到所有自变量的预测空间构建基本很难实现,因此常使用递归二进制拆分(recursive binary splitting)。每一步的拆分都使RSS减少量最大。 " ^6 b: G( R8 e5 I- _8 c7 E7 H. M, t4 b* t; T
如拆分点(cutpoint)为s,则拆分空间R1和R2为:/ M- S( l; Y) c1 j5 s! o
7 R- X: Y8 v0 S
" O7 R. R. X( H; Z / K& \; r N2 Mj和s的选择基于使RSS最小化: ( ?; J0 T- u, K7 |0 I 7 p5 M9 k' M- k6 {" \. @6 p 5 l- }' L+ N. w, J. O" C& {6 o/ Y* \5 R% w* n2 n; t5 A. @) [3 m+ N9 F$ G
后面重复此过程,寻找最佳预测空间和拆分点,从而使每个结果区域的RSS值最小,直到达到终止拆分标准,比如每个终端节点包含的样本数都不高于设定的阈值。 0 q. A% u. e( B | 8 a' x3 A! O. ]; U2.1 构建回归决策树 & T& G' T; r. M: v6 t使用微生物数据与环境因子数据进行决策树回归分析。为了更好的评估分类树的分类性能,不能只计算训练误差,需要估计测试误差。将数据分为训练集和测试集数据,训练集数据用于构建模型,测试集数据用于模型评估。 5 U: d( o4 B |8 v% u T, I8 _- {8 ^4 ]4 M! o. r* Y
# 2.1.1 将数据集分为train和test集,用train结果预测test的因变量值。 ; g5 Q: l1 T5 b8 a" xlibrary(splitstackshape)3 L" R$ O! {3 [/ \% c2 f
spe = data.frame(ID = rownames(spe),spe)# stratified提取后,样本名会消失,先提取样本名,重新构建数据框。6 T% [3 |$ q3 T# x, }
$ C/ S% D- B6 J( I1 {0 s
## train data sets,每个分类提取相同数目的样本用作训练集 # _* Z P8 `- [0 q+ ~" d4 \! V; `set.seed(12345) " k' z9 u" c. Ktrain.spe = stratified(spe, group=c("grazing"),size=10,replace=FALSE) 1 n/ J i1 m8 Ftable(train.spe$grazing) # 每个分类提取的样本数一致。3 n, F, m# R* |
( a( g5 }) j! w+ F- y0 b% X9 T4 U) M7 D
train.env = env[rownames(env) %in% train.spe$ID,], Z, E: Y% L. \& {0 B, Z
table(train.env$grazing) # 每个分类提取的样本数一致。 5 x& w5 i1 K2 X+ i, O8 a2 A/ A D6 S0 H/ V9 w8 }7 t u- g9 K# i
## test data sets a+ _ P& \% v
test.spe = spe[!spe$ID %in% train.spe$ID,] 7 D$ ^' Z; M9 M8 M! Etable(test.spe$grazing) 6 e/ s$ N7 R( M* |# x. O4 ? K g2 v( `7 R1 a
test.env = env[!rownames(env) %in% rownames(train.env),]2 \) w% d+ r [6 g7 z! r5 P5 A
table(test.env$grazing)5 W' z, y; u* o( g/ z, x! n6 Q
x6 D m) E7 w
#install.packages("tree") ! X9 ]# T# B" p( ~library(tree)# F! T8 V3 Q2 X$ X' g1 I
; O8 d& h# k8 V
# 2.1.2 构建回归决策树 & h0 s! E8 E& @7 M2 N9 F) {reg.tre = tree::tree(train.env$env1 ~.,data=train.spe[,-c(1:3)])4 d' X7 V' F9 T4 E) S, W! L
reg.tre: g! x+ Q1 o" `2 ]
0 L# i# w. r3 t3 @
# 2.1.3 输出结果简介 ) ?3 s6 j1 u5 a" [: A; I## 输出表格的行为节点名(整数值表示),包含9列数据。 3 d3 P6 j# ^& y* E. S8 `4 sreg.tre$frame 6 h* i* r8 e [9 o% f## 列包括var:用于拆分节点的变量及终端节点(<leaf>); + Z4 X, s3 p) hreg.tre$frame$var- F- n+ C9 Q1 s& `
## n:每个节点的样本数量; 7 `7 F* O$ L* P6 o2 Freg.tre$frame$n 6 I1 c; U0 X( M9 U1 O## dev:每个节点的偏差1 k/ O5 d: D7 F3 e
reg.tre$frame$dev ~/ S! U8 i7 M## yval:拟合结果,回归树为节点包含样本的因变量均值,分类树为该节点样本最多属于的分类水平;# H# Z- z/ O' `, m* l; X
#mean(train.env[reg.tre$where == 4,3]) # 第四个节点包含样本的因变量均值。2 B! U% V9 E8 O
reg.tre$frame$yval( ]; M! U# w0 e# `" t
: y; i0 k1 G* B R( }2 a
## split: 节点拆分,2列分别是属于左侧或右侧的标签; 8 W/ J' n/ V# q2 q4 L: ireg.tre$frame$splits+ f' L" D1 o& F, j$ O6 @1 Z, P* B
## yprob:回归树,此为NULL;分类树则为因变量各水平的拟合比率,此数据有5个处理,所以有5列。 * u* O, q/ y; a- p& v3 B) ereg.tre$frame$yprob: X7 g4 U9 {" y$ M2 K L
/ Y6 E) Z: a, s; I5 f& h+ k, {## output,需要输出行名,则设置row.names=TRUE。% N1 x6 \4 o& O! f
write.table(reg.tre$frame,"reg_tre_res.txt",sep="\t",quote = FALSE,row.names = FALSE)" o: m- l" r6 s5 P
' ]) h& O( S( N* X; U; U4 v## 每个样本所属节点 9 z5 M( m" q- {) S" p' W. nreg.tre$where 9 r5 m# \: ]$ z/ T9 l! C## formul形式' M! ^2 t+ f M2 F6 x, i
reg.tre$terms # h! L2 w& A5 s# P, L## 自变量数据,x=FALSE则不会返回此数据 0 s0 A) i& M) z% l) P/ ?0 ~+ [; D Preg.tre$x , K) R8 Q( {) }2 M1 t4 D( M## 因变量,y=FALSE则不会返回此数据 3 I( r8 C: ]; p5 g _reg.tre$y' T! T/ p# F/ T/ L; x
## 样本权重,未设置则均为1,权重值可以为分数形式。2 X" ?6 |7 H/ | v/ j: h
reg.tre$weights ( c e% x9 C( q& A0 [( q+ P$ z2 O9 p# o/ ]2 {! P3 U: f* o; m
## 结果描述统计" e; z+ a1 z+ f
reg.tre.res = summary(reg.tre) 5 u: \7 x/ ` ~) [" }6 x$ }8 `- O2 Rreg.tre.res8 e6 h4 @* L U7 L) ^
reg.tre.res$used # 用于构建回归决策树的自变量. _& N' L: ?6 U' d$ S
reg.tre.res$dev # 偏差,决策树的残差平方和。 , m5 P2 b4 A# F9 M, i) Lreg.tre.res$df # 训练样本数减去终端节点数: B: Q4 B" A0 P6 ~' f% z
reg.tre.res$residuals# 每个训练样本因变量的残差 0 Z1 o% c- R+ J1 d2 x; v2 e 0 z" ]3 ]: W, X8 i( k) r, R## 简单绘图 0 q, Y+ q m/ ~% ]- dplot(reg.tre), A& w" Q9 ^, _7 h& f% @3 q
text(reg.tre,pretty = 0)6 j5 f. U9 G$ x$ N
: c$ a/ ^2 ^/ ~% `, W# a$ @; l/ L# 2.1.4 预测测试集数据 " y/ {( [; ]$ {' T! i/ ~& ureg.pred = predict(reg.tre,newdata = test.spe[,-c(1:3)]) / L8 o$ Q! Y L$ a6 N. W/ p8 c+ Hreg.pred ' @5 f# G; {- x; U5 b## 预测结果与原始结果绘图 " t/ C# N* V6 j) J$ dplot(reg.pred,test.env$env1) $ _5 |. W3 _! B- Cabline(0,1) F E) m/ U5 b3 k- n7 e# x3 e' z+ j# K. Y1 D& d9 z5 N+ n
## 计算残差平方和(MSE)和标准化均方误差(NMSE)+ p5 G0 B- T& q6 C0 F. a
MSE0 = mean((reg.pred-test.env$env1)^2) 3 f7 {% z: i! j3 V$ \2 g1 vMSE0 3 A) z. J) M7 [5 X8 WNMSE0 = mean((test.env$env1-reg.pred)^2)/mean((test.env$env1-mean(test.env$env1))^2)7 O. w i1 F7 K1 N& \
NMSE0" B6 v$ T; n0 x6 Q
% _* A+ U/ J4 q5 G& n
# L/ U! \# e9 m& K8 Q
{1 o5 F+ G0 `, k& S
图3|回归树构建结果,reg.tre。每个节点以整数标注,tree()默认树最大生长数值为31。因子变量的分类水平不能超过32。2 R/ H, D. ? d/ a+ u6 u
1 ^( L3 e; l, f$ J$ y; v