机器学习 -- 决策树分类

机器学习 – 决策树分类


一,概念

1、决策节点
通过条件判断而进行分支选择的节点。如:将某个样本中的属性值(特征值)与决策节点上的值进行比较,从而判断它的流向。

2、叶子节点
没有子节点的节点,表示最终的决策结果。

3、决策树的深度
所有节点的最大层次数。

决策树具有一定的层次结构,根节点的层次数定为0,从下面开始每一层子节点层次数增加

4、决策树优点:

​ 可视化 - 可解释能力-对算力要求低

5、 决策树缺点:

​ 容易产生过拟合,所以不要把深度调整太大了。

在这里插入图片描述
在这里插入图片描述

是动物会飞有羽毛
1麻雀111
2蝙蝠110
3飞机010
4熊猫100

是否为动物

是动物会飞有羽毛
1麻雀111
2蝙蝠110
4熊猫100

是否会飞

是动物会飞有羽毛
1麻雀111
2蝙蝠110

是否有羽毛

是动物会飞有羽毛
1麻雀111

二,基于信息增益决策树的建立

信息增益决策树倾向于选择取值较多的属性,在有些情况下这类属性可能不会提供太多有价值的信息,算法只能对描述属性为离散型属性的数据集构造决策树。

2.1 信息熵

信息熵描述的是不确定性。信息熵越大,不确定性越大。信息熵的值越小,则D的纯度越高。

假设样本集合D共有N类,第k类样本所占比例为,则D的信息熵为
在这里插入图片描述

2.2 信息增益

信息增益是一个统计量,用来描述一个属性区分数据样本的能力。信息增益越大,那么决策树就会越简洁。这里信息增益的程度用信息熵的变化程度来衡量, 信息增益公式:
在这里插入图片描述

  • 示例
职业年龄收入学历是否贷款
1工人365500高中
2工人422800初中
3白领453300小学
4白领2510000本科
5白领328000硕士
6白领2813000博士
  • 根节点的信息熵 H(D)

根据是否贷款把样本分成2类样本,"是"占4/6=2/3,"否"占2/6=1/3,所以:

在这里插入图片描述

  • 属性的信息增益 (IG(D, \text{属性}))

1 "职业"属性的信息增益 (IG(D, \text{职业}))

在职业中,工人占1/3,工人中,是否代款各占1/2,白领占2/3,白领中,是贷款占3/4,不贷款占1/4,所以:

$[ H(\text{职业}) = -\frac{1}{3}\left(\frac{1}{2}\log_2\frac{1}{2} + \frac{1}{2}\log_2\frac{1}{2}\right) - \frac{2}{3}\left(\frac{3}{4}\log_2\frac{3}{4} + \frac{1}{4}\log_2\frac{1}{4}\right) \approx 0.867 ]
最后得到职业属性的信息增益为:
[ IG(D, \text{职业}) = H(D) - H(\text{职业}) = 0.066 ]
2. "年龄"属性的信息增益 (IG(D, \text{年龄}))(以35岁为界)

在这里插入图片描述

3 "收入"属性的信息增益 (IG(D, \text{收入}))(以10000为界,大于等于10000为一类)
在这里插入图片描述
4 "学历"属性的信息增益 (IG(D, \text{学历}))(以高中为界,大于等于高中的为一类)

在这里插入图片描述 结论

根据计算结果,收入和学历属性的信息增益最高,均为0.266,这意味着它们在分类任务中可能最有用。职业属性的信息增益最低,为0.066,表明其在当前数据集上的分类效果可能不如其他属性。年龄属性的信息增益为0,表明它对分类没有帮助。
三,基于基尼指数的决策树的建立
基尼指数(Gini Index)是决策树算法中用于评估数据集纯度的一种度量,基尼指数衡量的是数据集的不纯度,或者说分类的不确定性。在构建决策树时,基尼指数被用来决定如何对数据集进行最优划分,以减少不纯度。

基尼指数的计算

对于一个二分类问题,如果一个节点包含的样本属于正类的概率是 §,则属于负类的概率是 (1-p)。那么,这个节点的基尼指数 (Gini§) 定义为:

$Gini(p) = 1 - p^2 - (1-p)^2 = 2p(1-p) $

对于多分类问题,如果一个节点包含的样本属于第 k 类的概率是 p k p_k pk,则节点的基尼指数定义为:

$ Gini(p) = 1 - \sum_{k=1}^{K} p_k^2 $

基尼指数的意义

  • 当一个节点的所有样本都属于同一类别时,基尼指数为 0,表示纯度最高。
  • 当一个节点的样本均匀分布在所有类别时,基尼指数最大,表示纯度最低。

决策树中的应用

在构建决策树时,我们希望每个内部节点的子节点能更纯,即基尼指数更小。因此,选择分割特征和分割点的目标是使子节点的平均基尼指数最小化。具体来说,对于一个特征,我们计算其所有可能的分割点对应的子节点的加权平均基尼指数,然后选择最小化这个值的分割点。这个过程会在所有特征中重复,直到找到最佳的分割特征和分割点。

例如,考虑一个数据集 (D),其中包含 (N) 个样本,特征 (A) 将数据集分割为 ∣ D 1 ∣ |D_1| D1 ∣ D 2 ∣ |D_2| D2 ,则特征 (A) 的基尼指数为:

在这里插入图片描述

其中 ∣ D 1 ∣ |D_1| D1 ∣ D 2 ∣ |D_2| D2 分别是子集 D 1 D_1 D1 D 2 D_2 D2 中的样本数量。

通过这样的方式,决策树算法逐步构建一棵树,每一层的节点都尽可能地减少基尼指数,最终达到对数据集的有效分类。
在这里插入图片描述在这里插入图片描述
首先工资有两个取值,分别是0和1。当工资=1时,有3个样本。
所以:

同时,在这三个样本中,工作都是好。

所以:

就有了加号左边的式子:

同理,当工资=0时,有5个样本,在这五个样本中,工作有3个是不好,2个是好。

就有了加号右边的式子:

同理,可得压力的基尼指数如下:

平台的基尼指数如下:

在计算时,工资和平台的计算方式有明显的不同。因为工资只有两个取值0和1,而平台有三个取值0,1,2。所以在计算时,需要将平台的每一个取值都单独进行计算。比如:当平台=0时,将数据集分为两部分,第一部分是平台=0,第二部分是平台!=0(分母是5的原因)。

根据基尼指数最小准则, 我们优先选择工资或者平台=0作为D的第一特征。

我们选择工资作为第一特征,那么当工资=1时,工作=好,无需继续划分。当工资=0时,需要继续划分。

当工资=0时,继续计算基尼指数:

当平台=0时,基尼指数=0,可以优先选择。

同时,当平台=0时,工作都是好,无需继续划分,当平台=1,2时,工作都是不好,也无需继续划分。直接把1,2放到树的一个结点就可以。

三,示例

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.tree import export_graphviz
import joblib

def train():
    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.8, random_state=42)
    #标准化
    transformer = StandardScaler()
    x_train = transformer.fit_transform(x_train)
    x_test = transformer.transform(x_test)

    # 决策树算法
    model = DecisionTreeClassifier(max_depth=5,criterion="entropy")
    model.fit(x_train, y_train)

    # 模型评估
    score = model.score(x_test, y_test)
    print("准确率:", score)

    # 保存模型
    joblib.dump(model, "model/dctree_model.pkl")
    joblib.dump(transformer, "model/dctree_transformer.pkl")
    print("模型保存成功")
    
    #保存模型可视化数据
    export_graphviz(model, out_file="model/dctree_model.dot", feature_names=["花萼长", "花萼宽", "花瓣长", "花瓣宽"])
    print("模型可视化数据保存成功")

def predict():
    # 加载模型
    model = joblib.load("model/dctree_model.pkl")
    transformer = joblib.load("model/dctree_transformer.pkl")
    # 数据预处理
    x = [[5.1, 3.5, 1.4, 0.2],
         [5.9, 3.0, 5.1, 1.8]]
    x = transformer.transform(x)
    # 预测
    y_predict = model.predict(x)
    print("预测结果:", y_predict)


if __name__ == '__main__':
    train()
    predict()
准确率: 0.9333333333333333
模型保存成功
模型可视化数据保存成功
预测结果: [0 2]

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值