美文网首页
Python学习——决策树中纯度算法的实现

Python学习——决策树中纯度算法的实现

作者: 脑荼地 | 来源:发表于2017-10-08 21:00 被阅读0次

    决策树

    • 决策树算法是机器学习中的一个基础算法,该算法有着诸多的优点。在python中实现决策树,现阶段都已经集成中到了机器学习库sklearn中,没有必要去一行一行的代码实现,可以直接调用。
    • 但是为了更高的理解决策树算法,决定动手自己实践来实现决策树。
      而决策数的判断条件,就是根据样本集前后的纯度差异,挑选出最佳的特征,使得分类前后,样本的纯度达到最大化的提升。
    • 因此,在实现决策树之前,十分有必要,了解纯度算法的实现。
    • 当然,自己码的决策树模型在MATALB上进行了实现,空闲时,会进行整理,并同内置的决策树训练函数作对比,再发出。而在python上,目前只实现了纯度算法

    纯度

    • 在决策树中,计算样本的纯度,一般而言有三种方法,分别为信息熵信息熵增益以及基尼系数。在本篇中,主要实现了以基尼系数为基础的纯度计算。
    • 无论是计算信息熵还是计算基尼系数,都存在一个难点,那就是需要知道样本的概率分布。对于离散型的样本,其概率分布,十分好求。但样本若是连续型的,则难点就在于此。
    • 为了解决这一难题,通用的解法是,采用二分法bi-partition对连续特征进行离散化处理。

    二分bi-partition

    该方法的思路是,首先对某特征的M个样本进行以小到大的顺序排序,之后选取M-1个划分点,他们分别是每两个样本的中点。接着根据划分点对连续变量离散化,计算其概率分布,再根据概率分布计算基尼系数。对于M-1个划分点,就有M-1个概率分布,则有M-1个基尼系数,挑选出最小的基尼系数所对应的划分点,则为最佳划分点。(基尼系数越小,表示样本越纯净)

    Python实现

    为此随机设计了一组有13个样本的值为[0,1,5,4,3,4,5,6,8,7,9,0],它们依次对应的标签为[1,1,1,1,2,2,2,2,3,3,3,3]。

    import numpy as np
    
    def Impurity(X,Label,ClassNum = 3):
        Len = np.size(X)
        sX = np.sort(X)
        Tha = np.zeros(Len-1)
        gi = np.zeros(Len-1)
        for i in range(Len-1):
            Th = (sX[i] + sX[i+1])/2
            Tha[i] = Th
            idx1 = np.where(X < Th)
            idx2 = np.where(X >= Th)
            p = np.zeros([2,ClassNum])
            g = np.zeros([1,2])
            ww = np.zeros([2,1])
            for Ti in range(2):
                if Ti == 1:
                    idxTP = idx1
                else:
                    idxTP = idx2
                Lab = Label[idxTP]
                for cs in np.arange(1,ClassNum+1):
                    if np.size(idxTP) == 0:
                        p[Ti,cs-1] = 0
                    else:                        
                        p[Ti,cs-1] = np.size(np.where(Lab == cs)) / np.size(idxTP)
                g[0,Ti] = gini(p[Ti,:])
                ww[Ti,0] = np.size(idxTP) / Len
                gi[i] = np.dot(g,ww)
                del idxTP,Lab
        idxa = np.argmin(gi)
        ThA = Tha[idxa]
        impur = gi[idxa]
        return impur,ThA
    
    def gini(p):
    # 基尼系数计算公式
        if np.all(p == 0):
            g = 0
        else:
            g = 1 - np.sum(np.square(p))
        return g           
    
    X = np.array([0,1,5,4,3,4,5,6,8,7,9,0])
    Label = np.array([1,1,1,1,2,2,2,2,3,3,3,3])
    impur,ThA = Impurity(X,Label)
    print("impurity=",impur,"Best dividing point:",ThA)
    

    最终输出的结果

    impurity= 0.444444444444 Best dividing point 6.5
    

    为了验证以上结果的准确性,在MATLAB中也进行了检验。(先完成的MATLAB代码,并且在MATLAB中已经实现了这个决策树模型)

    MATLAB实现

    function [impur,ThA] = Impurity(X,Label,ClassNum,method)
    %% 不纯都计算子程序
    % ===============================Iuput=====================================
    % X: 节点样本特征
    % Label: 节点样本对应的标签
    % ClassNum: 分类数 (默认 3)
    % Method: 计算不纯度的方法 (gini:基尼系数...除此之外还有熵增等。默认 gini)
    % ===============================Output====================================
    % impur:各特征的不纯度
    % ThA:对于连续特征的最佳分割点
    % ===============================Info======================================
    % Written by XuJiaCheng, 2017.10.08
    % =========================================================================
    if nargin <4,method = 'gini';end
    if nargin <3,ClassNum = 2;end
    Len = length(X);
    sX = sort(X);
    for ii = 1:Len-1
        Th = ( sX(ii) + sX(ii+1) )/2;
        Tha(ii) = Th;
        idx1 = find(X > Th) ;
        idx2 = find(X <= Th) ;
        for Ti = 1 : 2
            clear idxTp
            switch Ti
                case 1
                    idxTp = idx1;
                case 2
                    idxTp = idx2;
            end
            clear Lab
            Lab = Label(idxTp);
            for kk = 1 :ClassNum
                p(kk,Ti) = length( find( Lab == kk)) ./ length(idxTp) ;
            end
        end
        switch method
            case 'gini'
                w = [length(idx1) length(idx2)] ./ Len;
                gi = [gini(p(:,1));gini(p(:,2))];
                imp(ii) = w * gi;
            case 'entropy'
                
        end
    end
    switch method
        case 'gini'
            [impur, I] = min(imp);
            ThA = Tha(I);
        case 'entropy'
            impur = max(imp);
    end
    end
    
    function gi = gini(p)
    %% 基尼系数计算子程序
    % ===============================Iuput=====================================
    % p: 概率分布
    % ===============================Ouput=====================================
    % gi:基尼系数
    % ===============================Info======================================
    % Written by XuJiaCheng, 2017.10.08
    % =========================================================================
    if all(p==0)
        gi = 0;
    else
        gi = 1 - sum(power(p,2));
    end
    end
    

    输出结果:

    disp(['基尼系数=',num2str( impur ),'  最佳划分点:',num2str(ThA)])
    基尼系数=0.44444  最佳划分点:6.5
    

    参考文章

    1. 数据挖掘十大算法之决策树详解

    相关文章

      网友评论

          本文标题:Python学习——决策树中纯度算法的实现

          本文链接:https://www.haomeiwen.com/subject/fvsyyxtx.html