机器学习-决策树的实现
在计算的过程中,我们会计算条件下每个分支的归一化信息熵,即用每个分支在该属性中出现的概率,来乘以该分支的信息熵。Gain(D,a)中 D 是当前结点包含的所有结果(来自父节点某一分支), a 是为划分这些结果所选的属性,Di 则是属性a下不同的分支所包含的结果。常用的特征选择指标有信息增益、信息增益比、基尼指数等,用于评估特征的重要性和划分能力,选择最佳的特征进行划分。(4)层数越多,叶结点越多,
文章目录
一、决策树的介绍
1.决策树的定义
2.决策树的原理
3.决策树的优缺点
二、决策树的构造步骤
1.特征选择
1.1信息熵
1.2信息增益
1.3基尼指数
2.决策树的构建
3.决策树的修剪
1.1为什么要剪枝?
1.2 剪枝的分类
三、决策树的实现
四、决策树的应用场景
五、总结
一、决策树的介绍
决策树(Decision Tree)是机器学习中最常用的算法之一,广泛应用于分类和回归问题。作为一种监督学习方法,决策树通过将数据集分割成不同的区域来做出预测,最终构建出树形结构,帮助我们做出决策。本文将详细讲解决策树的原理、如何在 Python 中实现决策树模型、评估模型的表现以及如何进行调优,并通过一个实际案例来展示决策树算法在预测中的应用。
1.决策树的定义
(1)决策树(Decision Tree)是从一组无次序、无规则,但有类别标号的样本集中推导出的、树形表示的分类规则。
(2)一般的,一棵决策树包含一个根结点、若干个内部结点(中间结点)和若干个叶子结点。
树的叶子结点表示类别标号,即分类属性的取值,也可以说是决策结果;树的内部结点为条件属性,每个结点包含的样本集合根据属性测试结果被划分到子结点中;根结点包含样本全集。从树根到叶子结点的一条路径称为一条决策规则,它可以对未知数据进行分类或预测。每条有向边都用其出点的属性值标记。
(3)通常,一个属性有多少种取值,就从该结点引出多少条有向边,每一条边代表属性的一种取值。
(4)树深度是树根到树叶的最大层数,通常作为决策树模型复杂度的一种度量。
2.决策树的原理
决策树是一种通过递归分割特征空间来构建模型的算法。它从根节点开始,每个非叶子节点代表一个特征的判定,而每个叶子节点表示最终的输出(目标变量的预测值)。决策树的目标是通过选择一个最佳的特征来分割数据集,使得每个子集尽可能纯净(即子集中的数据点尽可能属于同一类别)。
3.决策树的优缺点
决策树的优点
• 决策树算法中学习简单的决策规则建立决策树模型的过程非常容易理解;
•决策树模型可以可视化,非常直观;
•应用范围广,可用于分类和回归,而且非常容易做多类别的分类;
•能够处理数值型和连续的样本特征
决策树的缺点
• 很容易在训练数据中生成复杂的树结构,造成过拟合(overfitting)。剪枝可以缓解过拟合的负作用,常用方法是限制树的高度、叶子节点中的最少样本数量。
二、决策树的构建步骤
1.特征选择
特征选择是决策树构建过程中的关键步骤。常用的特征选择指标有信息增益、信息增益比、基尼指数等,用于评估特征的重要性和划分能力,选择最佳的特征进行划分。
1.1 信息熵
熵越大,代表数据的不确定性越高
熵越小,代表数据的不确定性越低
条件熵
给定特征 A 的条件下,数据集 S 的熵:
1.2 信息增益
信息增益指的就是划分可以带来纯度的提高,信息熵的下降。它的计算公式,是信息增益 = 划分前熵 - 划分后熵。在计算的过程中,我们会计算条件下每个分支的归一化信息熵,即用每个分支在该属性中出现的概率,来乘以该分支的信息熵。所以信息增益的公式可以表示为:
Gain(D,a)中 D 是当前结点包含的所有结果(来自父节点某一分支), a 是为划分这些结果所选的属性,Di 则是属性a下不同的分支所包含的结果 。
1.3 基尼指数
基尼指数(Gini不纯度)表示在样本集合中一个随机选中的样本被分错的概率。

对于特征A 的基尼指数增益:
2.决策树的构建
决策树的构建基于递归分裂策略。从根节点开始,根据选定的特征和划分标准,将数据集划分为不纯度较低的子集,逐步构建子节点,直到所有样本都被正确分类或达到预定义的停止条件。
3. 决策树的修剪
1.1为什么要剪枝?
(1)决策树的剪枝是为了简化决策树模型,避免过拟合。
(2)同样层数的决策树,叶结点的个数越多就越复杂;同样的叶结点个数的决策树,层数越多越复杂。
(3)剪枝前相比于剪枝后,叶结点个数和层数只能更多或者其中一特征一样多,剪枝前必然更复杂。
(4)层数越多,叶结点越多,分的越细致,对训练数据分的也越深,越容易过拟合,导致对测试数据预测时反而效果差,泛化能力差。
1.2 剪枝的分类
剪枝算法可以分为:预剪枝和后剪枝。
预剪枝
预剪枝就是在决策树生成过程中,在每次划分时,考虑是否能够带来决策树性能的提升。如果可以提升决策树的性能则会进行划分,如果不能则会停止生长。
一般的方法有如下几种:
(1)当树的深度达到一定的规模,则停止生长。
(2)达到当前节点的样本数量小于某个阈值的时候。
(3)计算每次分裂对测试集的准确性提升,当小于某个阈值,或不再提升甚至有所下降时,停止生长。
(4)当信息增益,增益率和基尼指数增益小于某个阈值的时候不在生长。
预剪枝的优缺点
优点:思想简单,算法高效,采用了贪心的思想,适合大规模问题。
缺点:提前停止生长,有可能存在欠拟合的风险。
后剪枝
后剪枝是先从训练集生成一颗完整的决策树,然后自底向上的对决策树进行剪枝。与预剪枝最大的不同就是决策树是否生长完整。决策树的生成是学习局部的模型,后剪枝则是学习整体的模型。
一般的方法有错误率降低剪枝(REP)等。
后剪枝的优缺点
优点:可以最大限度的保留树的各个节点,避免了欠拟合的风险。
缺点:相较于预剪枝的时间开销巨大。
三、决策树的实现
import numpy as np
def entropy(y):
"""
计算熵
"""
classes, counts = np.unique(y, return_counts=True)
probabilities = counts / len(y)
entropy = -np.sum(probabilities * np.log2(probabilities))
return entropy
def information_gain(X, y, feature_index):
"""
计算信息增益
"""
parent_entropy = entropy(y)
n = len(y)
feature_values = np.unique(X[:, feature_index])
weighted_entropy = 0
for value in feature_values:
subset_indices = X[:, feature_index] == value
subset_y = y[subset_indices]
subset_entropy = entropy(subset_y)
weighted_entropy += (len(subset_y) / n) * subset_entropy
return parent_entropy - weighted_entropy
def split_information(X, feature_index):
"""
计算分裂信息
"""
n = len(X)
feature_values = np.unique(X[:, feature_index])
split_info = 0
for value in feature_values:
subset_indices = X[:, feature_index] == value
subset_size = len(X[subset_indices])
if subset_size > 0:
probability = subset_size / n
split_info -= probability * np.log2(probability)
return split_info
def information_gain_ratio(X, y, feature_index):
"""
计算信息增益率
"""
ig = information_gain(X, y, feature_index)
si = split_information(X, feature_index)
if si == 0:
return 0
return ig / si
def gini_index(y):
"""
计算基尼指数
"""
classes, counts = np.unique(y, return_counts=True)
probabilities = counts / len(y)
gini = 1 - np.sum(probabilities ** 2)
return gini
def gini_index_split(X, y, feature_index):
"""
计算特征分裂后的基尼指数
"""
n = len(y)
feature_values = np.unique(X[:, feature_index])
weighted_gini = 0
for value in feature_values:
subset_indices = X[:, feature_index] == value
subset_y = y[subset_indices]
subset_gini = gini_index(subset_y)
weighted_gini += (len(subset_y) / n) * subset_gini
return weighted_gini
dataSet = [
[0, 0, 0, 0, 0], [0, 0, 0, 1, 0], [0, 1, 0, 1, 1], [0, 1, 1, 0, 1],
[0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 1, 0], [1, 1, 1, 1, 1],
[1, 0, 1, 2, 1], [1, 0, 1, 2, 1], [2, 0, 1, 2, 1], [2, 0, 1, 1, 1],
[2, 1, 0, 1, 1], [2, 1, 0, 2, 1], [2, 0, 0, 0, 0], [2, 0, 0, 2, 0]
]
dataSet = np.array(dataSet)
X = dataSet[:, :-1]
y = dataSet[:, -1]
# 计算并打印数据集的熵
dataset_entropy = entropy(y)
print(f"数据集的熵: {dataset_entropy}")
num_features = X.shape[1]
for i in range(num_features):
ig = information_gain(X, y, i)
igr = information_gain_ratio(X, y, i)
gi = gini_index_split(X, y, i)
print(f"特征 {i}:")
print(f" 信息增益: {ig}")
print(f" 信息增益率: {igr}")
print(f" 基尼指数: {gi}")
结果
四、决策树的应用场景
决策树在很多领域都有广泛应用,比如:
1.金融行业:决策树可用于信用评估、风险管理等领域。
2.医疗领域:决策树可用于疾病诊断、药物疗效预测等问题。
3.销售预测:决策树可用于分析客户行为、预测销售量等。
五、总结
决策树算法作为机器学习中的重要工具,在数据挖掘和模式识别等领域有着广泛的应用。它不仅提供了直观的模型解释能力,而且在处理大规模和复杂数据集时也表现出较高的效率和准确性。通过这一次实验,加深了对决策树算法的深入了解,并可以更好地应用该算法解决实际问题。
更多推荐


所有评论(0)