因为手机屏幕较小,看起来代码格式可能有点不整齐,但是复制到软件里面以后就整齐了,可以直接运行。

1、matlab实现决策树(默认用基尼系数来划分属性)

创建分类决策树或回归决策树

load carsmall % matlab自带数据,可以直接运行。数据包含变量:Horsepower, Weight, MPG

X = [Horsepower Weight];

rtree = fitrtree(X,MPG); % 生成决策树:回归树

view(ctree,'Mode','graph')  % 查看决策树

load fisheriris %matlab自带数据,可以直接运行。% load样本数据

ctree =  fitctree(meas,species); % 生成决策树:分类树

view(ctree,'Mode','graph') % % 查看决策树

用训练好的决策树做数据分类

load ionosphere % 包含变量 X 和 Y

ctree = fitctree(X,Y);

resuberror = resubLoss(ctree)%衡量分类误差,此处可以设置损失函数

Ynew = predict(ctree,mean(X))%变量X的所有列求平均值,生成新的样本数据,判断其分类

检验决策树性能并修正

先说一下交叉验证法,比如将数据分10份,轮流将其中的9份作训练1份做测试,10次的结果的均值作为对算法精度的估计。我们常常采用交叉检验法来验证决策树性能,因为交叉检验法使用的测试数据不同于训练数据,且是一个多次平均的结果,因此其对性能的估计比较准确。并根据交叉检验法进行决策树的修改,使得其性能表现更好。

(1)      限定每个叶节点包含的最少数据量

一般我们需要限定每个叶子的最小的样本量,如果叶子包含的样本量过低,会非常影响决策树的泛化能力。一般情况下都是进行多次尝试,得到最小的叶子尺寸,在生成决策树。

leafs = logspace(1,2,10);

rng('default')

N = numel(leafs);

err = zeros(N,1);

t =  fitctree(X,Y,'CrossVal','On', 'MinLeaf',leafs(n));%交叉验证法估计算法精度

err(n) = kfoldLoss(t);%计算分类误差

plot(leafs,err);

xlabel('Min Leaf Size');

ylabel('cross-validated error');

%根据err得到最小的叶子尺寸,再进行决策树生成

OptimalTree = fitctree(X,Y,'minleaf',40);

resuberror = resubLoss(OptimalTree) %衡量分类误差,默认均方差算法,此处可以设置损失函数

lossOpt = kfoldLoss(crossval(OptimalTree))  %交叉验证误差

(2)      剪枝

与上面类似,计算不同剪枝下的交叉检测误差,选择最小误差处剪枝。

[~,~,~,bestlevel] = cvLoss(ctree,'SubTrees','All','TreeSize','min')

cptree = prune(ctree,'Level',bestlevel);

view(cptree,'Mode','graph') % 查看决策树

%计算剪枝后决策树的重采样误差和交叉验证误差

resubPrune =  resubLoss(cptree)

lossPrune =  kfoldLoss(crossval(cptree))

2、Python实现决策树

Scikit-learn是个比较著名的Python库,被称之为机器学习神器,sklean中包含了大量的我们在做数据分析时候用到的包,使用起来很方便。

from sklearn import tree

X = [[0, 0], [1, 1]]

clf = tree.DecisionTreeClassifier()

clf = clf.fit(X, Y)   #拟合

clf.predict([[2., 2.]])   #预测新样本的分类

clf.predict_proba([[2., 2.]])    #计算属于每个类的概率

sklearn中决策树还可以设置其他参数

DecisionTreeClassifier(class_weight=None,  criterion='gini', max_depth=7,max_features=None, max_leaf_nodes=None,min_impurity_split=1e-07,  min_samples_leaf=10,min_samples_split=20, min_weight_fraction_leaf=0.0,presort=False,  random_state=None, splitter='best')

参数说明:

criterion: ”gini” or “entropy”(default=”gini”)是计算属性的gini(基尼不纯度)还是entropy(信息增益),来选择最合适的节点。splitter: ”best” or “random”(default=”best”)随机选择属性还是选择不纯度最大的属性,建议用默认。max_features: 选择最适属性时划分的特征不能超过此值。当为整数时,即最大特征数;当为小数时,训练集特征数*小数;if “auto”, then max_features=sqrt(n_features).If “sqrt”, thenmax_features=sqrt(n_features).If “log2”, thenmax_features=log2(n_features).If None, then max_features=n_features.max_depth: (default=None)设置树的最大深度,默认为None,这样建树时,会使每一个叶节点只有一个类别,或是达到min_samples_split。min_samples_split:根据属性划分节点时,每个划分最少的样本数。min_samples_leaf:叶子节点最少的样本数。max_leaf_nodes: (default=None)叶子树的最大样本数。min_weight_fraction_leaf: (default=0) 叶子节点所需要的最小权值