决策树详解与sklearn实战

机器学习 | 决策树详解与sklearn实战

一、sklearn概述

scikit-learn(又写作sklearn)是一个开源的Python机器学习工具包,通过NumPy、SciPy和Matplotlib等库实现高效的算法应用,涵盖了几乎所有主流机器学习算法。

在实际工程应用中,我们通常:

  1. 分析采集到的数据
  2. 根据数据特征选择适合的算法
  3. 在工具包中调用算法、调整参数
  4. 获取需要的信息

sklearn正是这样一个能帮助我们高效实现算法应用的工具包。


二、决策树工作原理

2.1 什么是决策树

决策树(Decision Tree)是一种非参数的有监督学习方法,能够从有特征和标签的数据中总结出决策规则,用树状图结构呈现,解决分类和回归问题。

2.2 决策树的核心概念

决策树由三种节点组成:

节点类型 描述
根节点 没有进边,有出边。包含最初的特征提问
中间节点 既有进边也有出边,进边只有一条,出边可以有多条
叶子节点 有进边,没有出边,每个叶子节点都是一个类别标签

父节点和子节点:两个相连的节点中,接近根节点的是父节点,另一个是子节点。

2.3 决策树要解决的两个核心问题

  1. 如何从数据表中找出最佳节点和最佳分枝?
  2. 如何让决策树停止生长,防止过拟合?

三、sklearn中的决策树

3.1 tree模块

sklearn中决策树的类都在tree模块下:

用途
tree.DecisionTreeClassifier 分类树
tree.DecisionTreeRegressor 回归树
tree.export_graphviz 导出为DOT格式,画图专用
tree.ExtraTreeClassifier 高随机版本的分类树
tree.ExtraTreeRegressor 高随机版本的回归树

3.2 sklearn建模基本流程

python 复制代码
from sklearn import tree

# 1. 导入模块
clf = tree.DecisionTreeClassifier()

# 2. 实例化
clf = clf.fit(X_train, y_train)

# 3. 用训练集数据训练模型
result = clf.score(X_test, y_test)

# 4. 导入测试集,从接口调用需要的信息

四、DecisionTreeClassifier 重要参数详解

4.1 criterion(不纯度计算方法)

作用:决定不纯度的计算方法,帮助找出最佳节点和最佳分枝。

决策树算法通过不纯度来衡量节点的质量。不纯度越低,决策树对训练集的拟合越好。sklearn提供两种选择:

参数值 计算方法
"gini" 基尼系数(Gini Impurity)
"entropy" 信息熵(Entropy)

公式

  • 基尼系数:Gini(t)=1−∑i=0c−1p(i∣t)2Gini(t) = 1 - \sum_{i=0}^{c-1}p(i|t)^2Gini(t)=1−∑i=0c−1p(i∣t)2
  • 信息熵:Entropy(t)=−∑i=0c−1p(i∣t)log2p(i∣t)Entropy(t) = -\sum_{i=0}^{c-1}p(i|t)log_2p(i|t)Entropy(t)=−∑i=0c−1p(i∣t)log2p(i∣t)

选择建议

场景 推荐
默认 基尼系数
数据维度很大,噪音很多 基尼系数
维度低,数据比较清晰 两者皆可
决策树拟合程度不够 信息熵

信息熵对不纯度更敏感,计算比基尼系数慢,但惩罚更强。高维数据或噪音多时容易过拟合。


4.2 random_state & splitter(随机性控制)

random_state:设置分枝中的随机模式参数

  • 默认None,高维度时随机性更明显
  • 输入任意整数,可以长出同一棵树,让模型稳定

splitter:控制分枝的随机程度

行为
"best" 优先选择更重要的特征进行分枝
"random" 更加随机,树更深更大

当预测模型会过拟合时,可用这两个参数降低过拟合可能性。


4.3 剪枝参数(防止过拟合)

在不加限制的情况下,决策树会生长到不纯度指标最优或没有更多特征可用,这样往往会导致过拟合------在训练集上表现好,但在测试集上表现糟糕。

max_depth

限制树的最大深度,超过设定深度的树枝全部剪掉。

在高维度低样本量时非常有效,建议从=3开始尝试。

min_samples_leaf & min_samples_split
参数 作用
min_samples_leaf 限定一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本
min_samples_split 限定一个节点必须包含至少min_samples_split个训练样本才允许被分枝

建议从=5开始使用。如果类别不多的分类问题,=1通常就是最佳选择。

max_features

限制分枝时考虑的特征个数,超过限制个数的特征会被舍弃。

在不知道特征重要性的情况下强行设定可能导致模型学习不足。

min_impurity_decrease

限制信息增益的大小,信息增益小于设定数值的分枝不会发生。


4.4 目标权重参数(处理样本不平衡)

class_weight:对样本标签进行平衡,给少量标签更多权重。

场景:比如银行判断信用卡违约(是vs否 = 1%:99%),即使全预测成"否"正确率也有99%,这时需要调整权重。

min_weight_fraction_leaf :基于权重的剪枝参数,与class_weight配合使用。


五、重要属性和接口

属性

feature_importances_:查看各个特征对模型的重要性

python 复制代码
clf.feature_importances_
[*zip(feature_name, clf.feature_importances_)]

四个核心接口

接口 功能
fit(X_train, y_train) 训练模型
score(X_test, y_test) 返回预测准确度
apply(X_test) 返回每个测试样本所在的叶子节点索引
predict(X_test) 返回每个测试样本的标签
python 复制代码
# 训练和评估
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, Ytest)

# 查看特征重要性
clf.feature_importances_

# 预测
clf.apply(Xtest)    # 返回叶子节点索引
clf.predict(Xtest)  # 返回分类结果

六、实战:绘制决策树

python 复制代码
from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
import graphviz

# 1. 导入数据
wine = load_wine()

# 2. 分训练集和测试集
Xtrain, Xtest, Ytrain, Ytest = train_test_split(
    wine.data, wine.target, test_size=0.3
)

# 3. 建立模型
clf = tree.DecisionTreeClassifier(criterion="entropy", random_state=30)
clf = clf.fit(Xtrain, Ytrain)

# 4. 评估
score = clf.score(Xtest, Ytest)

# 5. 绘制决策树
feature_name = ['酒精','苹果酸','灰','灰的碱性','镁','总酚',
                '类黄酮','非黄烷类酚类','花青素','颜色强度',
                '色调','od280/od315稀释葡萄酒','脯氨酸']

dot_data = tree.export_graphviz(
    clf,
    feature_names=feature_name,
    class_names=["琴酒","雪莉","贝尔摩德"],
    filled=True,
    rounded=True
)
graph = graphviz.Source(dot_data)
graph

七、总结

决策树核心知识点

类别 内容
七个参数 Criterion、random_state、splitter、max_depth、min_samples_leaf、max_features、min_impurity_decrease
一个属性 feature_importances_
四个接口 fit、score、apply、predict

超参数调优建议

通过学习曲线来判断最优参数------以超参数取值为横坐标,模型度量指标(score)为纵坐标绘制曲线。

调参没有绝对的答案,一切都要看数据本身。

不同数据集的模型选择

数据集类型 最擅长的模型
月亮型数据 最近邻算法、RBF支持向量机、高斯过程
环形数据 最近邻算法、高斯过程
对半分数据 朴素贝叶斯、神经网络、随机森林

八、剪枝策略

|

新增参数 说明
min_samples_split 节点分枝前的最小样本数门槛
max_leaf_nodes 限制最大叶子节点数
min_impurity_split 已废弃,用min_impurity_decrease替代
presort 是否预排序加速拟合
max_depth 限制树的最大深度,超过设定深度的树枝全部剪掉
python 复制代码
clf = tree.DecisionTreeClassifier(criterion="entropy"
                                 ,random_state=30
                                 ,splitter="random"
                                 ,max_depth=3
                                 ,min_samples_leaf=10
                                 ,min_samples_split=10
                                 )
clf = clf.fit(Xtrain, Ytrain)
 
相关推荐
江畔柳前堤7 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore9 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考10 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX11 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面11 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号12 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽12 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI12 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者14 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者14 小时前
【征程6】校准量化中HistogramObserver解析
算法