一、什么是决策树

        决策树是一种模仿人类决策过程的机器学习算法,它通过学习简单的决策规则来预测目标变量的值。决策树模型由节点和边组成,形成一个树状结构。树的每个内部节点表示一个特征上的判断,每个边代表判断的结果,而每个叶子节点代表一个类别或决策结果。决策树既可以用于分类问题,也可以用于回归问题,且决策树也是具有极高可解释性(大众基本都能听懂)的模型。

二、决策树模型原理

        决策树模型的原理基于递归地将数据集分割成越来越小的子集,直到满足特定条件,如达到某个纯度标准或子集中的样本数量小于预定阈值。每个分割决策都是基于特征的某个值来做出的,目的是最大化子集内部的同质性(即同一个类别的样本尽可能多)和不同子集之间的异质性(即不同类别的样本尽可能少)。以下是决策树模型构建的主要步骤和原理:

1、特征选择

        在每个节点上,决策树会选择一个特征和该特征的一个阈值来分割数据。特征选择的目的是找到最好的分割点,可以使用信息增益(Information Gain)等指标来衡量分割的效果。信息增益是衡量通过分割数据获得的信息量,它基于的概念,而熵是度量数据集不确定性的指标,信息增益高的分割可以更有效地减少不确定性(就好比你打算去买一台高性能的拍照手机,有两款手机供你挑选,一开始你并不确定到底要买哪一台,你打算从各个方面去比较两款手机,但这时候你发现了其中一款手机拍照像素只有可怜的200万,而另一款是2000万像素,显然从拍照性能这个特征入手极大程度减少了不确定性,相信你不会选择200万像素的拍照手机吧)。

        熵的计算公式如下,p_{i}是数据集中第i个类别的概率,m是类别的总数:

H(S) = -\sum_{i=1}^{m}p_{i}log_{2}(p_{i})

        有了熵,我们可以进行信息增益的计算:

Gain(S, A) = H(S) - \sum _{v-from-values(A)}\frac{|S_{v}|}{|S|}H(S_{v})

        其中,S是父节点的数据集,A是特征,values(A)是特征A的所有可能值,S_{v}是特征A值为v时的数据子集。

2、数据分割

        使用选定的特征和阈值,数据集被分割成两个或多个子集。每个子集应该尽可能地只包含同一类别的样本。特征的选择目标是选出使数据集的熵(不确定性)减少最多的特征。除了信息增益之外,一般更常用的是信息增益率,即信息增益与特征熵的比值,信息增益率可以解决信息增益偏向于选择具有大量值的特征的问题(假设特征中有一个ID列,每个样本都有一个唯一的ID,那么信息增益就会把ID列作为最重要特征,实际上这是不合理的,模型泛化能力会变得极差,但信息增益率可以解决这个问题)。公式如下,其中H(A)是特征A的熵:

Gain Ratio(S, A) = \frac{Gain(S, A)}{H(A)}

        一旦选择了特征,下一步是确定该特征的阈值,以便根据该特征的值将数据集分割成子集。对于数值型特征,可能需要遍历特征的所有唯一值,以找到最佳的分割点。对于每个可能的阈值,将数据集分割成两个子集,并计算分割后子集的纯度(如信息增益或基尼不纯度)。选择使子集纯度最大化的阈值作为最终的分割点。

3、递归数据分割

        对上一阶段分出来的每个子集重复特征选择和阈值选择的过程,直到满足停止条件(如达到最大树深度、节点中的样本数量小于预定阈值或无法进一步减少不纯度)。递归分割是指在每个子集上重复上述过程,直到满足停止条件,如达到最大树深度、节点中的样本数量小于预定阈值,或者无法进一步减少不纯度。

4、输出结果

        决策树的每个叶子节点代表一个预测结果。对于分类问题,叶子节点通常是数据集中最常见的类别;对于回归问题,叶子节点通常是子集中目标变量的平均值或中位数。

三、模型损失函数

        在实际应用中,决策树通常不需要显式地定义一个损失函数来进行训练,因为树的构建过程是通过递归地选择最佳分割点来完成的

四、决策树模型类型

        决策树模型有多种类型,每种类型都有其特点和适用场景。以下是一些教材中常见的决策树模型:

1、ID3

        经典的决策树算法,使用信息增益作为特征选择的标准,但它倾向于选择具有更多值的特征,比如每个样本的唯一编号。

2、C4.5

        C4.5是ID3的改进版,它使用信息增益率来选择特征,克服了ID3对特征值数量的偏好。

3、CART(Classification and Regression Trees)

        CART既可以用于分类问题,也可以用于回归问题。它使用基尼不纯度作为分类问题的划分标准,对于回归问题则使用均方误差。基尼不纯度(Gini Impurity)是决策树算法中用于衡量一个节点内样本类别多样性的指标。它基于概率理论,用于评估数据集的纯净度或不纯度。基尼不纯度越低,表示数据集的纯净度越高,即数据集中的样本属于同一类别的可能性越大。公式如下:

Gini(S) = 1-\sum_{m}^{i=1}p_{i}^{2}

        其中,m是数据集中不同类别的总数,p_{i}是数据集中第i个类别的样本所占的比例。基尼不纯度的值范围从0到1,当数据集中的所有样本都属于同一个类别时,基尼不纯度为0,表示纯净度最高;当数据集中的样本均匀分布在所有类别时,基尼不纯度接近1,表示不纯度最高。与信息增益相比,基尼不纯度对样本类别分布的不均匀性不太敏感,因此在某些情况下可能更受欢迎。此外,基尼不纯度的计算不需要对数运算,这在数值稳定性方面可能更有优势。

五、模型应用

        一般我们会直接使用scikit-learn库中的决策树类进行建模,该模型基于CART构建,有多个可调节参数,调用起来方便快捷。

1、分类任务

# 导入必要的库
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

# 加载鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target

# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建决策树分类器实例
clf = DecisionTreeClassifier(random_state=42)

# 训练模型
clf.fit(X_train, y_train)

# 在测试集上进行预测
y_pred = clf.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')

# 打印决策树
from sklearn.tree import export_text
tree_rules = export_text(clf, feature_names=iris.feature_names)
print(tree_rules)

2、回归任务

# 导入必要的库
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_squared_error

# 加载波士顿房价数据集
boston = load_boston()
X = boston.data
y = boston.target

# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建决策树回归器实例
regressor = DecisionTreeRegressor(random_state=42)

# 训练模型
regressor.fit(X_train, y_train)

# 在测试集上进行预测
y_pred = regressor.predict(X_test)

# 计算均方误差(MSE)
mse = mean_squared_error(y_test, y_pred)
print(f'Mean Squared Error: {mse:.2f}')

# 打印决策树
from sklearn.tree import export_text
tree_rules = export_text(regressor, feature_names=boston.feature_names)
print(tree_rules)

六、总结

        在业务应用过程中,决策树也是常见的baseline之一。一方面,我们可以通过训练一个决策树模型并打印出特征重要性从而决定各个特征的取舍,这也是特征工程的常见方法;另一方面,我们使用决策树作为baseline也可以将树结构打印出来,以便向上下游解释相关流程;最后,在一些低性能芯片部署模型的任务中,决策树甚至可以直接转化为规则写到芯片中,实现高效的边端部署。

1、优点

        (1)易于理解和解释:决策树的结构清晰,可以可视化,容易解释模型的决策过程。

        (2)不需要数据预处理:决策树可以处理数值型和类别型数据,不需要复杂的数据预处理,如特征缩放。

        (3)能够处理各种数据类型:既可以处理数值型数据,也可以处理类别型数据。

        (4)可以处理缺失数据:在构建决策树时,可以设计算法来处理缺失值。

2、缺点

        (1)容易过拟合:决策树很容易生长出过于复杂的树,导致模型在训练数据上表现良好,但在未见过的数据上表现差,因此要注意max_depth等参数的设置。

        (2)对噪声数据敏感:决策树对噪声数据和异常值比较敏感,可能会导致模型性能下降。

        (3)可能需要大量的内存:对于大型数据集,构建和存储决策树可能需要大量的内存。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐