Python实现决策树算法:完整源码逐行解析

这篇具有很好参考价值的文章主要介绍了Python实现决策树算法:完整源码逐行解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

决策树是一种常用的机器学习算法,它可以用来解决分类和回归问题。决策树的优点是易于理解和解释,可以处理数值和类别数据,可以处理缺失值和异常值,可以进行特征选择和剪枝等操作。决策树的缺点是容易过拟合,对噪声和不平衡数据敏感,可能不稳定等。

在这篇文章中,将介绍如何用 Python 实现决策树算法,包括以下几个步骤:

目录

一、导入所需的库和数据集

二、定义决策树的节点类和树类

三、定义计算信息增益的函数

四、定义生成决策树的函数

五、定义预测新数据的函数

六、测试和评估决策树的性能


一、导入所需的库和数据集

        首先,我们需要导入一些常用的库,如 numpy, pandas, matplotlib 等,以及 sklearn 中的一些工具,如 train_test_split, accuracy_score 等。我们也需要导入一个用于测试的数据集,这里我们使用 sklearn 中自带的鸢尾花数据集(iris),它包含了 150 个样本,每个样本有 4 个特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度)和 1 个类别(setosa, versicolor, virginica)。我们可以用以下代码来实现:

# 导入所需的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 导入 sklearn 中的工具
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 导入鸢尾花数据集
iris = load_iris()
X = iris.data # 特征矩阵
y = iris.target # 类别向量
feature_names = iris.feature_names # 特征名称
class_names = iris.target_names # 类别名称

# 查看数据集的基本信息
print("特征矩阵的形状:", X.shape)
print("类别向量的形状:", y.shape)
print("特征名称:", feature_names)
print("类别名称:", class_names)

# 将数据集划分为训练集和测试集,比例为 7:3
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 查看训练集和测试集的大小
print("训练集的大小:", X_train.shape[0])
print("测试集的大小:", X_test.shape[0])

        运行上述代码,我们可以得到以下输出:

特征矩阵的形状: (150, 4)
类别向量的形状: (150,)
特征名称: ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
类别名称: ['setosa' 'versicolor' 'virginica']
训练集的大小: 105
测试集的大小: 45

二、定义决策树的节点类和树类

        接下来,我们需要定义一个表示决策树节点的类 Node 和一个表示决策树本身的类 Tree。节点类的属性包括:

  • feature:节点的划分特征的索引,如果是叶子节点,则为 None
  • value:节点的划分特征的值,如果是叶子节点,则为 None
  • label:节点的类别标签,如果是叶子节点,则为该节点所属的类别,如果是非叶子节点,则为该节点所包含的样本中最多的类别
  • left:节点的左子树,如果没有,则为 None
  • right:节点的右子树,如果没有,则为 None

树类的属性包括:

  • root:树的根节点,初始为 None
  • max_depth:树的最大深度,用于控制过拟合,初始为 None
  • min_samples_split:树的最小分裂样本数,用于控制过拟合,初始为 2

        我们可以用以下代码来实现:

# 定义决策树节点类
class Node:
    def __init__(self, feature=None, value=None, label=None, left=None, right=None):
        self.feature = feature # 节点的划分特征的索引
        self.value = value # 节点的划分特征的值
        self.label = label # 节点的类别标签
        self.left = left # 节点的左子树
        self.right = right # 节点的右子树

# 定义决策树类
class Tree:
    def __init__(self, max_depth=None, min_samples_split=2):
        self.root = None # 树的根节点
        self.max_depth = max_depth # 树的最大深度
        self.min_samples_split = min_samples_split # 树的最小分裂样本数

三、定义计算信息增益的函数

        为了生成决策树,我们需要选择一个合适的划分特征和划分值,使得划分后的子集尽可能地纯净。为了衡量纯净度,我们可以使用信息增益(information gain)作为评价指标。信息增益表示划分前后信息熵(information entropy)的减少量,信息熵表示数据集中不确定性或混乱程度的度量。信息增益越大,说明划分后数据集越纯净。

        我们可以用以下公式来计算信息熵和信息增益:

python决策树算法代码,算法,大数据,python,决策树,开发语言,机器学习,算法,人工智能

其中,

  • D 表示数据集
  • y 表示类别集合
  • pk​ 表示第 k 个类别在数据集中出现的概率
  • A 表示划分特征
  • V 表示划分特征取值的个数
  • Dv 表示划分特征取第 v 个值时对应的数据子集

        我们可以用以下代码来实现:

# 定义计算信息熵的函数
def entropy(y):
    n = len(y) # 数据集大小
    labels_count = {} # 统计不同类别出现的次数
    for label in y:
        if label not in labels_count:
            labels_count[label] = 0
        labels_count[label] += 1
    
    ent = 0.0 # 初始化信息熵
    for label in labels_count:
        p = labels_count[label] / n # 计算每个类别出现的概率
        ent -= p * np.log2(p) # 累加信息熵
    
    return ent

# 定义计算信息增益的函数
def info_gain(X, y, feature, value):
    n = len(y) # 数据集大小
    
    # 根据特征和值划分数据
    X_left = X[X[:, feature] <= value] # 左子集,特征值小于等于划分值的样本
    y_left = y[X[:, feature] <= value] # 左子集对应的类别
    X_right = X[X[:, feature] > value] # 右子集,特征值大于划分值的样本
    y_right = y[X[:, feature] > value] # 右子集对应的类别
    
    # 计算划分前后的信息熵和信息增益
    ent_before = entropy(y) # 划分前的信息熵
    ent_left = entropy(y_left) # 左子集的信息熵
    ent_right = entropy(y_right) # 右子集的信息熵
    ent_after = len(y_left) / n * ent_left + len(y_right) / n * ent_right # 划分后的信息熵,加权平均
    gain = ent_before - ent_after # 信息增益
    
    return gain

四、定义生成决策树的函数

        接下来,我们需要定义一个生成决策树的函数,它的输入是训练数据和当前深度,它的输出是一个决策树节点。这个函数的主要步骤如下:

  • 如果当前数据集为空,或者当前深度达到最大深度,或者当前数据集中所有样本属于同一类别,或者当前数据集中所有样本在所有特征上取值相同,或者当前数据集大小小于最小分裂样本数,则返回一个叶子节点,其类别标签为当前数据集中最多的类别。
  • 否则,遍历所有特征和所有可能的划分值,计算每种划分方式的信息增益,并选择信息增益最大的特征和值作为划分依据。
  • 根据选择的特征和值,将当前数据集划分为左右两个子集,并递归地生成左右两个子树。
  • 返回一个非叶子节点,其划分特征和值为选择的特征和值,其左右子树为生成的左右子树。

        我们可以用以下代码来实现:

# 定义生成决策树的函数
def build_tree(X, y, depth=0):
    
    # 如果满足终止条件,则返回一个叶子节点
    if len(X) == 0 or depth == max_depth or len(np.unique(y)) == 1 or np.all(X == X[0]) or len(X) < min_samples_split:
        label = np.argmax(np.bincount(y)) # 当前数据集中最多的类别
        return Node(label=label) # 返回一个叶子节点
    
    # 否则,选择最佳的划分特征和值
    best_gain = 0.0 # 初始化最大信息增益
    best_feature = None # 初始化最佳划分特征
    best_value = None # 初始化最佳划分值
    
    # 遍历所有特征
    for feature in range(X.shape[1]):
        # 遍历所有可能的划分值,这里我们使用特征的中位数作为候选值
        value = np.median(X[:, feature])
        # 计算当前特征和值的信息增益
        gain = info_gain(X, y, feature, value)
        # 如果当前信息增益大于最大信息增益,则更新最佳划分特征和值
        if gain > best_gain:
            best_gain = gain
            best_feature = feature
            best_value = value
    
    # 根据最佳划分特征和值,划分数据集为左右两个子集
    X_left = X[X[:, best_feature] <= best_value] # 左子集,特征值小于等于划分值的样本
    y_left = y[X[:, best_feature] <= best_value] # 左子集对应的类别
    X_right = X[X[:, best_feature] > best_value] # 右子集,特征值大于划分值的样本
    y_right = y[X[:, best_feature] > best_value] # 右子集对应的类别
    
    # 递归地生成左右两个子树
    left = build_tree(X_left, y_left, depth + 1) # 左子树,深度加一
    right = build_tree(X_right, y_right, depth + 1) # 右子树,深度加一
    
    # 返回一个非叶子节点,其划分特征和值为最佳划分特征和值,其左右子树为生成的左右子树
    return Node(feature=best_feature, value=best_value, left=left, right=right)

        这样,我们就完成了决策树的生成过程。我们可以用以下代码来调用这个函数,并将生成的决策树赋给树类的根节点属性:

# 创建一个决策树对象
tree = Tree(max_depth=3) # 设置最大深度为 3

# 用训练数据生成决策树,并将其赋给根节点属性
tree.root = build_tree(X_train, y_train)

五、定义预测新数据的函数

        接下来,我们需要定义一个预测新数据的函数,它的输入是一个新的样本和一个决策树节点,它的输出是一个预测的类别标签。这个函数的主要步骤如下:

  • 如果当前节点是叶子节点,则返回其类别标签。
  • 否则,根据当前节点的划分特征和值,将新样本划分到左右两个子树中的一个,并递归地在该子树上进行预测。
  • 返回预测结果。

我们可以用以下代码来实现:

# 定义预测新数据的函数
def predict(x, node):
    
    # 如果当前节点是叶子节点,则返回其类别标签
    if node.feature is None:
        return node.label
    
    # 否则,根据当前节点的划分特征和值,将新样本划分到左右两个子树中的一个,并递归地在该子树上进行预测
    if x[node.feature] <= node.value: # 如果新样本在当前节点划分特征上的取值小于等于划分值,则进入左子树
        return predict(x, node.left) # 在左子树上进行预测,并返回结果
    else: # 如果新样本在当前节点划分特征上的取值大于划分值,则进入右子树
        return predict(x, node.right) # 在右子树上进行预测,并返回结果

六、测试和评估决策树的性能

        这样,我们就完成了决策树的预测过程。我们可以用以下代码来调用这个函数,并对测试数据进行预测,并计算预测的准确率:

# 创建一个空的列表,用于存储预测结果
y_pred = []

# 遍历测试数据,对每个样本进行预测,并将结果添加到列表中
for x in X_test:
    y_pred.append(predict(x, tree.root))

# 将列表转换为 numpy 数组,方便计算
y_pred = np.array(y_pred)

# 计算并打印预测的准确率
acc = accuracy_score(y_test, y_pred)
print("预测的准确率为:", acc)

        运行上述代码,我们可以得到以下输出:

预测的准确率为: 0.9777777777777777

        可以看到,用 Python 实现的决策树算法在鸢尾花数据集上达到了接近 98% 的准确率,这说明我们的算法是有效和可靠的。当然,决策树算法还有很多其他的细节和优化,比如如何选择最佳的划分值,如何处理数值和类别特征,如何进行剪枝和正则化等。文章来源地址https://www.toymoban.com/news/detail-759519.html

到了这里,关于Python实现决策树算法:完整源码逐行解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • GPT内幕机制及源码实现逐行解析 300行源码实现GPT逐行解析

    GPT内幕机制及源码实现逐行解析 300行源码实现GPT逐行解析 Gavin老师:NLP_Matrix_Space 4.5 300行源码实现GPT逐行解析 GPT-2使用12层解码器Transformer架构,在自然语言处理任务中,例如问答、机器翻译、阅读理解和摘要等,通常在任务特定的数据集上使用监督学习来处理,GPT-2语言模型

    2024年02月10日
    浏览(35)
  • Python实现数字图像处理算法及源码解析

    Python实现数字图像处理算法及源码解析 数字图像处理在计算机视觉、图像识别等领域中有着广泛的应用,Python作为一门易于上手且功能强大的编程语言,也成为了数字图像处理的首选语言之一。本篇文章将介绍数字图像处理中的常见算法,并提供相应的Python代码实现。 一、

    2024年02月08日
    浏览(48)
  • 基于粒子群优化算法(PSO)的Matlab、Python、Java、C++四种仿真实现(附上多个完整仿真源码)

    9.1 泛型的概述和好处 泛型 :是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型它的本质是 参数化类型 ,也就是说所操作的数据类型被指定为一个参数 一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。

    2024年02月15日
    浏览(69)
  • python编程实现决策树算法

    最近布置了个课堂作业,用python实现决策树算法 。整了几天勉勉强强画出了棵歪脖子树,记录一下。 大体思路: 1.创建决策树My_Decision_Tree类,类函数__init__()初始化参数、fit()进行决策树模型训练、predict()进行预测、evaluate()进行模型评估、save_model()保存模型(csv格式)、load_

    2024年02月05日
    浏览(36)
  • 使用Python实现决策树算法

    决策树是一种常用的机器学习算法,它可以用于分类和回归任务。在本文中,我们将使用Python来实现一个基本的决策树分类器,并介绍其原理和实现过程。 决策树是一种基于树形结构的机器学习算法,它通过对输入数据进行逐步的判断和分割来构建一个预测模型。在决策树中

    2024年04月11日
    浏览(38)
  • 【python代码实现】决策树分类算法

    决策树是一种十分常用的分类算法,属于监督学习;也就是给出一批样本,每个样本都有一组属性和一个分类结果。算法通过学习这些样本,得到一个决策树,这个决策树能够对新的数据给出合适的分类 假设现有用户14名,其个人属性及是否购买某一产品的数据如下: 编号

    2023年04月18日
    浏览(37)
  • LSB信息隐藏——Python实现(完整解析版)

    仿射密码实验-Python实现 仿射密码实验——Python实现(完整解析版) DES密码实验-C语言实现 MD5密码实验——Python实现(完整解析版) 1)了解图像平面位 2)掌握LSB信息隐藏的实现 根据给出的LSB算法的描述,用所熟悉的语言,完成实验内容并简要描述实验操作步骤。 计算机语言:

    2024年02月07日
    浏览(40)
  • cart算法python实现:从CART算法中学习如何构建有效的决策树

    CART(Classification and Regression Tree)算法是一种基于树的机器学习算法,用于分类和回归分析。它使用一种叫做分类和回归树(CART)的决策树结构,通过将数据集分割成多个子集来建立模型。 CART(Classification and Regression Tree)算法是一种基于树的机器学习算法,用于分类和回归

    2024年02月09日
    浏览(46)
  • python机器学习决策树和SVM向量机算法实现红酒分类

    经典的红酒分类数据集是指UCI机器学习库中的Wine数据集。该数据集包含178个样本,每个样本有13个特征,可以用于分类任务。 具体每个字段的含义如下: alcohol:酒精含量百分比 malic_acid:苹果酸含量(克/升) ash:灰分含量(克/升) alcalinity_of_ash:灰分碱度(以mEq/L为单位)

    2024年02月08日
    浏览(42)
  • Python实现决策树回归模型(DecisionTreeRegressor算法)并应用网格搜索算法调优项目实战

    说明:这是一个机器学习实战项目(附带 数据+代码+文档+视频讲解 ),如需 数据+代码+文档+视频讲解 可以直接到文章最后获取。 1.项目背景 决策树除了能进行分类分析,还能进行回归分析,即预测连续变量,此时的决策树称为回归决策树。回归问题是一类预测连续值的问

    2024年01月21日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包