CART决策树算法浅谈(分类树部分)

在有上一篇博文做铺垫的情况下,分类树算法的介绍就显得相对简单。这篇博客首先介绍GINI系数以及它的直观意义,再给出基于GINI系数的CART分类树算法实现。这样,CART算法的两部分就介绍完毕。

1. GINI系数

考虑集合D, D={(x,y)|x=A1,A2,...AN} 代表该集合有A1~AN这N个特征,每个特征取值又可以分为Ki类(i<=N)。如果这个集合包含了m类,设取到其中一类的概率为Pi,则有放回地取出两个样本,它们属于不同类别的概率为

P=1i=1mpi

该数值反映了集合的纯粹程度,可以想象,如果集合只含有一类,那么该值将变为0。所以,该值越小表示集合中属于同一类样本的个体越多,这个反应纯粹程度的量就是GINI系数。
对样本进行分类其实就是将属于同一类的样本集中,属于不同类的样本分开。我们最小化GINI系数就可以实现这一功能。
在上述推导的基础上,如果基于某一个特征按照 和 将集合分裂成两个子集合(a为特征Ai的某一取值),该如何计算这两个集合的“纯度”?这就引入了基于特征的GINI系数。
Gini(D,Ai)=p(Ai=a)Gini(DAi=i)+p(Aia)Gini(DAii)

这个量可用于评价使用Ai作为分类标准时,所得到分类结果的“纯度”。

2. 树的生成

分类树的基本生成过程与上篇博客提到的回归树生成十分相似。不同点在于选择分枝特征的准则,这里使用的是GINI系数。树的具体生成步骤如下:
Step1:根据特征Ai的某一取值a,将集合D分为 和 两部分,计算GINI系数。
Step2:对D的每一个特征和特征的每一个取值分别计算GINI系数,取GINI系数最小者作为分类准则,将集合D分裂成两个子集合。以后的切分过程不再使用该特征。
Step3:对每个子集合递归地调用步骤1~2,直到GINI系数为0或者特征使用完为止。

3. 基于Python的CART实现

树的生成过程与上篇博客大同小异,所以这里只介绍基尼系数选择特征的函数。

def calGINI(data, feature):
    # data已经剪过了
    targetFeature = data[:, feature]  # 获得目标特征
    label = data[:, -1]  # 标签
    sampleNum = len(targetFeature)  # 总样本数
    kind = np.unique([targetFeature])  # 特征中含有的类别
    labelKind = np.unique([label])
    # 特征中的每一个分量都要计算
    gini = []
    for kindF in kind:
        g = 0.0
        subClass = data[np.nonzero(targetFeature == kindF)[0], :]  # 获取满足条件的子数据集
        cmpClass = data[np.nonzero(targetFeature != kindF)[0], :]  # 获得差集
        subClassP = len(subClass) / (1.0 * sampleNum)  # 该分量等于该值的比例
        # 拆分后的数据集应当不为空
        if len(subClass) and len(cmpClass):
            g = subClassP * (
                1.0 - sum(np.power(
                    [len(np.nonzero(subClass[:, -1] == labK)[0]) / (1.0 * len(subClass[:, -1])) for labK in labelKind],
                    2))) \
                + (1.0 - subClassP) * (
                1.0 - sum(np.power(
                    [len(np.nonzero(cmpClass[:, -1] == labK)[0]) / (1.0 * len(cmpClass[:, -1])) for labK in labelKind],
                    2)))
        else:
            g = np.inf
        gini.append(g)
    # 寻找最大特征作为分割点
    featureLoc = int(np.where(gini == np.amin(gini))[0][0])  # 可能有同时为为最小的,只取一个
    return feature, kind[featureLoc], gini[featureLoc]  # 返回最优分割对应的分量和gini系数

上面的代码用于计算某一特征的最优gini系数分割值。首先在该特征的所有取值中选择一个,计算按照该值分裂样本之后的GINI系数。遍历所有取值,找出GINI系数最小的那个特征取值,返回它。这样就可以获得一个特征的最优分裂值。通过与其他特征进行对比,就可找到最优的分裂值。
详细代码我转了一份到github,地址为:https://github.com/FlyingRoastDuck/CART_REG
参考文献
[1] 李航. 统计学习方法 [M]. 北京:清华大学出版社, 2012: 65-70.
[2] Peter H. 机器学习实战 [M]. 北京:人民邮电出版社,2013: 161-170.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值