• 决策树模型与学习

定义5.1(决策树):分类决策树模型是一种描述对实例进行分类的树形结构。决策树由结点和有向边组成。结点有两种类型:内部结点和叶结点。内部结点表示一个特征或属性,叶结点表示一个类。

用决策树分类,从根结点开始,对实例的某一特征进行测试,根据测试结果,将实例分配到其子结点;这时,每一个子结点对应着该特征的一个取值。如此递归地对实例进行测试并分配,直至达到叶结点。最后将实例分到叶结点的类中。

《统计学习方法》——决策树《统计学习方法》——决策树

  • 特征选择

随机变量X的熵定义为:《统计学习方法》——决策树

定义5.2(信息增益):特征A对训练数据集D的信息增益g(D,A),定义为集合D的经验熵H(D)与特征A给定条件下D的经验条件熵H(D|A)之差,即:《统计学习方法》——决策树

定义5.3(信息增益比):特征A对训练数据集D的信息增益比《统计学习方法》——决策树定义为其信息增益《统计学习方法》——决策树与训练数据集D关于特征A的值的熵《统计学习方法》——决策树之比,即:《统计学习方法》——决策树

其中,《统计学习方法》——决策树,n是特征A取值的个数。

  • 决策树的生成

《统计学习方法》——决策树

《统计学习方法》——决策树

  • 决策树的剪枝

决策树的剪枝往往通过极小化决策树整体的损失函数来实现。设树T的叶结点个数为|T|,t是树T的叶结点,该叶结点有《统计学习方法》——决策树个样本点,其中k类的样本点有《统计学习方法》——决策树个,《统计学习方法》——决策树《统计学习方法》——决策树为叶结点t上的经验熵,《统计学习方法》——决策树为参数,则决策树学习的损失函数可以定义为《统计学习方法》——决策树,其中经验熵为《统计学习方法》——决策树

在损失函数中,右端第一项记作《统计学习方法》——决策树,这时有《统计学习方法》——决策树

C(T)表示模型对训练数据的预测误差,即模型与训练数据的拟合程度,|T|表示模型复杂度,参数《统计学习方法》——决策树控制两者之间的影响。较大的《统计学习方法》——决策树促使选择较简单的模型,较小的《统计学习方法》——决策树促使选择较复杂的模型。《统计学习方法》——决策树意味着只考虑模型与训练数据的拟合程度,不考虑模型的复杂度。

剪枝,就是当《统计学习方法》——决策树确定时,选择损失函数最小的模型,即损失函数最小的子树。当《统计学习方法》——决策树值确定时,子树越大,往往与训练数据的拟合越好,但是模型的复杂度就越高;相反,子树越小,模型的复杂度就越低,但是往往与训练数据的拟合不好。损失函数正好表示了对两者的平衡。

  • CART算法

定义5.4(基尼指数):分类问题中,假设有K个类,样本点属于第k类的概率为《统计学习方法》——决策树,则概率分布的基尼指数定义为:《统计学习方法》——决策树

对于二分类问题,若样本点属于第1个类的概率是p,则概率分布的基尼指数为:《统计学习方法》——决策树

对于给定的样本集合D,其基尼指数为:《统计学习方法》——决策树

这里,《统计学习方法》——决策树是D中属于第k类的样本子集,K是类的个数。

如果样本集合D根据特征A是否取某一可能值a被分割成《统计学习方法》——决策树《统计学习方法》——决策树两部分,即《统计学习方法》——决策树

则在特征A的条件下,集合D的基尼指数定义为:

《统计学习方法》——决策树

基尼指数Gini(D)表示集合D的不确定性,基尼指数Gini(D,A)表示经A=a分割后集合D的不确定性。基尼指数值越大,样本集合的不确定性也就越大,这一点与熵相似。

下图显示二分类问题中基尼指数Gini(p)、熵之半H(p)/2和分类误差率的关系。横坐标表示概率p,纵坐标表示损失。可以看出基尼指数和熵之半的曲线很接近,都可以近似地代表分类误差率。

《统计学习方法》——决策树

  • 练习

尝试调用sklearn.tree.DecisionTreeClassifier模块,训练样本集采用表5.1的数据,判断是否应该批准下列人员的贷款申请:

A={青年,否,是,一般}

B={中年,是,否,好}

C={老年,否,是,一般}

DecisionTreeClassifier(criterion='gini', splitter='best', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, class_weight=None, presort=False)

采用的是CART算法

参数

  1. criterion:度量分类质量,默认值"gini",可选值"entropy"
  2. splitter:选择分类点,默认值"best",可选值"random"
  3. max_depth:树最大深度,默认值None,可选值int
  4. min_samples_split:最小样本阈值,默认值2,可选值int or float
  5. min_samples_leaf:叶子节点最小样本,默认值1,可选值int or float
  6. min_weight_fraction_leaf:叶子节点最小样本权重,默认值0.0,可选值float
  7. max_features:考虑最大特征值,默认值None,可选值int, float, "auto", "sqrt", "auto"
  8. random_state:随机数种子,默认值None
  9. max_leaf_nodes:最大叶子节点数量,默认值None,可选值float
  10. min_impurity_decrease:split损失阈值,默认值0.0,可选值float
  11. class_weight:类别权重,解决样本不均衡,默认值None
  12. presort:数据是否排序,默认值False,可选值bool
# coding:utf-8
"""
@author:hanmy
@file:dt_sklearn.py
@time:2019/05/17
"""
from sklearn.tree import DecisionTreeClassifier
from sklearn import preprocessing
import numpy as np
import pandas as pd


if __name__ == "__main__":
    # 原始样本数据
    features = ["年龄", "有工作", "有自己的房子", "信贷情况"]
    X_train = pd.DataFrame([
        ["青年", "否", "否", "一般"],
        ["青年", "否", "否", "好"],
        ["青年", "是", "否", "好"],
        ["青年", "是", "是", "一般"],
        ["青年", "否", "否", "一般"],
        ["中年", "否", "否", "一般"],
        ["中年", "否", "否", "好"],
        ["中年", "是", "是", "好"],
        ["中年", "否", "是", "非常好"],
        ["中年", "否", "是", "非常好"],
        ["老年", "否", "是", "非常好"],
        ["老年", "否", "是", "好"],
        ["老年", "是", "否", "好"],
        ["老年", "是", "否", "非常好"],
        ["老年", "否", "否", "一般"]
    ])
    y_train = pd.DataFrame(["否", "否", "是", "是", "否", "否", "否", "是", "是", "是", "是", "是", "是", "是", "否"])

    # 数据预处理
    le_x = preprocessing.LabelEncoder()
    le_x.fit(np.unique(X_train))
    X_train = X_train.apply(le_x.transform)
    
    le_y = preprocessing.LabelEncoder()
    le_y.fit(np.unique(y_train))
    y_train = y_train.apply(le_y.transform)

    # 调用sklearn.DT建立训练模型
    clf = DecisionTreeClassifier()
    clf.fit(X_train, y_train)

    # 用训练得到模型进行预测
    X_new = pd.DataFrame([["青年", "否", "是", "一般"],
                          ["中年", "是", "否", "好"],
                          ["老年", "否", "是", "一般"]])
    X = X_new.apply(le_x.transform)
    y_predict = clf.predict(X)

    # 结果输出
    for i in range(len(y_predict)):
        X_show = [{features[j]: X_new.values[i][j]} for j in range(len(features))]
        print("{0}被分类为:{1}".format(X_show, le_y.inverse_transform(y_predict)[i]))

预测结果为:

[{'年龄': '青年'}, {'有工作': '否'}, {'有自己的房子': '是'}, {'信贷情况': '一般'}]被分类为:是
[{'年龄': '中年'}, {'有工作': '是'}, {'有自己的房子': '否'}, {'信贷情况': '好'}]被分类为:是
[{'年龄': '老年'}, {'有工作': '否'}, {'有自己的房子': '是'}, {'信贷情况': '一般'}]被分类为:是

相关文章:

  • 2021-11-04
  • 2021-09-13
  • 2022-01-17
  • 2021-12-21
  • 2022-02-09
猜你喜欢
  • 2021-07-09
  • 2021-04-07
  • 2021-08-31
  • 2021-11-21
  • 2021-07-23
  • 2021-06-03
  • 2021-11-02
相关资源
相似解决方案