机器学习之决策树剪枝-决策树调优的一种常见并且有效的手段

第一部分:决策树的缺点

(1)训练的复杂度过高

这个详细的源代码可见机器学习实现决策树Decision Tree-CSDN博客

这里面有详细的进行决策树的代码,每个节点的处理过程分为两层for循环和内部的一层计算熵的函数。

(2)比较容易过拟合

这个和knn非常相似,都属于非参数的学习方式,比较容易出现过拟合现象。

第二部分:剪枝的目的(降低复杂度+解决过拟合)和手段

(1)存在过拟合的代码(以鸢尾花数据集为例,使用决策树分类算法)

①导包

#第一部分:导包
import numpy as np
import matplotlib.pyplot as plt

②加载数据集

#第二部分:加载数据集
from sklearn.datasets import load_iris
iris = load_iris()
x=iris.data[:,0:2]#选择前两个特征
y=iris.target
plt.scatter(x[:,0],x[:,1],c=y)
plt.show()

③使用决策树进行分类

#第三部分:使用决策树进行分类
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier()
clf = clf.fit(x,y)

④使用决策边界来绘制样本点分类散布情况

#第四部分:使用决策边界来绘制样本点分类散布情况
def decision_boundary_plot(X, y, clf):
    axis_x1_min, axis_x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    axis_x2_min, axis_x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    x1, x2 = np.meshgrid(np.arange(axis_x1_min, axis_x1_max, 0.01),
                         np.arange(axis_x2_min, axis_x2_max, 0.01))
    z = clf.predict(np.c_[x1.ravel(), x2.ravel()])
    z = z.reshape(x1.shape)
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#F5B9EF', '#BBFFBB', '#F9F9CB'])
    plt.contourf(x1, x2, z, cmap=custom_cmap)
    plt.scatter(X[:, 0], X[:, 1], c=y)
    plt.show()
decision_boundary_plot(x,y,clf)

从这个图中就可以看出来,图形分布交错混乱,也就是过拟合的表现。

⑤可视化分类结构图

#第五部分:可视化分类结构图
from sklearn.tree import plot_tree
import matplotlib.pyplot as plt
# 绘制决策树
plt.figure(figsize=(10, 6))  # 设置图像大小
plot_tree(clf, filled=True)  # `filled=True` 会为不同的类别填充颜色
plt.show()

可以看到,真正的树总共有13层,过拟合!

⑥完整pycharm代码

#第一部分:导包
import numpy as np
import matplotlib.pyplot as plt
#第二部分:加载数据集
from sklearn.datasets import load_iris
iris = load_iris()
x=iris.data[:,0:2]#选择前两个特征
y=iris.target
plt.scatter(x[:,0],x[:,1],c=y)
plt.show()
#第三部分:使用决策树进行分类
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier()
clf = clf.fit(x,y)
#第四部分:使用决策边界来绘制样本点分类散布情况
def decision_boundary_plot(X, y, clf):
    axis_x1_min, axis_x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    axis_x2_min, axis_x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    x1, x2 = np.meshgrid(np.arange(axis_x1_min, axis_x1_max, 0.01),
                         np.arange(axis_x2_min, axis_x2_max, 0.01))
    z = clf.predict(np.c_[x1.ravel(), x2.ravel()])
    z = z.reshape(x1.shape)
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#F5B9EF', '#BBFFBB', '#F9F9CB'])
    plt.contourf(x1, x2, z, cmap=custom_cmap)
    plt.scatter(X[:, 0], X[:, 1], c=y)
    plt.show()
decision_boundary_plot(x,y,clf)
#第五部分:可视化分类结构图
from sklearn.tree import plot_tree
import matplotlib.pyplot as plt
# 绘制决策树
plt.figure(figsize=(10, 6))  # 设置图像大小
plot_tree(clf, filled=True)  # `filled=True` 会为不同的类别填充颜色
plt.show()

(2)剪枝方式1:限制深度(结点层数)

(3)剪枝方式2:限制广度(叶子结点个数)

我们将第三部分代码的clf = DecisionTreeClassifier()内添加四个参数:max_depth和min_samples_split和min_samples_leaf和max_leaf_nodes和min_weight_fraction_leaf

变成了:

clf = DecisionTreeClassifier(max_depth=3,min_samples_split=20,min_samples_leaf=5,max_leaf_nodes=5,min_weight_fraction_leaf=0.03)

代表的含义就是:

①最多就只能有3层

②同时当每一个分类的样本总数少于20的时候就不再进行往下划分了;

③最小样本数不能低于5个,如果低于5个了就要向上合并,让它的上一级成为叶子结点.

④最多只能有5个叶子结点

⑤指定叶子结点中的最小权重(在没有设置样本权重的时候,所有样本的权重是相同的)

就好比总共有100个样本,每个样本权重0.01,我规定每个叶子结点中权重最少要0.05,也就是说,这个叶子结点中最起码要有5个点,少于5个点就不能分,其实跟③中差不多。

完整代码:

#第一部分:导包
import numpy as np
import matplotlib.pyplot as plt
#第二部分:加载数据集
from sklearn.datasets import load_iris
iris = load_iris()
x=iris.data[:,0:2]#选择前两个特征
y=iris.target
plt.scatter(x[:,0],x[:,1],c=y)
plt.show()
#第三部分:使用决策树进行分类
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier()
clf = DecisionTreeClassifier(max_depth=3,min_samples_split=20,min_samples_leaf=5,max_leaf_nodes=5,min_weight_fraction_leaf=0.03)

clf = clf.fit(x,y)
#第四部分:使用决策边界来绘制样本点分类散布情况
def decision_boundary_plot(X, y, clf):
    axis_x1_min, axis_x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    axis_x2_min, axis_x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    x1, x2 = np.meshgrid(np.arange(axis_x1_min, axis_x1_max, 0.01),
                         np.arange(axis_x2_min, axis_x2_max, 0.01))
    z = clf.predict(np.c_[x1.ravel(), x2.ravel()])
    z = z.reshape(x1.shape)
    from matplotlib.colors import ListedColormap
    custom_cmap = ListedColormap(['#F5B9EF', '#BBFFBB', '#F9F9CB'])
    plt.contourf(x1, x2, z, cmap=custom_cmap)
    plt.scatter(X[:, 0], X[:, 1], c=y)
    plt.show()
decision_boundary_plot(x,y,clf)
#第五部分:可视化分类结构图
from sklearn.tree import plot_tree
import matplotlib.pyplot as plt
# 绘制决策树
plt.figure(figsize=(10, 6))  # 设置图像大小
plot_tree(clf, filled=True)  # `filled=True` 会为不同的类别填充颜色
plt.show()

可以发现,最终的效果比之前要好了不少。

但是如果我们这个里面的参数过于极端,也会出现过拟合现象,比如只设置最多1层,每层1000个点,相当于直接让二叉树失效了。

注:我们可以手动设置这5个参数,当然也可以使用网格搜索的方式来找到最优超参数!

第三部分:附加提示

(1)方向问题

从上述我们通过“使用决策边界来绘制样本点分类散布情况”,就可以看出,决策树只能用于“水平方向上样本点的分类,如果这个分类正确应该是斜着的分类线,那么决策树就会产生很大的误差!”

(2)不够稳定

随便改变某一个数可能会让改变前和改变后的图像出现较大的变化!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

还不秃顶的计科生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值