二十五.决策树之CART决策树的原理和sklearn实现

1.简介

CART算法采用的是基尼系数作为划分依据。
ID3、C4.5算法生成的决策树都是多叉树,而CART算法生成的决策树为二叉树。

2.基尼系数

基尼系数代表了信息的不纯度,基尼系数越小,不纯度越低,特征越好。
在分类问题中,假设有 K K K个类别,第 k k k个类别的概率为 P k P_{k} Pk,则基尼系数为:
G i n i ( P ) = ∑ k = 1 K P k ( 1 − P k ) = 1 − ∑ k = 1 K P k 2 Gini(P)=\sum_{k=1}^{K}P_{k}(1-P_{k})=1-\sum_{k=1}^{K}P_{k}^{2} Gini(P)=k=1KPk(1Pk)=1k=1KPk2
在二分类问题中,如果第一个类别的概率为 P P P,则基尼系数为:
G i n i ( P ) = 2 P ( 1 − P ) Gini(P)=2P(1-P) Gini(P)=2P(1P)

3.CART分类树

(1)数据集的基尼系数

数据集 D D D,输出有 K K K个类别,第 k k k个类别的样本集合为 C k C_{k} Ck,则数据集 D D D的基尼系数为:
G i n i ( D ) = 1 − ∑ k = 1 K ( ∣ C k ∣ ∣ D ∣ ) 2 Gini(D)=1-\sum_{k=1}^{K}(\frac{|C_{k}|}{|D|})^{2} Gini(D)=1k=1K(DCk)2

(2)数据集对于某个特征的基尼系数

根据某个特征 A A A的某个取值 A i A_{i} Ai,将样本分为两个子集 D 1 , D 2 D_{1},D_{2} D1,D2,则数据集 D D D在对于特征 A A A的基尼系数为:
G i n i ( D , A ) = ∣ D 1 ∣ ∣ D ∣ G i n i ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ G i n i ( D 2 ) = ∣ D 1 ∣ ∣ D ∣ ( 1 − ∑ k = 1 K ( ∣ C 1 k ∣ ∣ D 1 ∣ ) 2 ) + ∣ D 2 ∣ ∣ D ∣ ( 1 − ∑ k = 1 K ( ∣ C 2 k ∣ ∣ D 2 ∣ ) 2 ) \begin{aligned} Gini(D,A) &=\frac{|D_{1}|}{|D|}Gini(D_{1})+\frac{|D_{2}|}{|D|}Gini(D_{2})\\ &= \frac{|D_{1}|}{|D|}(1-\sum_{k=1}^{K}(\frac{|C_{1k}|}{|D_{1}|})^{2})+\frac{|D_{2}|}{|D|}(1-\sum_{k=1}^{K}(\frac{|C_{2k}|}{|D_{2}|})^{2}) \end{aligned} Gini(D,A)=DD1Gini(D1)+DD2Gini(D2)=DD1(1k=1K(D1C1k)2)+DD2(1k=1K(D2C2k)2)
其中, C 1 k C_{1k} C1k为数据集 D 1 ∣ D_{1}| D1中输出类别为 C k C_{k} Ck的集合; C 2 k C_{2k} C2k为数据集 D 2 ∣ D_{2}| D2中输出类别为 C k C_{k} Ck的集合。

(3)连续值特征处理

连续特征的处理方式采用离散化。
数据集 D D D的特征 A A A m m m个取值,从小到大排列为:
( A 1 , A 2 , A 3 , . . . , A m ) (A_{1},A_{2},A_{3},...,A_{m}) (A1,A2,A3,...,Am)
划分出 m − 1 m-1 m1个取值点:
( T 1 , T 2 , T 3 , . . . , T m − 1 ) (T_{1},T_{2},T_{3},...,T_{m-1}) (T1,T2,T3,...,Tm1)
其中:
T i = A i + A i + 1 2 T_{i}=\frac{A_{i}+A_{i+1}}{2} Ti=2Ai+Ai+1
将小于 T i T_{i} Ti的样本划分到集合 D T − D_{T}^{-} DT,大于 T i T_{i} Ti的样本划分到集合 D T + D_{T}^{+} DT+, 计算其作为二元离散值时的基尼系数。
在选择分裂特征时,要遍历样本所有特征的所有分割点,选择基尼系数最小的作为分裂依据,其余的分割点会在接下来的计算中继续参与选择。

(4)离散值特征处理

CART回归树会枚举离散特征的所有二元组合,选择基尼系数最小的进行分裂,剩余组合会在接下来的分裂中继续计算。
例如离散特征 A A A有三个取值 ( A 1 , A 2 , A 3 ) (A_{1},A_{2},A_{3}) (A1,A2,A3),可以将其二元分类为三种情况:
( A 1 ) , ( A 2 , A 3 ) ( A 1 , A 2 ) , ( A 3 ) ( A 1 , A 3 ) , ( A 2 ) (A_{1}),(A_{2},A_{3})\\ (A_{1},A_{2}),(A_{3})\\ (A_{1},A_{3}),(A_{2}) (A1),(A2,A3)(A1,A2),(A3)(A1,A3),(A2)
计算这三种组合的二元基尼系数,如果最终选择的分裂组合为 ( A 1 ) , ( A 2 , A 3 ) (A_{1}),(A_{2},A_{3}) (A1),(A2,A3),则剩余的两个取值 A 2 , A 3 A_{2},A_{3} A2,A3会在接下来的分裂中继续参与计算。

(5)缺失值的处理

参考C4.5缺失值处理方式。

(6)CART分类树流程

输入:训练集 D D D,基尼系数阈值,样本个数阈值,深度阈值。
输出:决策树 T T T
a.分别计算当前节点的样本数,当前数据集的基尼系数,当前树的深度,如果小于阈值,则停止递归。
b.遍历当前节点的所有样本的所有特征的所有取值,计算出每一个分割点的基尼系数,选择基尼系数最小的进行二分裂。
c.重复以上步骤,知道达到要求。

4.CART回归树

与分类树相比,回归树主要有一下两点不同。

(1)连续值的处理

分类树采用的分裂依据为基尼数,而回归树采用了方差来度量。
对于特征 A A A,遍历其所有的划分点 T T T,根据划分点将样本分为 D 1 , D 2 D_{1},D_{2} D1,D2两个子集,计算其方差,选择方差最小的某个特征的划分点进行分裂。
min ⁡ A , T [ ∑ x i ∈ D 1 ( x i − c 1 ) 2 + ∑ x i ∈ D 2 ( x i − c 2 ) 2 ] \min_{A,T}[\sum_{\mathbf{x}^{i}\in D_{1}}(\mathbf{x}^{i}-\mathbf{c}_{1})^{2}+\sum_{\mathbf{x}^{i}\in D_{2}}(\mathbf{x}^{i}-\mathbf{c}_{2})^{2}] A,Tmin[xiD1(xic1)2+xiD2(xic2)2]
其中, c 1 , c 2 {c}_{1},{c}_{2} c1,c2 D 1 , D 2 {D}_{1},{D}_{2} D1,D2的均值。

(2)预测值(叶节点)的输出不同

在CART分类树中,叶节点的输出会根据该节点样本类别进行多数表决。
回归树则将叶节点的均值或者中位数作为样本的预测值。

5.sklearn实现CART决策树

(1)分类树

#数据预处理
#深度为5的决策树进行训练
#评价
from sklearn import datasets,model_selection,metrics,tree,preprocessing
iris = datasets.load_iris()
x,y=iris.data,iris.target
x=preprocessing.StandardScaler().fit_transform(x)
x_train,x_test,y_train,y_test=model_selection.train_test_split(x,y)
model1=tree.DecisionTreeClassifier(max_depth=5)
model1.fit(x_train,y_train)
y_pred=model1.predict(x_test)
print(metrics.accuracy_score(y_pred,y_test))

输出:

0.9473684210526315

(2)使用网格搜索寻找最佳深度

parameters={'max_depth':[2,5,7]}
model2=tree.DecisionTreeClassifier()
cvModel=model_selection.GridSearchCV(model2,parameters,cv=5)
cvModel.fit(x_train,y_train)
print(cvModel.best_score_)
print(cvModel.best_params_)

输出:

0.9553359683794467
{'max_depth': 5}

(3)回归树

boston = datasets.load_boston()
x2_train,x2_test,y2_train,y2_test=model_selection.train_test_split(boston.data,boston.target)
model3 = tree.DecisionTreeRegressor()
model3.fit(x2_train,y2_train)
y2_pred = model3.predict(x2_test)
print(metrics.mean_squared_error(y2_pred,y2_test)

输出:

15.873543307086615
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值