机器学习算法之CART分类树算法(python实现)

        CART(Classification and Regression Trees)是一种常用的决策树算法,既可以用于分类问题,也可以用于回归问题。CART分类树的主要思想是通过递归地将数据集划分为更小的子集,使得每个子集内的样本属于同一类别。与C4.5算法不同,CART分类树使用基尼系数作为属性选择的准则。

        以下是CART分类树算法的主要步骤:

        1.数据集划分:将原始数据集划分为训练集和测试集。
        2.属性选择:计算每个属性的基尼系数,选择基尼系数最小的属性作为当前节点的划分标准,基尼系数越小表示划分后的纯度越高。
        3.决策树构建:根据选择的属性将数据集划分为多个子集,每个子集对应一个分支。递归地对每个子集进行属性选择和决策树构建。
        4.剪枝:若构建好的决策树分支过多,则可能需要对其进行剪枝操作,以减少过拟合的风险。
        5.分类预测:使用构建好的决策树对新样本进行分类预测。

        CART分类树的特点是生成的决策树是二叉树,每个内部节点都有两个分支。CART算法通过贪心的方式逐步最小化基尼系数,构建出具有较好分类性能的决策树模型。

        本次代码中的数据集我选用是否拖欠贷款的数据,每条数据的属性均包含是否有房、是否已婚、年薪是否超过80K和是否拖欠贷款,其中属性值为1表示是,属性值为0表示否。

        具体的python代码如下:

def CreateTree(dataset, labels):  # 递归构建分类决策树,用Python中的字典来存储树的结构
    n = len(dataset)  # 求出数据集中有多少条数据
    ginis = []  # 用列表ginis计算每个属性的基尼系数
    yes = 0  # 记录拖欠贷款的人数
    no = 0  # 记录没有拖欠贷款的人数
    for i in range(0, n):
        if dataset[i][len(dataset[0])-1] == 'yes':
            yes += 1
        else:
            no += 1
    if yes == n:  # 递归边界,即剩余数据中全为拖欠贷款的情况
        Leaf = {}
        Leaf['result'] = 'yes'  # 结果为拖欠贷款
        Leaf['IsLeaf'] = True  # 标记此节点为叶子节点
        return Leaf

    if no == n:  # 递归边界,即剩余数据中全为不拖欠贷款的情况
        Leaf = {}
        Leaf['result'] = 'no'  # 结果为不拖欠贷款
        Leaf['IsLeaf'] = True  # 标记此节点为叶子节点
        return Leaf

    if len(dataset) == 1:  # 递归边界,即只剩1条数据时的情况
        yes = 0
        no = 0
        for i in range(0, len(dataset)):
            if dataset[i][len(dataset[0]) - 1] == 'yes':
                yes += 1
            else:
                no += 1
        Leaf = {}
        if yes > no:
            Leaf['result'] = 'yes'
            Leaf['IsLeaf'] = True
        else:
            Leaf['result'] = 'no'
            Leaf['IsLeaf'] = True
        return Leaf

    for j in range(0, len(dataset[0])-1):
        yes = 0  # 记录属性值 = 1 的人数
        no = 0  # 记录属性值 = 1 的人数
        yes1 = 0  # 记录当属性值 = 1 时拖欠贷款的人数
        no1 = 0  # 记录当属性值 = 1 时不拖欠贷款的人数
        yes2 = 0  # 记录当属性值 = 0 时拖欠贷款的人数
        no2 = 0  # 记录当属性值 = 0 时不拖欠贷款的人数
        for i in range(0, n):
            if dataset[i][j] == 1:
                yes += 1
                if dataset[i][len(dataset[0]) - 1] == 'yes':
                    yes1 += 1
                else:
                    no1 += 1
            else:
                no += 1
                if dataset[i][len(dataset[0]) - 1] == 'yes':
                    yes2 += 1
                else:
                    no2 += 1

        p1 = yes1 / yes
        p2 = no1 / yes
        # 计算属性值 = 1 时的基尼系数
        gini1 = 1 - (p1 * p1 + p2 * p2)
        p1 = yes2 / no
        p2 = no2 / no
        # 计算属性值 = 0 时的基尼系数
        gini2 = 1 - (p1 * p1 + p2 * p2)
        # 计算加权基尼系数
        gini = (yes / n) * gini1 + (no / n) * gini2
        ginis.append(gini)
    min = 0
    for i in range(0, len(ginis)):
        if ginis[i] < ginis[min]:
            min = i  # 求出哪个属性的加权基尼系数最小

    dataset2 = []

    for i in range(n - 1, -1, -1):  # 根据属性值为0或1将数据划分为两部分,再分别对这两部分数据递归地构建子树
        if dataset[i][min] == 1:
            dataset2.append(dataset[i])
            dataset.pop(i)

    for i in range(0, len(dataset2)):  # 将已作为根节点的属性从原有属性集中剔除掉
        dataset2[i].pop(min)
    for i in range(0, len(dataset)):
        dataset[i].pop(min)

    # 构建节点
    Node = {}
    # 该节点为分支节点
    Node['feature'] = labels[min]
    Node['IsLeaf'] = False
    labels.pop(min)

    # 递归地划分左右子树
    Node['left'] = CreateTree(dataset2, labels)
    Node['right'] = CreateTree(dataset, labels)

    return Node

# 根据已构建的子树来预测数据


def TestTree(Tree, Node):
    if Tree['IsLeaf'] == True:
        if Tree['result'] == 'yes':
            print('会拖欠贷款')
        else:
            print('不会拖欠贷款')
    else:
        if Node[Tree['feature']] == 1:
            TestTree(Tree['left'], Node)
        if Node[Tree['feature']] == 0:
            TestTree(Tree['right'], Node)


labels = ['是否有房', '是否已婚', '年薪是否超过80K', '是否拖欠贷款']
dataset = [
    [1, 0, 1, 'no'],
    [0, 1, 1, 'no'],
    [0, 0, 0, 'no'],
    [1, 1, 1, 'no'],
    [0, 0, 1, 'yes'],
    [0, 1, 0, 'no'],
    [1, 0, 1, 'no'],
    [0, 0, 1, 'yes'],
    [0, 1, 0, 'no'],
    [0, 0, 1, 'yes']
],

if __name__ == '__main__':
    Tree = {}
    # 构建决策树
    Tree = CreateTree(dataset[0], labels)
    # 打印决策树
    print(Tree)

    # 输入测试数据
    test = {}
    test['是否有房'] = int(input("是否有房: "))
    test['是否已婚'] = int(input("是否已婚: "))
    test['年薪是否超过80K'] = int(input("年薪是否超过80K: "))

    # 利用已构建的决策树来进行预测
    TestTree(Tree, test)

        代码运行结果如下 :

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值