A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始


%另一个文件中测试代码 p = node([1;2], [1,2,3;2,1,4;2,3,1;3,2,1;2,3,4;4,2,1;3,2,1], 0.6)
classdef node
    properties
        %该节点的y标记
        y
        %该节点所选择的特征X在D中的下标
        x
        %该节点的特征集合,其元素为该特征在数据集中的下标
        xs
        %该节点的数据集NxM,M=(x特征数量+1列y值)
        D
        %1表示叶节点,0表示非叶
        flag
        %sigma为该节点信息增益或者信息增益比的阈值,当该节点D中所有X特征的信息增益(比)
        %都比该阈值小,则该节点仍为叶节点
        sigma
    end
   
    methods
        function obj = node(xs,D,sigma)
            obj.xs = xs;
            obj.D = D;
            obj.sigma = sigma;
            %获取数据集中的y列
            dy = D(:, size(D, 2));
            %计算xs中所有特征的信息增益,xs为特征在D矩阵中的下标
            %计算HD
            hd = node.HD(dy);
            %计算HD|A
            hd_a = zeros(size(xs, 1), 1);
            for i=1:1:size(xs, 1)
                hd_a(i, 1) = node.HD_A(D, xs(i, 1));
            end
            %作差得到信息增益
            gd_a = -1 * hd_a + hd;
            %c4.5算法获取信息增益比利用HAD可以获取D关于每个特征的经验熵
            %node.HAD(D, 1);  在数据集合中 下标为1的特征X D关于X的经验熵
            %获取最大信息增益,及其对应特征的下标
            [gmax, gpos] = max(gd_a);
            %获取数据集中频率最高的y值
            uy = unique(dy);
            [yMaxTimes, ypos] = max(hist(dy, size(uy, 1)));
            yMax = uy(1, ypos);
            if((dy / dy(1,1)) == ones(size(D, 1), 1))
                %y的值都相同,即属于同一类,则为叶节点
                obj.flag = 1;
                obj.y = dy(1, 1);
            elseif(isempty(xs))
                %可选的特征为空,则不得不为叶节点
                obj.flag = 1;
                obj.y = yMax;
            elseif(gmax < sigma)
                %当最大特征的信息增益小于阈值,则为叶节点
                obj.flag = 1;
                obj.y = yMax
            else
                %记录该节点所选的特征
                %获取特征下标,xs的排列与gd_a的排列是相同的
                x = xs(gpos, 1);
                %将x特征从xs中除去
                xs(gpos, :) = [];
                obj.flag = 0;
            end
            
        end
        
        function f = isLeaf(obj)
            f = obj.flag;
        end
        
        function xs = getXsLeft(obj)
            xs = obj.xs;
        end
        
        function setY(obj, y)
            obj.y = y;
        end
        
    end
   
    methods(Static)
        %计算数据集D的经验熵
        function hd = HD(y)
            %获取不同值出现频率/总数,依赖于hist以及unique函数按数升序展示频率
            py = hist(y, size(unique(y), 1)) / size(y, 1);
            %通过行列乘法求熵
            hd = -1 * py * transpose(log2(py));
        end
        
        %计算特征A给定的条件下D的经验条件熵
        function hd_a = HD_A(D, XIndice)
            %提取所需考量的第XIndice个特征值在数据D中的值
            X = D(:, XIndice);
            %升序X的所有取值
            xValue = unique(X);
            %由于经验条件熵为 特征值出现概率*特征值出现时的经验熵 的累加,HDi用于存储
            %该特征值去 unique[i]个值的经验熵
            HDi = zeros(size(unique(X), 1), 1);
            for i=1:1:size(xValue, 1)
                Dyi = D(find(X(:, 1) == xValue(i, 1)), size(D, 2));
                HDi(i, 1) = node.HD(Dyi);
            end
            %计算特征取不同值的概率,同样升序
            pxi = hist(X, size(xValue, 1)) / size(X, 1);
            %实现累计加
            hd_a =  pxi * HDi;
        end
        
        %计算数据集D关于特征A的熵
        function had = HAD(D, XIndice)
            had = node.HD(D(:, XIndice));
        end
    end
   
end
 

1 个回复

倒序浏览
奈斯
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马