决策树ID3算法-matlab实现

ID3_decision_tree.m

%% 使用ID3决策树算法预测销量高低
clear ;

%% 数据预处理
disp('正在进行数据预处理...');
[matrix,attributes_label,attributes] =  id3_preprocess();

%% 构造ID3决策树,其中id3()为自定义函数
disp('数据预处理完成,正在进行构造树...');
tree = id3(matrix,attributes_label,attributes);

%% 打印并画决策树
[nodeids,nodevalues] = print_tree(tree);
tree_plot(nodeids,nodevalues);

disp('ID3算法构建决策树完成!');

id3_preprocess.m

function [ matrix,attributes,activeAttributes ] = id3_preprocess(  )
%% ID3算法数据预处理,把字符串转换为0,1编码

% 输出参数:
% matrix: 转换后的0,1矩阵;
% attributes: 属性和Label;
% activeAttributes : 属性向量,全1;

%% 读取数据
txt = {  '序号'    '天气'    '是否周末'    '是否有促销'    '销量'
        ''        '坏'      '是'          '是'            '高'  
        ''        '坏'      '是'          '是'            '高'  
        ''        '坏'      '是'          '是'            '高'  
        ''        '坏'      '否'          '是'            '高'  
        ''        '坏'      '是'          '是'            '高'  
        ''        '坏'      '否'          '是'            '高'  
        ''        '坏'      '是'          '否'            '高'  
        ''        '好'      '是'          '是'            '高'  
        ''        '好'      '是'          '否'            '高'  
        ''        '好'      '是'          '是'            '高'  
        ''        '好'      '是'          '是'            '高'  
        ''        '好'      '是'          '是'            '高'  
        ''        '好'      '是'          '是'            '高'  
        ''        '坏'      '是'          '是'            '低'  
        ''        '好'      '否'          '是'            '高'  
        ''        '好'      '否'          '是'            '高'  
        ''        '好'      '否'          '是'            '高'  
        ''        '好'      '否'          '是'            '高'  
        ''        '好'      '否'          '否'            '高'  
        ''        '坏'      '否'          '否'            '低'  
        ''        '坏'      '否'          '是'            '低'  
        ''        '坏'      '否'          '是'            '低'  
        ''        '坏'      '否'          '是'            '低'  
        ''        '坏'      '否'          '否'            '低'  
        ''        '坏'      '是'          '否'            '低'  
        ''        '好'      '否'          '是'            '低'  
        ''        '好'      '否'          '是'            '低'  
        ''        '坏'      '否'          '否'            '低'  
        ''        '坏'      '否'          '否'            '低'  
        ''        '好'      '否'          '否'            '低'  
        ''        '坏'      '是'          '否'            '低'  
        ''        '好'      '否'          '是'            '低'  
        ''        '好'      '否'          '否'            '低'  
        ''        '好'      '否'          '否'            '低'  }
attributes=txt(1,2:end);
activeAttributes = ones(1,length(attributes)-1);
data = txt(2:end,2:end);

%% 针对每列数据进行转换
[rows,cols] = size(data);
matrix = zeros(rows,cols);
for j=1:cols
    matrix(:,j) = cellfun(@trans2onezero,data(:,j));
end

end

function flag = trans2onezero(data)
    if strcmp(data,'坏') ||strcmp(data,'否')...
        ||strcmp(data,'低')
        flag =0;
        return ;
    end
    flag =1;
end

id3.m

function [ tree ] = id3( examples, attributes, activeAttributes )
%% ID3 算法 ,构建ID3决策树
    ...参考:https://github.com/gwheaton/ID3-Decision-Tree

% 输入参数:
% 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

参考:
http://blog.csdn.net/lfdanding/article/details/50753239

### 回答1: 基于ID3算法决策树分类器实现步骤如下: 1. 收集数据集,包括特征和分类标签。 2. 计算数据集的熵,用于衡量数据集的无序程度。 3. 针对每个特征,计算信息增益,选择信息增益最大的特征作为节点。 4. 将数据集按照选择的特征分成不同的子集,递归地构建决策树。 5. 当所有特征都被使用或者数据集已经完全分类时,停止递归。 6. 对新数据进行分类,根据决策树的规则进行分类。 需要注意的是,ID3算法有可能会出现过拟合的情况,因此可以采用剪枝等方法来提高决策树的泛化能力。 ### 回答2: ID3算法是一种经典的分类算法,可以通过计算经验熵来构建决策树。在实现基于ID3算法决策树分类器时,需要进行以下步骤。 1. 数据准备 首先需要准备好训练数据。数据应该包括若干个样本,每个样本包含若干个特征和一个类别标签。 2. 计算信息熵 使用信息熵来衡量数据的混乱程度。信息熵的公式为:$H = -\sum_{i=1}^k p_i \log_2 p_i$,其中$p_i$是某个类别在所有样本中出现的概率。 3. 计算信息增益 信息增益衡量某个特征对分类的贡献程度。信息增益的公式为:$Gain(A) = H(D) - \sum_{v=1}^V \frac{|D_v|}{|D|}H(D_v)$,其中$A$是某个特征,$D$是所有样本,$D_v$是某个特征取某个值时的样本。计算每个特征的信息增益,找到信息增益最大的特征。 4. 构建决策树 将信息增益最大的特征作为当前节点的分裂特征。将所有样本按照该特征的取值分成若干个子集。对每个子集递归调用上述步骤,直到无法分割或者达到某个条件时停止递归。 5. 预测 对于新的数据样本,根据决策树进行分类。从根节点开始,根据各个特征的取值不断向下遍历,直到到达叶子节点,叶子节点的类别即为预测结果。 以上是基于ID3算法实现决策树分类器的主要步骤。在实际应用中,还需要考虑如何处理缺失数据、如何剪枝优化等问题。此外,也可以使用其他决策树算法,如C4.5和CART等。 ### 回答3: —————————————分割线—————————————— 决策树是机器学习领域中重要的算法之一,它可以将数据集合分成可辨识别的不同类别,适用于二分类和多分类问题。而ID3算法是其中被广泛应用的一种决策树算法,它的主要核心是通过信息增益来分裂数据集合,得到高准确率。 实现基于ID3算法决策树分类器的主要思路可以概括为: 1. 选取一个最优的特征,将数据集划分为若干个子集,使得节点上的样本分类纯度更高。通常采用信息增益或信息增益比来选择最优特征。 2. 不断调用递归函数,从根节点开始构建决策树。 3. 对于每个子集,如果该集合中的样本已经被完全划分为同一类别,或者集合为空,则对应的节点标记为叶子节点,并标注该节点的分类类别。 4. 否则,继续选择最优特征,将该子集继续划分为更小的子集。 实现ID3算法的代码框架可以参考以下伪代码: function ID3(DataSet) if (DataSet.samples all belong to same class): return a leaf node with the class as label else if(DataSet.features are empty): return a leaf node with the majority class as label else bestFeat = choose the feature with maximum information gain tree = a new decision tree with root node as bestFeat divide DataSet into subsets according to bestFeat for each subset add a branch to tree with ID3(subset) end for end if return tree end function 其中,信息增益的计算方式为: $Gain(D, A) = Ent(D) - \sum_{v=1}^V \frac{|D^v|}{|D|} Ent(D^v)$ 其中,$D$为数据样本集合,$A$为要进行划分的特征集合,$D^v$为集合$D$划分后属于$A$中特征值为$v$的子集合,$Ent$为样本不确定性度量函数。 通过ID3算法实现决策树分类器在处理张量数据时存在着一些困难之处,这时,可以将高维张量数据投影到低维度空间中使用ID3算法进行分类。这样可以降低特征数量对分类器效果的影响,从而提高计算效率和精度。 在实际应用中,ID3算法的效果受到很多因素的影响,如数据集质量、特征选择和树的剪枝方法等。因此,在使用中需要对其进行不断的优化和改进,以获得更好的分类效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值