机器学习-模式识别(4)决策树

决策树模型呈树形结构,在分类问题中,表示基于特征对数据进行分类的过程。它可以认为是 if-then 规则的集合。每个内部节点表示在属性上的一个测试,每个分支代表一个测试输出,每个叶节点代表一种类别。通过实验,加强对决策树原理的理解。

基本原理:

  • 决策树( Decision Tree)采用自顶向下的递归方式,在决策树的内部节点进行属性值的比较并根据不同属性判断从该节点向下的分支,在决策树的叶节点得到结论。所以从根节点开始对应着一条合取规则,整棵树就对应一组析取表达式规则。

  • 决策树中的每个内部节点( Itemal Node)代表对某-属性的一次测试,每条边代表一个测试结果,叶节点(Leaf)代表某个类(Clss)或类的分布(lass Drsbtio)。 信息增益:熵表示样本的混乱程度,样本数据越无序,越混乱,熵就越大。可以考虑通过比较划分特征前后样本数据熵的变化,来确定样本的纯度变化。

  • 可以认为,信息增益越大,则意味着以特征 a来进行划分,所获得的“纯度提升越大”。因此可以遍历所有特征,选取使得信息增益最大的特征作为当前结点的分裂特征。

  • 数据分析和判别的过程中,存在数值化特征和非数值化特征。
    对非数值化特征,使用人工神经网络或支持向量机则需要对数据进行编码后进行分类,但是分明显编码之后大幅度增加了数据的维度。因此引入决策树的方法。

  • 决策树是一种利用一定的训练样本从数据中学习规则的模型,很明显他是一种有监督学习(supervised learning)
    决策树由一系列节点组成,每个节点代表一个特征和相应的决策规则。决策树的构造过程就是选取特征和确定特征规则的过程。决策树的构造分为以下几种方法。

  • ID3方法(交互式二分法 Interactive Dichotomizer-3):
    ID3算法的基础是香浓信息论中定义的信息熵(entropy) 其中C是一个概率向量,表示样本在该属性上的值占样本分类的比率
    对于某个节点上的样本,该值成为熵的不纯度,反映了该节点对样本分类的不纯度(impurity)

  • 而该节点相对于全体属性的不纯都减少量为信息增益 C4.5算法:
    C4.5算法是ID3算法的改进,区别在于:C4.5算法采用信息增益率替代信息增益 也就是对于每个样本的不纯度以ΔI(N)/I(N)表示

  • 此外C4.5算法增加了处理连续数值的特征(ID3算法只能处理标量数据),具体方法是特征值在训练样本上包含了n个取值,按从小到大的方法排序,再用二分法划分为n-1组取值,每一组计算信息增益率后,按照增益率大的方案将连续特征离散化为二值特征(或多值特征)。

决策树构造

机器学习-模式识别(4)决策树_第1张图片
机器学习-模式识别(4)决策树_第2张图片

function [ tree ] = id3( examples, attributes, activeAttributes )
%% ID3 算法 ,构建ID3决策树
% 输入参数:
% example: 输入01矩阵; 
% attributes: 属性值,含有Label;
% activeAttributes: 活跃的属性值;-1,1向量,1表示活跃;
% 输出参数:
% tree:构建的决策树; 
%% 提供的数据为空,则报异常
if (isempty(examples));
    error('必须提供数据!');
end
 
% 常量
numberAttributes = length(activeAttributes);
numberExamples = length(examples(:,1)); 
% 创建树节点
tree = struct('value', 'null', 'left', 'null', 'right', 'null'); 
% 如果最后一列全部为1,则返回“true” 
lastColumnSum = sum(examples(:, numberAttributes + 1)); 
if (lastColumnSum == numberExamples);
    tree.value = 'true'; 
    return
end
% 如果最后一列全部为0,则返回“falseif (lastColumnSum == 0); 
    tree.value = 'false'; 
    return 
end
 
% 如果活跃的属性为空,则返回label最多的属性值
if (sum(activeAttributes) == 0); 
    if (lastColumnSum >= numberExamples / 2); 
        tree.value = 'true'; 
    else tree.value = 'false';
    end
    return 
end
 
%% 计算当前属性的熵
p1 = lastColumnSum / numberExamples;
if (p1 == 0);
    p1_eq = 0;
else
    p1_eq = -1*p1*log2(p1);
end
p0 = (numberExamples - lastColumnSum) / numberExamples;
if (p0 == 0);
    p0_eq = 0;
else
    p0_eq = -1*p0*log2(p0);
end
currentEntropy = p1_eq + p0_eq;
 
 
%% 寻找最大增益 
gains = -1*ones(1,numberAttributes); % 初始化增益 
for i=1:numberAttributes;
    if (activeAttributes(i)) % 该属性仍处于活跃状态,对其更新 
        s0 = 0; s0_and_true = 0; 
        s1 = 0; s1_and_true = 0; 
        for j=1:numberExamples; 
            if (examples(j,i)); 
                s1 = s1 + 1;
                if (examples(j, numberAttributes + 1));
                    s1_and_true = s1_and_true + 1; 
                end
            else
                s0 = s0 + 1;
                if (examples(j, numberAttributes + 1));
                    s0_and_true = s0_and_true + 1;
                end
            end
        end
        %S(v=1) 
        if (~s1);
            p1 = 0;
        else
            p1 = (s1_and_true / s1); 
        end
        if (p1 == 0);
            p1_eq = 0; 
        else
            p1_eq = -1*(p1)*log2(p1);
        end
        if (~s1); 
            p0 = 0; 
        else
            p0 = ((s1 - s1_and_true) / s1);
        end
        if (p0 == 0); 
            p0_eq = 0;
        else
            p0_eq = -1*(p0)*log2(p0); 
        end
        entropy_s1 = p1_eq + p0_eq; 
        %S(v=0) 
        if (~s0); 
            p1 = 0;
        else
            p1 = (s0_and_true / s0); 
        end
        if (p1 == 0); 
            p1_eq = 0; 
        else
            p1_eq = -1*(p1)*log2(p1); 
        end
        if (~s0);
            p0 = 0; 
        else
            p0 = ((s0 - s0_and_true) / s0);
        end
        if (p0 == 0); 
            p0_eq = 0; 
        else
            p0_eq = -1*(p0)*log2(p0);
        end
        entropy_s0 = p1_eq + p0_eq;
        gains(i) = currentEntropy - ((s1/numberExamples)*entropy_s1) - ((s0/numberExamples)*entropy_s0);
    end
end
% 选出最大增益
[~, bestAttribute] = max(gains);
% 设置相应值
tree.value = attributes{bestAttribute};
% 去活跃状态 
activeAttributes(bestAttribute) = 0; 
% 根据bestAttribute把数据进行分组 
examples_0= examples(examples(:,bestAttribute)==0,:); 
examples_1= examples(examples(:,bestAttribute)==1,:); 
 
% 当 value = false or 0, 左分支 
if (isempty(examples_0));
    leaf = struct('value', 'null', 'left', 'null', 'right', 'null');
    if (lastColumnSum >= numberExamples / 2); % for matrix examples 
        leaf.value = 'true'; 
    else
        leaf.value = 'false'; 
    end
    tree.left = leaf; 
else
    % 递归 
    tree.left = id3(examples_0, attributes, activeAttributes);
end
% 当 value = true or 1, 右分支 
if (isempty(examples_1));
    leaf = struct('value', 'null', 'left', 'null', 'right', 'null'); 
    if (lastColumnSum >= numberExamples / 2);
        leaf.value = 'true'; 
    else
        leaf.value = 'false'; 
    end
    tree.right = leaf; 
else
    % 递归 
    tree.right = id3(examples_1, attributes, activeAttributes);
end
% 返回 
return
end

你可能感兴趣的:(模式识别,matlab,机器学习,决策树,算法,matlab)