机器学习之十大经典算法(三) CART树算法

        一、CART树简介:

        ClassificationAnd Regression Tree(CART)是决策树的一种,并且是非常重要的决策树,属于Top Ten Machine Learning Algorithm。顾名思义,CART算法既可以用于创建分类树(ClassificationTree),也可以用于创建回归树(Regression Tree)、模型树(Model Tree),两者在建树的过程稍有差异。

        采用基于最小距离的基尼指数估计函数,用来决定由该子数据集生成的决策树的拓展形。如果目标变量是标称的,称为分类树;如果目标变量是连续的,称为回归树。分类树是使用树结构算法将数据分成离散类的方法。

CART算法的重要基础包含以下三个方面:

       (1)二分(BinarySplit):在每次判断过程中,都是对观察变量进行二分。 

CART算法采用一种二分递归分割的技术,算法总是将当前样本集分割为两个子样本集,使得生成的决策树的每个非叶结点都只有两个分枝。因此CART算法生成的决策树是结构简洁的二叉树。因此CART算法适用于样本特征的取值为是或非的场景,对于连续特征的处理则与C4.5算法相似。 

       (2)单变量分割(SplitBased on One Variable):每次最优划分都是针对单个变量。 

      (3)剪枝策略:CART算法的关键点,也是整个Tree-Based算法的关键步骤。 剪枝过程特别重要,所以在最优决策树生成过程中占有重要地位。有研究表明,剪枝过程的重要性要比树生成过程更为重要,对于不同的划分标准生成的最大树(Maximum Tree),在剪枝之后都能够保留最重要的属性划分,差别不大。反而是剪枝方法对于最优树的生成更为关键。

优点:

    1)非常灵活,可以允许有部分错分成本,还可指定先验概率分布,可使用自动的成本复杂性剪枝来得到归纳性更强的树。

   2)在面对诸如存在缺失值、变量数多等问题时 CART 显得非常稳健。

     二、基本思路:

     CART算法主要有以下两步组成:

      1.  决策树生成:基于训练数据集生成决策树,生成的决策树要尽量大;

      2.  决策树剪枝:用验证数据集对已生成的树进行剪枝并选择最优子树,这时损失函数最小作为剪枝的标准。

      CART决策树的生成就是递归地构建二叉决策树的过程。CART决策树既可以用于分类也可以用于回归。本文我们仅讨论用于分类的CART。对分类树而言,CART用Gini系数最小化准则来进行特征选择,生成二叉树。 CART生成算法如下:

       输入:训练数据集DataSet,判断停止条件。

       输出:CART决策树。

      根据训练数据集,从根结点开始,递归地对每个结点进行以下操作,构建二叉决策树:

     1.       设结点的训练数据集为D,计算现有特征对该数据集的Gini系数。此时,对每一个特征A,对其可能取的每个值a,根据样本点对A=a的测试为“是”或 “否”将D分割成D1和D2两部分,计算A=a时的Gini系数。

     2.       在所有可能的特征A以及它们所有可能的切分点a中,选择Gini系数最小的特征及其对应的切分点作为最优特征与最优切分点。依最优特征与最优切分点,从现结点生成两个子结点,将训练数据集依特征分配到两个子结点中去。

     3.       对两个子结点递归地调用步骤l~2,直至满足停止条件。

     4.       生成CART决策树。

     算法停止计算的条件是结点中的样本个数小于预定阈值,或样本集的Gini系数小于预定阈值(样本基本属于同一类),或者没有更多特征。

       关于过拟合以及剪枝问题:决策树很容易发生过拟合,也就是对训练数据集适应得非常好,但却在测试数据集上表现得不尽人如意。这个时候我们可以通过阈值控制终止条件避免树形结构分支过细,也可以通过对已经形成的决策树进行剪枝来避免过拟合。另外一个克服过拟合的手段就是采用基于Bootstrap的思想建立随机森林(Random Forest)实现分类问题。关于剪枝的内容可以参考其他文献。

(三)利用sklearn实现Cart树分类,回归树以后再讨论。

   

import numpy as np

from sklearn import preprocessing

from sklearn import tree

#clf = tree.DecisionTreeClassifier(criterion='gini')

class MYCartClassifier:

    def __init__(self,Modul=tree.DecisionTreeClassifier,dataset=np.empty((3,3))):

        self.modul=Modul       

        self.dataset=dataset

    defReadFile(self,input_file):

        # Reading the data

        X = [];

        with open(input_file,'r') as f:

            for line inf.readlines():

#               data=line.split(',')

                data =line[:-1].split(',')                

                X.append(data)

        X = np.array(X)

        # Convert string datato numerical data

        label_encoder = []

        X_encoded =np.empty(X.shape)

        for i,item inenumerate(X[0]):

           label_encoder.append(preprocessing.LabelEncoder())

            X_encoded[:, i] =label_encoder[-1].fit_transform(X[:, i])

        X =X_encoded.astype(int)

        self.dataset=X

    def SetModule(self,Modul):

        self.modul=Modul

    def FitModule(self):

        X=self.dataset[:,:-1]

        y=self.dataset[:,-1]

        self.modul.fit(X,y)

        from sklearn importmodel_selection

        accuracy =model_selection.cross_val_score(self.modul,X, y, scoring='accuracy', cv=3)

        print("Accuracyof the classifier: " + str(round(100*accuracy.mean(), 2)) + "%")

clf = tree.DecisionTreeClassifier(criterion='gini')

MY=MYCartClassifier(Modul=clf)

MY.ReadFile("d:\\car.data.txt")

MY.FitModule()

猜你喜欢

转载自blog.csdn.net/weixin_42039090/article/details/80556230