✏️
LiHang-TongJiXueXiFangFa
  • Introduction
  • 第2章 感知机 - 原始形式
    • 学习策略的推导
    • 梯度下降法的算法过程
    • 梯度下降法的推导过程
    • 梯度下降法的收敛证明
  • 第2章 感知机 - 对偶形式
    • 学习模型的推导
    • 梯度下降法的算法过程
    • 梯度下降法的推导过程
  • 第3章 k近邻算法
    • 模型三要素
    • 构造平衡kd树
    • 用kd树的k近邻搜索
    • kd树的原理与改进
  • 第4章 朴素贝叶斯
    • 模型公式的推导
    • 策略公式的推导
    • 最大似然估计算法过程
    • 贝叶斯估计算法过程
  • 第5章 决策树
    • 决策树的模型
    • 信息增益的算法
    • ID3决策树的生成算法
    • C4.5决策树的生成算法
    • 决策树的剪枝算法
  • 第5章 CART决策树
    • CART树的生成
    • CART树的剪枝
  • 第6章 逻辑回归
    • 二分类逻辑回归模型
    • 多分类逻辑回归模型
  • 第6章 最大熵模型
    • 最大熵的原理
    • 最大熵模型的定义
    • 最大熵的学习过程
    • 根据最大熵的学习过程推导最大熵模型
    • 证明:对偶函数的极大化=模型的极大似然估计
  • 第6章 目标函数最优化问题
    • 改进的迭代尺度法(IIS)
    • IIS算法公式(1)推导
    • A和B的推导
    • 拟牛顿法
  • 第7章 支持向量机
    • 函数间隔与几何间隔
  • 第7章 线性可分SVM
    • 凸二次规划问题推导
    • 支持向量
    • 凸二次规划问题求解
    • 原始问题转换为对偶最优化问题
  • 第7章 线性SVM
    • 原始问题转换为对偶最优化问题
    • 根据 a 求 w 和 b*
    • 支持向量
  • 第7章 非线性SVM
    • 核函数与核技巧
    • 核技巧在SVM中的应用
    • 7.3.2 正定核
    • 常用的核函数
  • 第7章 序列最小最优化算法
    • 选择变量
    • 推导1
    • 推导2
    • 推导3
    • 推导4
    • 推导5:update b
  • 第8章 adaboost
    • 算法过程
    • 训练误差分析
    • 加法模型
    • 前向分步算法
    • adaboost一种特殊的加法模型
  • 第8章 提升树
    • 回归问题提升树的推导
    • 回归问题提升树前向分步算法
    • 一般决策问题梯度提升算法
  • 第9章 EM算法
    • 算法过程
    • Q函数的推导
    • 关于算法的收敛性
    • 高斯混合模型参数估计的EM算法
    • Q函数推导
    • 推导2
  • 第10章 隐马尔可夫模型
    • 定义
    • 概率计算问题 - 直接计算法
    • 概率计算问题 - 前向算法
    • 概率计算问题 - 后向算法
    • 学习问题 - 监督学习
    • 学习问题 - 非监督学习
    • Baum - Welch算法推导
    • 推导1
    • 预测问题 - 近似算法
    • 预测问题 - 维特比算法
    • 维特比算法推导过程
  • 第11章 条件随机场
    • 概率无向图模型
  • 遗留问题
Powered by GitBook
On this page
  • CART树的剪枝算法
  • 原理
  • 步骤
  • 代码
  • 这个算法没想通

Was this helpful?

  1. 第5章 CART决策树

CART树的剪枝

PreviousCART树的生成Next第6章 逻辑回归

Last updated 5 years ago

Was this helpful?

CART树的剪枝算法

输入:剪枝前的CART树 输出:剪枝后的CART树

原理

令: 损失函数为:

Ca(T)=C(T)+a∣T∣C_a(T) = C(T) + a|T|Ca​(T)=C(T)+a∣T∣

对树上的所有结点计算: 假如该结点不split,该结点的损失为:

Ca(t)=C(t)+a∣T∣C_a(t) = C(t) + a|T|Ca​(t)=C(t)+a∣T∣

假如该结点split,则该结点的损失为:

Ca(Tt)=C(Tt)+a∣Tt∣C_a(T_t) = C(T_t) + a|T_t|Ca​(Tt​)=C(Tt​)+a∣Tt​∣

当a=0或a足够小时,有

即split得到的损失更小。这是肯定的,因为CART树的生成算法就是这样的定义的。因为split得到的损失更小,才会split生成子结点。 但当a慢慢增大,对一个特定的结点t来说,当a取到某个值时,会有

将公式(2)、(3)代码公式(5),得出:

若对于某个结点来说,此时的a使得$C_a(T_t)< C_a(t) $,那么就应该剪枝了。

步骤

  1. 令当前树为$T_0$,表示未做过剪枝的CART树

  2. 自下而上【?】地对所有结点计算g(t),并同时记录最小的g(t)作为当前的alpha

  3. 对Tree中$g(t)=a$的结点做剪枝,得到的新的树$T_a$

  4. 如果当前的树不只一个根结点,就循环2-3步

  5. 通过交叉验证选出最优的$T_a$

代码

def isLeaf(Node):
    # return type(Node).__name__ != 'dict'
    return not ('left' in Node.keys() or 'right' in Node.keys())

def calcAlphaList(Node):
    if isLeaf(Node):
        return
    costNotSplit = Node['gini']
    costSplit = Node['left']['gini'] + Node['right']['gini']
    alpha = (costNotSplit-costSplit)/(Node['Tt']-1)
    Node['alpha'] = alpha
    if alpha < calcAlphaList.bestAlpha:
        calcAlphaList.bestAlpha = alpha
    calcAlphaList(Node['left'])
    calcAlphaList(Node['right'])

def calcTt(Node):
    if isLeaf(Node):
        return 1
    Node['Tt'] = calcTt(Node['left']) + calcTt(Node['right'])
    return Node['Tt']

def cut(Node, alpha):
    if Node['alpha'] == alpha:
        Node.pop('left')
        Node.pop('right')
    else:
        cut(Node['left'], alpha)
        cut(Node['right'], alpha)

def prune(Tree):
    i = 0
    print ('i=',i,Tree)
    while not isLeaf(Tree):
        calcTt(Tree)
        calcAlphaList.bestAlpha = np.inf
        calcAlphaList(Tree)
        i += 1
        print ('i=',i,'alpha',calcAlphaList.bestAlpha)
        cut(Tree, calcAlphaList.bestAlpha)
        print (Tree)

这个算法没想通

Ca(Tt)<Ca(t)C_a(T_t) < C_a(t)Ca​(Tt​)<Ca​(t)
Ca(Tt)=Ca(t)C_a(T_t) = C_a(t)Ca​(Tt​)=Ca​(t)
a=C(t)−C(Tt)∣Tt∣−1a = \frac {C(t) - C(T_t)}{|T_t| - 1}a=∣Tt​∣−1C(t)−C(Tt​)​
g(t)=C(t)−C(Tt)∣Tt∣−1g(t) = \frac {C(t) - C(T_t)}{|T_t| - 1}g(t)=∣Tt​∣−1C(t)−C(Tt​)​