精华内容
下载资源
问答
  • CART决策树

    2018-10-16 14:00:21
    一个非常完整的CART决策树的python实现,大家可以下过来学习一下
  • CART 决策树

    2020-05-10 05:18:31
    我们将从头开始一步一步地介绍CART决策树示例。 CART树的核心是决策规则将通过GINI索引值决定。 停止条件。 如果我们继续使树完全生长直到每个叶节点对应最低的杂质,那么数据通常会过拟合。如果过早停止拆分,则...

    ID3使用信息增益,而C4.5使用增益比率进行拆分。 在此,CART是另一种决策树构建算法。 它可以处理分类和回归任务。 该算法使用名为gini索引的新度量标准来创建分类任务的决策点。

    CART树的核心是决策规则将通过GINI索引值决定。

    在这里插入图片描述

    停止条件。

    如果我们继续使树完全生长直到每个叶节点对应最低的杂质,那么数据通常会过拟合。如果过早停止拆分,则训练数据的错误不会足够高,并且由于bais会影响性能。因此,在对决策树进行建模时,防止过度拟合和欠拟合是至关重要的,可以通过以下两种方式完成:

    1. 对树大小设置约束
    2. 修剪树木

    对树大小设置约束:

    1. 为节点拆分提供最少数量的样本。
    2. 为终端节点(叶)部署最少数量的样本。
    3. 允许树的最大深度(垂直深度)。
    4. 终端节点的最大数量。
    5. 拆分要考虑的最大功能。
      修剪树
      修剪是机器学习中的一种技术,它通过删除树的部分来减小决策树的大小。它还降低了最终分类器的复杂度,因此通过减少过度拟合提高了预测准确性。可以通过预修剪或后修剪两种方式完成树修剪。

    -预先整理
    如果当前节点没有将熵至少提高到预设(阈值),则停止拆分当前节点。
    如果数据点的数量小于某些预设(阈值)值,就停止分区。
    将树的深度限制为某个预设(阈值)值。

    -修剪后:
    可以通过首先允许树生长到最大潜力,然后在计算每个级别的交叉验证准确性之后修剪每个级别的树来完成此操作。

    CART的优势:

    1. 决策树可以固有地执行多类分类。
    2. 它们提供了大多数模型可解释性,因为它们只是一系列if-else条件。
    3. 他们可以处理数值和分类数据。
    4. 特征之间的非线性关系不会影响决策树的性能。

    CART的缺点:

    1. 数据集的微小变化会使树结构不稳定,从而导致差异。
    2. 如果某些类不平衡,决策树学习者将创建欠适应树。 因此,建议在与决策树拟合之前平衡数据集

    例子

    展开全文
  • CART决策树分类算法VC++ CART决策树分类算法VC++ CART决策树分类算法VC++ CART决策树分类算法VC++
  • cart决策树

    千次阅读 2016-03-17 15:53:44
    分类与回归(CART——Classification And Regression Tree) 在已知各种情况的概率,用直观图表求最大期望的方法。

    分类与回归树(CART——Classification And Regression Tree)   在已知各种情况的概率,用直观图表求最大期望的方法。


    实例

    为了适应市场的需要,某地准备扩大电视机生产。市场预测表明:产品销路好的概率为0.7;销路差的概率为0.3。备选方案有三个:第一个方案是建设大工厂,需要投资600万元,可使用10年;如销路好,每年可赢利200万元;如销路不好,每年会亏损40万元。第二个方案是建设小工厂,需投资280万元;如销路好,每年可赢利80万元;如销路不好,每年也会赢利60万元。第三个方案也是先建设小工厂,但是如销路好,3年后扩建,扩建需投资400万元,可使用7年,扩建后每年会赢利190万元。

      各点期望:
    点②:0.7×200×10+0.3×(-40)×10-600(投资)=680(万元)

    决策树分析
    点⑤:1.0×190×7-400=930(万元)
    点⑥:1.0×80×7=560(万元)
    比较决策点4的情况可以看到,由于点⑤(930万元)与点⑥(560万元)相比,点⑤的期望利润值较大,因此应采用扩建的方案,而舍弃不扩建的方案。把点⑤的930万元移到点4来,可计算出点③的期望利润值。
    点③:0.7×80×3+0.7×930+0.3×60×(3+7)-280 = 719(万元)
    最后比较决策点1的情况。由于点③(719万元)与点②(680万元)相比,点③的期望利润值较大,因此取点③而舍点②。这样,相比之下,建设大工厂的方案不是最优方案,合理的策略应采用前3年建小工厂,如销路好,后7年进行扩建的方案。

    展开全文
  • Python实现CART决策树

    千次阅读 2020-11-16 14:37:10
    CART决策树前言一、CART决策树算法二、Python代码实现1.计算结点GINI值2.分离数据集3.选择最好的特征4.生成决策树4.测试决策树6.决策树可视化7.主程序部分CART决策分类树所有代码总结 前言   CART算法的全称是...
      
    


    前言

      CART算法的全称是Classification And Regression Tree,采用的是Gini指数(选Gini指数最小的特征s)作为分裂标准,是一种实用的分类算法。


    一、CART决策树算法

      主要思路是对一个数据集选择几个属性作为特征,对于每个特征提出一个划分条件,根据这个条件将结点分为两个子节点,对于子节点同样利用下一个特征进行划分,直到某结点的Gini值符合要求,我们认为这个结点的不纯性很小,该节点已成功分类。如此反复执行,最后可以得到由若干个结点组成的决策树,其中的每个叶节点都是分类的结果。

      某结点的Gini值的计算公式如下:
    某结点Gini值的计算方式
      如果要对某种划分计算Gini值,可以利用加权平均,即:

    在这里插入图片描述
      明确了Gini值的计算以及决策树的基本思路后,就可以继续向下看具体的代码实现了,本文没有使用sklearn库,如果读者只是需要使用该算法,而不想了解算法实际的实现思路的话,可以无需向下看了。

    二、Python代码实现

    主要分为6个步骤:

    1. 寻找到最佳属性
    2. 创建决策树
    3. 将上一结点分裂,分别计算左、右子节点的Gini值。
    4. 计算Gnin值有一种方法:将数据集对应这个属性的值排序,从头开始选择相邻两个值的平均值作为划分条件,计算该分发下的Gini值,如此遍历一遍,选出最小的一个Gini值对应的划分条件,作为该属性的最佳分裂条件
    5. 对于子节点,Gini值小于阈值,认为其是叶节点,结束这一方向的分裂。若Gini值大于阈值,认为分类还不够纯,需继续分裂,下一次分裂要使用不同的属性值。
    6. 递归调用创建决策树,就可以得到完整的决策树。

    使用到的函数主要有5个:

    • calcGini(dataSet)   #计算结点GINI值
    • splitDataSet(dataSet, n, value, type)  #根据条件分离数据集
    • FindBestFeature(dataSet)  #选择最好的特征划分数据集,即返回最佳特征下标及传入数据集各列的Gini指数
    • createTree(dataSet, features, decisionTree)  #生成决策树。输入:训练数据集D,特征集A。输出:决策树T
    • testTree(dataSet)  #获得测试结果,给出混淆矩阵

    1.计算结点GINI值

    def calcGini(dataSet):
    
        numTotal = dataSet.shape[0]            # 记录本数据集总条数
        length = len(dataSet[0])               # 计算特征列数
        frequent_0 = 0.0                         # 记录三种样本出现次数
        frequent_1 = 0.0
        frequent_2 = 0.0
        for i in range(0,numTotal):
            if dataSet[i][length-1] == '0.0':
                frequent_0 += 1
            elif dataSet[i][length-1] == '1.0':
                frequent_1 += 1
            elif dataSet[i][length-1] == '2.0':
                frequent_2 += 1
        gini = 1 - (frequent_0/numTotal)**2 - (frequent_1/numTotal)**2 - (frequent_2/numTotal)**2
        return gini
    

    2.分离数据集

    def splitDataSet(dataSet, n, value, type):
    
        subDataSet = []
        numTotal = dataSet.shape[0]            # 记录本数据集总条数
        if type == 1:                          # type==1对应小于等于value的情况
            for i in range(0,numTotal):
                if float(dataSet[i][n]) <= value:
                    subDataSet.append(dataSet[i])
        elif type == 2:                        # type==2对应大于value的情况
            for i in range(0,numTotal):
                if float(dataSet[i][n]) > value:
                    subDataSet.append(dataSet[i])
        subDataSet = np.array(subDataSet)      # 强制转换为array类型
         
        return subDataSet,len(subDataSet)
    

    3.选择最好的特征

    def FindBestFeature(dataSet):
        numTotal = dataSet.shape[0]            # 记录本数据集总条数
        numFeatures = len(dataSet[0]) - 2      # 计算特征列数
        bestFeature = -1                       # 初始化参数,记录最优特征列i,下标从0开始
        columnFeaGini={}                       # 初始化参数,记录每一列x的每一种特征的基尼 Gini(D,A)
        for i in range(1, numFeatures+1):      # 遍历所有x特征列,i为特征标号
            featList = list(dataSet[:, i])     # 取这一列x中所有数据,转换为list类型
            featListSort = [float(x) for x in featList]
            featListSort.sort()                # 对该特征值排序
            FeaGinis = []
            FeaGiniv = []
            for j in range(0,len(featListSort)-1):    # j为第几组数据
                value = (featListSort[j]+featListSort[j+1])/2
                feaGini = 0.0
                subDataSet1,sublen1 = splitDataSet(dataSet, i, value, 1)  # 获取切分后的数据
                subDataSet2,sublen2 = splitDataSet(dataSet, i, value, 2)
                feaGini = (sublen1/numTotal) * calcGini(subDataSet1) + (sublen2/numTotal) * calcGini(subDataSet2)  # 计算此分法对应Gini值
                FeaGinis.append(feaGini)       # 记录该特征下各种分法遍历出的Gini值
                FeaGiniv.append(value)         # 记录该特征下的各种分法
    
            columnFeaGini['%d_%f'%(i,FeaGiniv[FeaGinis.index(min(FeaGinis))])] = min(FeaGinis)    # 将该特征下最小的Gini值
        bestFeature = min(columnFeaGini, key=columnFeaGini.get) # 找到最小的Gini指数对应的数据列
        return bestFeature,columnFeaGini
    

    4.生成决策树

    def createTree(dataSet, features, decisionTree):
    
        if len(features) > 2:           #特征未用完
            bestFeature, columnFeaGini = FindBestFeature(dataSet)
            bestFeatureLable = features[int(bestFeature.split('_')[0])]  # 最佳特征
            NodeName = bestFeatureLable + '\n' +'<=' + bestFeature.split('_')[1]    #结点名称
            decisionTree = {NodeName: {}}   # 构建树,以Gini指数最小的特征bestFeature为子节点
        else:
            return decisionTree
    
        LeftSet, LeftSet_len = splitDataSet(dataSet, int(bestFeature.split('_')[0]), float(bestFeature.split('_')[1]), 1)
        RightSet, RightSet_len = splitDataSet(dataSet, int(bestFeature.split('_')[0]), float(bestFeature.split('_')[1]), 2)
        del (features[int(bestFeature.split('_')[0])])        # 该特征已为子节点使用,则删除,以便接下来继续构建子树
    
        if calcGini(LeftSet) <= 0.1 or len(features) == 2:
            L_lables_grp = dict(Counter(LeftSet[:,-1]))
            L_leaf = max(L_lables_grp, key=L_lables_grp.get)  # 获得划分后出现概率最大的分类作为结点的分类
            decisionTree[NodeName]['Y'] = L_leaf              # 设定左枝叶子值
        elif calcGini(LeftSet) > 0.1:
            dataSetNew = np.delete(LeftSet, int(bestFeature.split('_')[0]), axis=1)  # 删除此最优划分x列,使用剩余的x列进行数据划分
            L_subFeatures = features[:]
            decisionTree[NodeName]['Y'] = {'NONE'}
            decisionTree[NodeName]['Y'] = createTree(dataSetNew, L_subFeatures, decisionTree[NodeName]['Y'])   #递归生成左边的树
    
        if calcGini(RightSet) <= 0.1 or len(features) == 2:
            R_lables_grp = dict(Counter(RightSet[:,-1]))
            R_leaf = max(R_lables_grp, key=R_lables_grp.get)  # 获得划分后出现概率最大的分类作为结点的分类
            decisionTree[NodeName]['N'] = R_leaf              # 设定右枝叶子值
        elif calcGini(RightSet) > 0.1:
            dataSetNew = np.delete(RightSet, int(bestFeature.split('_')[0]), axis=1)  # 删除此最优划分x列,使用剩余的x列进行数据划分
            R_subFeatures = features[:]
            decisionTree[NodeName]['N'] = {'NONE'}
            decisionTree[NodeName]['N'] = createTree(dataSetNew, R_subFeatures, decisionTree[NodeName]['N'])  #递归生成右边的树
    
        return decisionTree
    

    5.测试决策树

    def testTree(dataSet):
        numTotal = dataSet.shape[0]  # 记录本数据集总条数
        testmemory = []
        label = dataSet[:,-1]
        TP = 0
        FP = 0
        TN = 0
        FN = 0
        for i in range(0,numTotal):
            if float(dataSet[i][4]) <= 0.001444:                   #标准差
                if float(dataSet[i][1]) <= 0.01022:                #均值
                    if float(dataSet[i][6]) <= -0.589019:          #峰度
                        testmemory.append('0.0')
                    else:
                        if float(dataSet[i][3]) <= -0.001811:        #四分位差
                            if float(dataSet[i][2]) <= -0.000026:      #中位数
                                testmemory.append('0.0')
                            else:
                                testmemory.append('2.0')
                        else:
                            if float(dataSet[i][2]) <= 0.007687:       #中位数
                                if float(dataSet[i][5]) <= 0.452516:   #偏度
                                    testmemory.append('0.0')
                                else:
                                    testmemory.append('0.0')
                            else:
                                testmemory.append('2.0')
                else:
                    testmemory.append('2.0')
            else:
                if float(dataSet[i][3]) <= -0.013691:                # 四分位差
                    testmemory.append('1.0')
                else:
                    if float(dataSet[i][5]) <= 1.462280:   #偏度
                        if float(dataSet[i][6]) <= -1.034223:  # 峰度
                            if float(dataSet[i][1]) <= 0.009173:  # 均值
                                if float(dataSet[i][2]) <= -0.004193:  # 中位数
                                    testmemory.append('2.0')
                                else:
                                    testmemory.append('2.0')
                            else:
                                testmemory.append('0.0')
                        else:
                            testmemory.append('2.0')
                    else:
                        if float(dataSet[i][1]) <= -0.023631:  # 均值
                            testmemory.append('2.0')
                        else:
                            testmemory.append('1.0')
    
        for i in range(0, numTotal):
            if (testmemory[i] == '1.0') and (label[i] == '1.0'):
                TP += 1
            elif (testmemory[i] == '1.0') and (label[i] != '1.0'):
                FP += 1
            elif (testmemory[i] != '1.0') and (label[i] != '1.0'):
                TN += 1
            elif (testmemory[i] != '1.0') and (label[i] == '1.0'):
                FN += 1
    
        print('TP:%d' % TP)    #真阳性
        print('FP:%d' % FP)    #假阳性
        print('TN:%d' % TN)    #真阴性
        print('FN:%d' % FN)    #假阴性
    
        cm = confusion_matrix(label, testmemory, labels=["0.0", "1.0", "2.0"])
        plt.rc('figure', figsize=(5, 5))
        plt.matshow(cm, cmap=plt.cm.cool)  # 背景颜色
        plt.colorbar()  # 颜色标签
        # 内部添加图例标签
        for x in range(len(cm)):
            for y in range(len(cm)):
                plt.annotate(cm[x, y], xy=(y, x), horizontalalignment='center', verticalalignment='center')
        plt.ylabel('True Label')
        plt.xlabel('Predicted Label')
        plt.title('decision_tree')
        plt.savefig(r'confusion_matrix')
    

    6.决策树可视化

    可视化部分基本摘自《机器学习实战》第三章。

    matplotlib.rcParams['font.family']='SimHei'  # 用来正常显示中文
    plt.rcParams['axes.unicode_minus']=False  # 用来正常显示负号
    
    decisionNode = dict(boxstyle="sawtooth", fc="0.8")
    leafNode = dict(boxstyle="round4", fc="0.8")
    arrow_args = dict(arrowstyle="<-")
    
    def getNumLeafs(myTree):
        numLeafs = 0
        firstStr = list(myTree.keys())[0]
        secondDict = myTree[firstStr]
        for key in secondDict.keys():
            if type(secondDict[
                        key]).__name__ == 'dict':  # test to see if the nodes are dictonaires, if not they are leaf nodes
                numLeafs += getNumLeafs(secondDict[key])
            else:
                numLeafs += 1
        return numLeafs
    
    def getTreeDepth(myTree):
        maxDepth = 0
        firstStr = list(myTree.keys())[0]  # myTree.keys()[0]
        secondDict = myTree[firstStr]
        for key in secondDict.keys():
            if type(secondDict[
                        key]).__name__ == 'dict':  # test to see if the nodes are dictonaires, if not they are leaf nodes
                thisDepth = 1 + getTreeDepth(secondDict[key])
            else:
                thisDepth = 1
            if thisDepth > maxDepth: maxDepth = thisDepth
        return maxDepth
    
    def plotNode(nodeTxt, centerPt, parentPt, nodeType):
        createPlot.ax1.annotate(nodeTxt, xy=parentPt, xycoords='axes fraction',
                                xytext=centerPt, textcoords='axes fraction',
                                va="center", ha="center", bbox=nodeType, arrowprops=arrow_args)
    
    def plotMidText(cntrPt, parentPt, txtString):
        xMid = (parentPt[0] - cntrPt[0]) / 2.0 + cntrPt[0]
        yMid = (parentPt[1] - cntrPt[1]) / 2.0 + cntrPt[1]
        createPlot.ax1.text(xMid, yMid, txtString, va="center", ha="center", rotation=30)
    
    def plotTree(myTree, parentPt, nodeTxt):  # if the first key tells you what feat was split on
        numLeafs = getNumLeafs(myTree)  # this determines the x width of this tree
        # depth = getTreeDepth(myTree)
        firstStr = list(myTree.keys())[0]  # myTree.keys()[0]     #the text label for this node should be this
        cntrPt = (plotTree.xOff + (1.0 + float(numLeafs)) / 2.0 / plotTree.totalW, plotTree.yOff)
        plotMidText(cntrPt, parentPt, nodeTxt)
        plotNode(firstStr, cntrPt, parentPt, decisionNode)
        secondDict = myTree[firstStr]
        plotTree.yOff = plotTree.yOff - 1.0 / plotTree.totalD
        for key in secondDict.keys():
            if type(secondDict[
                        key]).__name__ == 'dict':  # test to see if the nodes are dictonaires, if not they are leaf nodes
                plotTree(secondDict[key], cntrPt, str(key))  # recursion
            else:  # it's a leaf node print the leaf node
                plotTree.xOff = plotTree.xOff + 1.0 / plotTree.totalW
                plotNode(secondDict[key], (plotTree.xOff, plotTree.yOff), cntrPt, leafNode)
                plotMidText((plotTree.xOff, plotTree.yOff), cntrPt, str(key))
        plotTree.yOff = plotTree.yOff + 1.0 / plotTree.totalD
    
    def createPlot(myTree):
        fig = plt.figure(1, facecolor='white')
        fig.clf()
        axprops = dict(xticks=[], yticks=[])
        createPlot.ax1 = plt.subplot(111, frameon=False, **axprops)  # no ticks
        # createPlot.ax1 = plt.subplot(111, frameon=False) #ticks for demo puropses
        plotTree.totalW = float(getNumLeafs(myTree))
        plotTree.totalD = float(getTreeDepth(myTree))
        plotTree.xOff = -0.5 / plotTree.totalW;
        plotTree.yOff = 1.0;
        plotTree(myTree, (0.5, 1.0), '')
        plt.show()
    

    7.主程序部分

    trainingData, testingData= read_xslx(r'e:/Table/机器学习/1109/attribute_113.xlsx')
    features = list(trainingData[0])          # x的表头,即特征
    trainingDataSet = trainingData[1:]        # 训练集
    
    bestFeature, columnFeaGini=FindBestFeature(trainingDataSet)
    decisionTree = {}
    decisiontree = createTree(trainingDataSet, features, decisionTree)  # 建立决策树,CART分类树
    print('CART分类树:\n', decisiontree)
    testTree(testingData)
    createPlot(decisiontree)
    

    CART决策分类树所有代码

    # -*- coding: utf-8 -*-     支持文件中出现中文字符
    #########################################################################
    
    """
    Created on Mon Nov 16 21:26:00 2020
    
    @author: ixobgenw
    
    代码功能描述: (1)计算结点GINI值
                  (2)分离数据集
                  (3)选择最好的特征
                  (4)生成决策树
                  (5)测试决策树
    
    """
    #####################################################################
    
    import xlrd
    import numpy as np
    from collections import Counter
    import matplotlib.pyplot as plt
    import matplotlib
    
    
    #可视化部分
    ####################################################################################################################
    matplotlib.rcParams['font.family']='SimHei'  # 用来正常显示中文
    plt.rcParams['axes.unicode_minus']=False  # 用来正常显示负号
    
    decisionNode = dict(boxstyle="sawtooth", fc="0.8")
    leafNode = dict(boxstyle="round4", fc="0.8")
    arrow_args = dict(arrowstyle="<-")
    
    def getNumLeafs(myTree):
        numLeafs = 0
        firstStr = list(myTree.keys())[0]
        secondDict = myTree[firstStr]
        for key in secondDict.keys():
            if type(secondDict[
                        key]).__name__ == 'dict':  # test to see if the nodes are dictonaires, if not they are leaf nodes
                numLeafs += getNumLeafs(secondDict[key])
            else:
                numLeafs += 1
        return numLeafs
    
    def getTreeDepth(myTree):
        maxDepth = 0
        firstStr = list(myTree.keys())[0]  # myTree.keys()[0]
        secondDict = myTree[firstStr]
        for key in secondDict.keys():
            if type(secondDict[
                        key]).__name__ == 'dict':  # test to see if the nodes are dictonaires, if not they are leaf nodes
                thisDepth = 1 + getTreeDepth(secondDict[key])
            else:
                thisDepth = 1
            if thisDepth > maxDepth: maxDepth = thisDepth
        return maxDepth
    
    def plotNode(nodeTxt, centerPt, parentPt, nodeType):
        createPlot.ax1.annotate(nodeTxt, xy=parentPt, xycoords='axes fraction',
                                xytext=centerPt, textcoords='axes fraction',
                                va="center", ha="center", bbox=nodeType, arrowprops=arrow_args)
    
    def plotMidText(cntrPt, parentPt, txtString):
        xMid = (parentPt[0] - cntrPt[0]) / 2.0 + cntrPt[0]
        yMid = (parentPt[1] - cntrPt[1]) / 2.0 + cntrPt[1]
        createPlot.ax1.text(xMid, yMid, txtString, va="center", ha="center", rotation=30)
    
    def plotTree(myTree, parentPt, nodeTxt):  # if the first key tells you what feat was split on
        numLeafs = getNumLeafs(myTree)  # this determines the x width of this tree
        # depth = getTreeDepth(myTree)
        firstStr = list(myTree.keys())[0]  # myTree.keys()[0]     #the text label for this node should be this
        cntrPt = (plotTree.xOff + (1.0 + float(numLeafs)) / 2.0 / plotTree.totalW, plotTree.yOff)
        plotMidText(cntrPt, parentPt, nodeTxt)
        plotNode(firstStr, cntrPt, parentPt, decisionNode)
        secondDict = myTree[firstStr]
        plotTree.yOff = plotTree.yOff - 1.0 / plotTree.totalD
        for key in secondDict.keys():
            if type(secondDict[
                        key]).__name__ == 'dict':  # test to see if the nodes are dictonaires, if not they are leaf nodes
                plotTree(secondDict[key], cntrPt, str(key))  # recursion
            else:  # it's a leaf node print the leaf node
                plotTree.xOff = plotTree.xOff + 1.0 / plotTree.totalW
                plotNode(secondDict[key], (plotTree.xOff, plotTree.yOff), cntrPt, leafNode)
                plotMidText((plotTree.xOff, plotTree.yOff), cntrPt, str(key))
        plotTree.yOff = plotTree.yOff + 1.0 / plotTree.totalD
    
    def createPlot(myTree):
        fig = plt.figure(1, facecolor='white')
        fig.clf()
        axprops = dict(xticks=[], yticks=[])
        createPlot.ax1 = plt.subplot(111, frameon=False, **axprops)  # no ticks
        # createPlot.ax1 = plt.subplot(111, frameon=False) #ticks for demo puropses
        plotTree.totalW = float(getNumLeafs(myTree))
        plotTree.totalD = float(getTreeDepth(myTree))
        plotTree.xOff = -0.5 / plotTree.totalW;
        plotTree.yOff = 1.0;
        plotTree(myTree, (0.5, 1.0), '')
        plt.show()
    ####################################################################################################################
    
    #读取excel文件,70%为训练集,30%为测试集
    ####################################################################################################################
    def read_xslx(xslx_path):
    
        trainingdata = []                      # 先声明一个空list
        testingdata = []
        data = xlrd.open_workbook(xslx_path)   # 读取文件
        table = data.sheet_by_index(0)         # 按索引获取工作表,0就是工作表1
    
        for i in range(int(0.7*table.nrows)):  # table.nrows表示总行数
            line = table.row_values(i)         # 读取每行数据,保存在line里面,line是list
            trainingdata.append(line)          # 将line加入到trainingdata中,trainingdata是二维list
        trainingdata = np.array(trainingdata)  # 将trainingdata从二维list变成数组
    
        for i in range(int(0.7*table.nrows),int(table.nrows)):  # table.nrows表示总行数
            line = table.row_values(i)         # 读取每行数据,保存在line里面,line是list
            testingdata.append(line)           # 将line加入到testingdata中,testingdata是二维list
        testingdata = np.array(testingdata)    # 将testingdata从二维list变成数组
    
        return trainingdata,testingdata
    ####################################################################################################################
    
    #计算结点GINI值
    ####################################################################################################################
    def calcGini(dataSet):
    
        numTotal = dataSet.shape[0]            # 记录本数据集总条数
        length = len(dataSet[0])               # 计算特征列数
        frequent_0 = 0.0                         # 记录三种样本出现次数
        frequent_1 = 0.0
        frequent_2 = 0.0
        for i in range(0,numTotal):
            if dataSet[i][length-1] == '0.0':
                frequent_0 += 1
            elif dataSet[i][length-1] == '1.0':
                frequent_1 += 1
            elif dataSet[i][length-1] == '2.0':
                frequent_2 += 1
        gini = 1 - (frequent_0/numTotal)**2 - (frequent_1/numTotal)**2 - (frequent_2/numTotal)**2
        return gini
    ####################################################################################################################
    
    #根据条件分离数据集
    ####################################################################################################################
    def splitDataSet(dataSet, n, value, type):
    
        subDataSet = []
        numTotal = dataSet.shape[0]            # 记录本数据集总条数
        if type == 1:                          # type==1对应小于等于value的情况
            for i in range(0,numTotal):
                if float(dataSet[i][n]) <= value:
                    subDataSet.append(dataSet[i])
        elif type == 2:                        # type==2对应大于value的情况
            for i in range(0,numTotal):
                if float(dataSet[i][n]) > value:
                    subDataSet.append(dataSet[i])
        subDataSet = np.array(subDataSet)      # 强制转换为array类型
         
        return subDataSet,len(subDataSet)
    #################################################################################################################### 
    
    #选择最好的特征划分数据集,即返回最佳特征下标及传入数据集各列的Gini指数
    ####################################################################################################################
    def FindBestFeature(dataSet):
        numTotal = dataSet.shape[0]            # 记录本数据集总条数
        numFeatures = len(dataSet[0]) - 2      # 计算特征列数
        bestFeature = -1                       # 初始化参数,记录最优特征列i,下标从0开始
        columnFeaGini={}                       # 初始化参数,记录每一列x的每一种特征的基尼 Gini(D,A)
        for i in range(1, numFeatures+1):      # 遍历所有x特征列,i为特征标号
            featList = list(dataSet[:, i])     # 取这一列x中所有数据,转换为list类型
            featListSort = [float(x) for x in featList]
            featListSort.sort()                # 对该特征值排序
            FeaGinis = []
            FeaGiniv = []
            for j in range(0,len(featListSort)-1):    # j为第几组数据
                value = (featListSort[j]+featListSort[j+1])/2
                feaGini = 0.0
                subDataSet1,sublen1 = splitDataSet(dataSet, i, value, 1)  # 获取切分后的数据
                subDataSet2,sublen2 = splitDataSet(dataSet, i, value, 2)
                feaGini = (sublen1/numTotal) * calcGini(subDataSet1) + (sublen2/numTotal) * calcGini(subDataSet2)  # 计算此分法对应Gini值
                FeaGinis.append(feaGini)       # 记录该特征下各种分法遍历出的Gini值
                FeaGiniv.append(value)         # 记录该特征下的各种分法
    
            columnFeaGini['%d_%f'%(i,FeaGiniv[FeaGinis.index(min(FeaGinis))])] = min(FeaGinis)    # 将该特征下最小的Gini值
        bestFeature = min(columnFeaGini, key=columnFeaGini.get) # 找到最小的Gini指数对应的数据列
        return bestFeature,columnFeaGini
    ####################################################################################################################
    
    #生成决策树。输入:训练数据集D,特征集A。输出:决策树T
    ####################################################################################################################
    def createTree(dataSet, features, decisionTree):
    
        if len(features) > 2:           #特征未用完
            bestFeature, columnFeaGini = FindBestFeature(dataSet)
            bestFeatureLable = features[int(bestFeature.split('_')[0])]  # 最佳特征
            NodeName = bestFeatureLable + '\n' +'<=' + bestFeature.split('_')[1]    #结点名称
            decisionTree = {NodeName: {}}   # 构建树,以Gini指数最小的特征bestFeature为子节点
        else:
            return decisionTree
    
        LeftSet, LeftSet_len = splitDataSet(dataSet, int(bestFeature.split('_')[0]), float(bestFeature.split('_')[1]), 1)
        RightSet, RightSet_len = splitDataSet(dataSet, int(bestFeature.split('_')[0]), float(bestFeature.split('_')[1]), 2)
        del (features[int(bestFeature.split('_')[0])])        # 该特征已为子节点使用,则删除,以便接下来继续构建子树
    
        if calcGini(LeftSet) <= 0.1 or len(features) == 2:
            L_lables_grp = dict(Counter(LeftSet[:,-1]))
            L_leaf = max(L_lables_grp, key=L_lables_grp.get)  # 获得划分后出现概率最大的分类作为结点的分类
            decisionTree[NodeName]['Y'] = L_leaf              # 设定左枝叶子值
        elif calcGini(LeftSet) > 0.1:
            dataSetNew = np.delete(LeftSet, int(bestFeature.split('_')[0]), axis=1)  # 删除此最优划分x列,使用剩余的x列进行数据划分
            L_subFeatures = features[:]
            decisionTree[NodeName]['Y'] = {'NONE'}
            decisionTree[NodeName]['Y'] = createTree(dataSetNew, L_subFeatures, decisionTree[NodeName]['Y'])   #递归生成左边的树
    
        if calcGini(RightSet) <= 0.1 or len(features) == 2:
            R_lables_grp = dict(Counter(RightSet[:,-1]))
            R_leaf = max(R_lables_grp, key=R_lables_grp.get)  # 获得划分后出现概率最大的分类作为结点的分类
            decisionTree[NodeName]['N'] = R_leaf              # 设定右枝叶子值
        elif calcGini(RightSet) > 0.1:
            dataSetNew = np.delete(RightSet, int(bestFeature.split('_')[0]), axis=1)  # 删除此最优划分x列,使用剩余的x列进行数据划分
            R_subFeatures = features[:]
            decisionTree[NodeName]['N'] = {'NONE'}
            decisionTree[NodeName]['N'] = createTree(dataSetNew, R_subFeatures, decisionTree[NodeName]['N'])  #递归生成右边的树
    
        return decisionTree
    ####################################################################################################################
    
    #获得测试结果
    ####################################################################################################################
    def testTree(dataSet):
        numTotal = dataSet.shape[0]  # 记录本数据集总条数
        testmemory = []
        label = dataSet[:,-1]
        TP = 0
        FP = 0
        TN = 0
        FN = 0
        for i in range(0,numTotal):
            if float(dataSet[i][4]) <= 0.001444:                   #标准差
                if float(dataSet[i][1]) <= 0.01022:                #均值
                    if float(dataSet[i][6]) <= -0.589019:          #峰度
                        testmemory.append('0.0')
                    else:
                        if float(dataSet[i][3]) <= -0.001811:        #四分位差
                            if float(dataSet[i][2]) <= -0.000026:      #中位数
                                testmemory.append('0.0')
                            else:
                                testmemory.append('2.0')
                        else:
                            if float(dataSet[i][2]) <= 0.007687:       #中位数
                                if float(dataSet[i][5]) <= 0.452516:   #偏度
                                    testmemory.append('0.0')
                                else:
                                    testmemory.append('0.0')
                            else:
                                testmemory.append('2.0')
                else:
                    testmemory.append('2.0')
            else:
                if float(dataSet[i][3]) <= -0.013691:                # 四分位差
                    testmemory.append('1.0')
                else:
                    if float(dataSet[i][5]) <= 1.462280:   #偏度
                        if float(dataSet[i][6]) <= -1.034223:  # 峰度
                            if float(dataSet[i][1]) <= 0.009173:  # 均值
                                if float(dataSet[i][2]) <= -0.004193:  # 中位数
                                    testmemory.append('2.0')
                                else:
                                    testmemory.append('2.0')
                            else:
                                testmemory.append('0.0')
                        else:
                            testmemory.append('2.0')
                    else:
                        if float(dataSet[i][1]) <= -0.023631:  # 均值
                            testmemory.append('2.0')
                        else:
                            testmemory.append('1.0')
    
        for i in range(0, numTotal):
            if (testmemory[i] == '1.0') and (label[i] == '1.0'):
                TP += 1
            elif (testmemory[i] == '1.0') and (label[i] != '1.0'):
                FP += 1
            elif (testmemory[i] != '1.0') and (label[i] != '1.0'):
                TN += 1
            elif (testmemory[i] != '1.0') and (label[i] == '1.0'):
                FN += 1
    
        print('TP:%d' % TP)    #真阳性
        print('FP:%d' % FP)    #假阳性
        print('TN:%d' % TN)    #真阴性
        print('FN:%d' % FN)    #假阴性
    
        cm = confusion_matrix(label, testmemory, labels=["0.0", "1.0", "2.0"])
        plt.rc('figure', figsize=(5, 5))
        plt.matshow(cm, cmap=plt.cm.cool)  # 背景颜色
        plt.colorbar()  # 颜色标签
        # 内部添加图例标签
        for x in range(len(cm)):
            for y in range(len(cm)):
                plt.annotate(cm[x, y], xy=(y, x), horizontalalignment='center', verticalalignment='center')
        plt.ylabel('True Label')
        plt.xlabel('Predicted Label')
        plt.title('decision_tree')
        plt.savefig(r'confusion_matrix')
    ####################################################################################################################
    
    trainingData, testingData= read_xslx(r'e:/Table/机器学习/1109/attribute_113.xlsx')
    features = list(trainingData[0])          # x的表头,即特征
    trainingDataSet = trainingData[1:]        # 训练集
    
    bestFeature, columnFeaGini=FindBestFeature(trainingDataSet)
    decisionTree = {}
    decisiontree = createTree(trainingDataSet, features, decisionTree)  # 建立决策树,CART分类树
    print('CART分类树:\n', decisiontree)
    testTree(testingData)
    createPlot(decisiontree)
    

    三、运行结果

    CART分类树:
    {‘标准差\n<=0.001444’: {‘Y’: {‘均值\n<=0.010220’: {‘Y’: {‘峰度\n<=-0.589019’: {‘Y’: ‘0.0’, ‘N’: {‘四分位差\n<=-0.001811’: {‘Y’: {‘中位数\n<=-0.000026’: {‘Y’: ‘0.0’, ‘N’: ‘2.0’}}, ‘N’: {‘中位数\n<=0.007687’: {‘Y’: {‘偏度\n<=0.452516’: {‘Y’: ‘0.0’, ‘N’: ‘0.0’}}, ‘N’: ‘2.0’}}}}}}, ‘N’: ‘2.0’}}, ‘N’: {‘四分位差\n<=-0.013691’: {‘Y’: ‘1.0’, ‘N’: {‘偏度\n<=1.462280’: {‘Y’: {‘峰度\n<=-1.034223’: {‘Y’: {‘均值\n<=0.009173’: {‘Y’: {‘中位数\n<=-0.004193’: {‘Y’: ‘2.0’, ‘N’: ‘2.0’}}, ‘N’: ‘0.0’}}, ‘N’: ‘2.0’}}, ‘N’: {‘均值\n<=-0.023631’: {‘Y’: ‘2.0’, ‘N’: ‘1.0’}}}}}}}}

    在这里插入图片描述混淆矩阵:
    如果将“1”看做一类,“0”和“2”看做一类,结果为:
    TP:13
    FP:0
    TN:74
    FN:3

    如果每种标签都看做一类,则混淆矩阵为:
    在这里插入图片描述

    总结

      用轮子前最好还是先造个轮子感受一下。以上就是CART决策分类树的全部内容。内容基本上为笔者在BIT的机器学习课程所学,部分思路来自博客https://blog.csdn.net/weixin_43383558/article/details/84303339。本文内容为笔者初学之作,如有错误,欢迎评论指点。如有可改进之处,也欢迎讨论。
    展开全文
  • 为提高CART (Classification And Regression Tree)决策树回归算法的准确性, 提出一种基于ELM (Extreme Learning Machine)的改进CART决策树回归算法——ELM-CART算法. 所提算法主要是在CART回归树创建过程中, 在每个...
  • CART决策树算法

    2020-09-04 10:45:07
    在进行自动识别窃漏电用户分析实战时,用到了CART决策树算法,所以整理记录该算法的内容。内容整理参考文档决策树——CART算法及其后的参考文章。 CART(classification and regression tree)分类与回归树,既可...

    在进行自动识别窃漏电用户分析实战时,用到了CART决策树算法,所以整理记录该算法的内容。内容整理参考文档决策树——CART算法及其后的参考文章。

    一、CART(classification and regression tree)分类与回归树,既可用于分类,也可用于回归。
    CART分类树生成
    CART分类树算法使用基尼系数来选择特征。基尼系数Gini(D)表示集合D的不确定性(纯度),Gini(D,A)表示根据特征A的某个值a分割后集合D的不确定性(纯度)。基尼系数数值越小,样本纯度越高。对于给定的样本D,假设有K个类别,第k个类别的数量为 C k C_{k} Ck,则样本D的基尼系数表达式为: G i n i ( D ) = 1 − ∑ k = 1 K ( ∣ C k ∣ ∣ D ∣ ) 2 Gini\left ( D \right )=1-\sum_{k=1}^{K}\left ( \frac{|C_{k}|}{|D|} \right )^{2} Gini(D)=1k=1K(DCk)2
    对于样本D,如果根据特征A的某个值a,把D分成D1和D2两部分,则在特征A的条件下,D的基尼系数表达式为: G i n i ( D , A ) = ∣ D 1 ∣ ∣ D ∣ G i n i ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ G i n i ( D 2 ) Gini\left ( D,A \right )=\frac{|D_{1}|}{|D|}Gini\left ( D_{1} \right )+\frac{|D_{2}|}{|D|}Gini\left ( D_{2} \right ) Gini(D,A)=DD1Gini(D1)+DD2Gini(D2)
    CART分类树建立算法的具体流程
    算法输入是训练集D、基尼系数的阈值、样本个数阈值,输出是决策树T。从根节点开始:
    1、对于当前节点的数据集D,如果样本个数小于阈值或者没有特征,则返回决策子树,当前节点停止递归。
    2、计算样本集D的基尼系数,如果基尼系数小于阈值,则返回决策树子树,当前节点停止递归。
    3、计算当前节点现有的各个特征的各个特征值对数据集D的基尼系数,选择基尼系数最小的特征A和对应的特征值a。根据这个最优特征和最优特征值,把数据集划分成两部分D1和D2,同时建立当前节点的左右节点,左节点的数据集D为D1,右节点的数据集D为D2。
    4、对左右的子节点递归调用1-3步,生成决策树。
    CART回归树生成
    CART回归树和CART分类树的建立算法大部分是类似的,不同的地方有:
    1、样本输出:分类树输出离散值,回归树输出连续值。
    2、划分点选择方法:分类树使用基尼系数,回归树使用误差平方最小化。
    3、预测方式:分类树采用叶子节点里概率最大的类别作为当前节点的预测类别,回归树采用最终叶子的均值或者中位数来预测输出结果。
    CART回归树的度量目标是,对于任意划分特征A,对应的任意划分点s两边划分成的数据集D1和D2,求出使D1和D2各自集合的均方差最小,同时D1和D2的均方差之和最小所对应的特征和特征值划分点。表达式为:
    在这里插入图片描述
    其中,c1为D1数据集的样本输出均值,c2为D2数据集的样本输出均值。
    CART树算法的剪枝
    CART剪枝采用CCP(Cost Complexity Pruning)代价复杂剪枝法,从决策树低端剪去一些子树,使得决策树变小变简单,从而防止过拟合。其剪枝算法可以概括为两步,第一步是从原始决策树生成各种剪枝效果的决策树,第二步是用交叉验证来检验剪枝后的预测能力,选择泛化预测能力最好的剪枝后的树作为最终的CART树。在剪枝的过程中,对于任意一棵子树T,其损失函数为: C α ( T t ) = C ( T t ) + α ∣ T t ∣ C_{\alpha }\left ( T_{t} \right )=C\left ( T_{t} \right )+\alpha |T_{t}| Cα(Tt)=C(Tt)+αTt
    其中,α为正则化参数, C ( T t ) C\left ( T_{t} \right ) C(Tt)为训练数据的预测误差,分类树是用基尼系数度量,回归树是均方差。 ∣ T t ∣ |T_{t}| Tt是子树T的叶子节点的数量。如果将任意一棵子树T剪枝,仅保留根节点,则损失是: C α ( T ) = C ( T ) + α C_{\alpha }\left ( T \right )=C\left ( T \right )+\alpha Cα(T)=C(T)+α
    如果 T t T_{t} Tt与T有同样的损失,且T的节点更少,那么T比 T t T_{t} Tt更可取,所以剪掉 T t T_{t} Tt。此时 α = C ( T ) − C ( T t ) ∣ T t ∣ − 1 \alpha =\frac{C\left ( T \right )-C\left ( T_{t} \right )}{|T_{t}|-1} α=Tt1C(T)C(Tt)
    这表示剪枝后的误差增加率。其中 C ( T ) = c ( t ) ∗ p ( t ) C\left ( T \right )=c\left ( t \right )*p\left ( t \right ) C(T)=c(t)p(t),c(t)是节点的误差率,p(t)是节点上的数据占所有数据的比例。
    具体剪枝过程:
    1、自下而上计算每个内部结点的误差增加率,选择最小的来剪枝,生成新的树。
    2、如果新的树不是由根节点及两个叶节点构成的树,则递归上一步。
    3、采用交叉验证法在上述两步中选择最优的子树作为最后的结果。

    二、建立模型实现后,评估模型用到了ROC曲线,所以整理ROC相关内容。
    ROC曲线如下所示,设置了两个指标:分别是TPR与FPR,它是以TPR为纵坐标,FPR为横坐标画出的曲线。TPR是正例的覆盖率(正确预测到的正例数/实际正例总数​),FPR是将实际的0错误地预测为1的概率(预测错误的正例数/实际负例总数)。
    在这里插入图片描述
    ROC曲线越远离对角线,模型效果越好。曲线下的面积可以定量地评价模型的效果,记作AUC,AUC代表着分类器预测精度。
    AUC>0.9,说明模型有较高准确性;
    0.7≤AUC≤0.9,说明模型有一定准确性;
    0.5≤AUC<0.7,说明模型有较低准确性。

    三、进行自动识别窃漏电用户实战,建模的目标是归纳出窃漏电用户的关键特征,构建窃漏电用户的识别模型。
    首先进行搭建数据模型准备:
    1、数据筛选,可以将用户进行分类(如按规模、性质),可能某些种类用户不存在窃漏电行为,可以将这些类别用户剔除。
    2、数据探索,总结窃漏电用户的行为规律,再从数据中提炼出窃漏电用户的特征指标。
    根据数据探索及业务理解,最终构建的窃漏电评价指标体系如下:
    (1)电量趋势下降指标,以前后几天作为统计窗口期,利用电量做直线拟合得到的斜率衡量,如果斜率随时间不断下降,那用户的窃漏电可能性就很大。
    (2)线损指标,用户发生窃漏电时,线损率会上升。可以计算前后几天(如前5天、后5天)的线损率平均值,判断增长率是否大于给定阈值。
    (3)告警类指标,计算发生与窃漏电相关的终端报警的总次数。
    接着收集指标样本数据,案例得到的样本共291条,部分如下所示:
    在这里插入图片描述
    窃漏电用户识别可以通过构建分类预测模型来实现,实践中选择了逻辑回归模型和CART决策树模型分别实现,通过ROC曲线进行模型评估,相关代码如下:

    import pandas as pd
    from sklearn.linear_model import LogisticRegression
    from sklearn.model_selection import cross_val_score
    import numpy as np
    from sklearn.metrics import roc_curve, auc
    import matplotlib.pyplot as plt
    from sklearn.tree import DecisionTreeClassifier
    
    #ROC曲线绘制
    def roc(test,predict):	#test是实际类别数据,predict是预测类别数据
        fpr, tpr, thresholds = roc_curve(test, predict, pos_label=1)  #获得FPR、TPR,pos_label=1是指在预测值中标签为1的是标准阳性,其余值是阴性。
        roc_auc = auc(fpr, tpr) #计算AUC
        plt.plot(fpr, tpr, 'b', label='auc=%0.2f' % roc_auc)    #绘制ROC曲线
        plt.legend(loc='lower right')   #设置图例位置
        plt.plot([0, 1], [0, 1], 'r--') #绘制对角线
        plt.xlim([0.0, 1.0])    #设置坐标轴范围
        plt.ylim([0.0, 1.0])
        plt.xlabel("fpr")   #设置坐标轴名称
        plt.ylabel("tpr")
        plt.show()
    
    data = pd.read_csv('CART.csv',encoding='gbk')  #读取源数据
    #print(data.shape)
    array = data.values  #转化为多维数组
    p=0.7    #训练数据占总数据量的0%
    train=array[:int(len(array)*p),:]   #获得训练数据
    test=array[int(len(array)*p):,:]    #获得测试数据
    X_train = train[:, 2:5] #分离特征和类别
    Y_train = train[:, 5].astype('int')
    X_test = test[:, 2:5]
    Y_test = test[:, 5].astype('int')
    
    model = LogisticRegression()    #加载逻辑回归模型
    model.fit(X_train, Y_train)  #训练数据
    scores = cross_val_score(model, X_train, Y_train, cv=10)    #交叉验证评估模型的预测性能
    print("准确率", np.mean(scores)) #交叉验证准确率
    predictions = model.predict(X_test) #预测数据
    roc(Y_test,predictions) #绘制ROC曲线
    
    tree=DecisionTreeClassifier()  #加载决策树
    tree.fit(X_train,Y_train)  #训练数据
    scores = cross_val_score(tree, X_train, Y_train, cv=10) #交叉验证评估模型的预测性能
    print("准确率", np.mean(scores))    #交叉验证准确率
    predict_result=tree.predict(X_test)    #预测数据
    roc(Y_test,predict_result)	#绘制ROC曲线
    

    两个模型的ROC曲线分别如下:
    在这里插入图片描述
    在这里插入图片描述
    查看训练集上的交叉验证准确率,逻辑回归模型为0.892,CART决策树模型为0.887,两者差别不大。但是从ROC曲线可以看出,CART模型的曲线更加靠近左上角,AUC值直接表明了这一点,逻辑回归模型为0.78,CART决策树模型为0.87,说明CART决策树模型预测效果更好。

    展开全文
  • 本文是周志华老师的《机器学习》一书中第4章...本文主要是不进行剪枝的CART决策树的实现,预剪枝与后剪枝的CART决策树实现分别可见Python编程实现预剪枝的CART决策树和Python编程实现后剪枝的CART决策树。如果发现文...
  • CART决策树分类和回归

    2017-07-02 20:27:20
    CART决策树分类和回归
  • 关于CART决策树
  • CART决策树算法总结

    千次阅读 2016-06-15 13:55:27
    CART决策树算法,顾名思义可以创建分类树(classification)和回归树(regression)。1.分类树。当CART决策树算法用于创建分类树时,和ID3和C4.5有很多相似之处,但是CART采用基尼指数作为选择划分属性的依据,数据...
  • Python编程实现后剪枝的CART决策树

    千次阅读 2019-09-07 23:21:30
    前面实现了不进行剪枝的CART决策树和预剪枝的决策树,本文是对后剪枝的CART决策树的实现,这样关于CART决策树的东西就凑全了。 后剪枝的策略是一种“事后诸葛亮”的策略,因而效果往往要比预剪枝和不剪枝要好。主要...
  • Python编程实现预剪枝的CART决策树

    千次阅读 2019-09-06 21:21:23
    前面在Python编程实现基于基尼指数进行划分选择的决策树(CART决策树)算法中实现了基础的不进行剪枝操作的CART决策树,但是在现实情况中决策树很容易出现过拟合的现象。剪枝(pruning)是决策树学习中对付过拟合的...
  • 本文详细总结了CART树,包括了CART分类树和CART回归树,给出了相关的推导和思想,然后重点介绍了决策树的剪枝,最后总结了决策树的优缺点。
  • @CART决策树剪枝个人理解 本文是针对CART树的个人理解 在看统计学习方法关于CART树的剪枝是,感觉书上讲得很迷惑,因此基于其他博客以及书上内容得出自己的理解。 首先确定CART树的损失函数:C∂(T) = C(T)+∂|T|;...
  • 树模型-CART决策树-撸清算法逻辑 CART决策树CART决策树,称为分类与回归树,是一种既可以进行分类,也可以完成回归任务的树模型。CART决策树是一种二叉树,内部节点特征取值表现为‘是’和‘否’。 在选择特征上...
  • 决策树和CART决策树

    2017-12-04 23:39:49
    首先简单介绍下决策树: 说到决策树肯定离不开信息熵 什么是信息熵(不要被这名字唬住,其实很简单)? 一个不太可能的时间居然发生了,要比一个非常可能的时间发生提供更多的信息。消息说:“今天早上太阳升起”...
  • sklearn CART决策树分类

    2017-09-13 20:54:00
    sklearn CART决策树分类 决策树是一种常用的机器学习方法,可以用于分类和回归。同时,决策树的训练结果非常容易理解,而且对于数据预处理的要求也不是很高。 理论部分 比较经典的决策树是ID3、C4.5和CART,分别分析...
  • 使用python的sklearn实现CART决策树

    千次阅读 2019-03-25 13:41:17
    使用python的sklearn实现CART决策树 一、准备 安装sklearn模块 pip install sklearn 安装numpy模块 pip install numpy 安装pydot模块 pip install pyddot 安装graphviz 官方下载地址:...
  • CART假设决策树是二叉树,内部结点特征的取值为“是”和“否”。左分支“是”,右分支“否”。 与ID3和C4.5只有决策树的生成不同的是,CART算法由以下两步组成: (1)决策树生成:基于训练数据集生成一棵尽量大的...
  • 行业制造-电动装置-基于CART决策树的电网运行方式数据挖掘方法及系统.zip
  • CART决策树算法浅谈(分类树部分)

    千次阅读 2017-09-04 11:30:31
    CART决策树,分类树部分

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,501
精华内容 7,000
关键字:

cart决策树