决策树matlab实现二分类或者多分类

版权声明:本文为博主原创文章,未经博主允许不得转载。可联系邮箱[email protected] https://blog.csdn.net/Justin_bibo/article/details/84143307

代码解释

maketree函数递归建立树
tree=struct(‘isnode’,1,‘a’,0.0,‘mark’,0.0,‘child’,{}) 所有分支递归的存在child{}中
函数gan(D)计算D的信息率
代码可以自动适应不同的分类标签和类别个数

代码

function tree=maketree(D,a) 
tree=struct('isnode',1,'a',0.0,'mark',0.0,'child',{});%isnode判断是否是分支还是叶子,a表示节点属性,若节点是叶子,a表示分类结果,child是孩子
tree(1).a=1;%给tree分配一个确切的内存
if length(unique(D(:,end)))==1%D中样本属于同一类别
    tree.isnode=0;%把tree标记为树叶
    tree.a=D(1,end);%把tree的类别标记为D的类别
    return
end

if sum(a)==0 ||length(D)==0 %属性划分完毕
    tree.isnode=0;%把tree标记为树叶
    tree.a=mode(D(:,end));%把tree的类别标记为D出现最多的类别
    return
end
for i=1:length(a)
    if a(i)==1
        if length(unique(D(:,i)))==1
            tree.isnode=0;%把tree标记为树叶
            tree.a=mode(D(:,end));%把tree的类别标记为D出现最多的类别
            return
        end
    end
end
gain=zeros(length(a),1); %保存每个属性的信息增益
best=zeros(length(a),1); %保存每个属性的最佳划分

for i=1:length(a)
    if a(i)==1
        t=D(:,i);
        t=sort(t);
    
        gain1=zeros(length(t)-1,1);
        for j=1:length(t)-1%二分划分
            ta=(t(j)+t(j+1))/2;
         
            Df=D(D(:,i)<=ta,:);
            Dz=D(D(:,i)>ta,:);
            gain1(j)=ent(D)-(ent(Df)*length(Df(:,end))/length(D(:,end))+ent(Dz)*length(Dz(:,end))/length(D(:,end)));
        end
     
        [gain(i),j]=max(gain1);
        ta=(t(j)+t(j+1))/2;
        best(i)=ta; 
    end
end
[g,m]=max(gain);%选择信息增益最大的属性
D1=D(D(:,m)<=best(m),:);
D2=D(D(:,m)>best(m),:);
a(m)=0;

tree.a=best(m); %建立分支
tree.mark=m;
% disp('****************************')
% tree.a
% tree.mark
tree.isnode=1;
tree.child(1)=maketree(D1,a);
tree.child(2)=maketree(D2,a);

end
function f=ent(D)%计算信息商
l=unique(D(:,end));
if length(D)==0
    f=0;
    return
end
f=0;
t=zeros(length(l),1);
for i=1:length(D(:,end))
    for j=1:length(l)
        if D(i,end)==l(j)
            t(j)=t(j)+1;
            break;
        end
    end
end
n=length(D(:,end));
for i=1:length(l)
    f=f+(t(i)/n)*log2(t(i)/n);
end
f=-f;
end

测试结果

在训练集测试结果精度是0.91
该测试函数是测试随机森林的函数,但不影响测试决策树。

function randomforest()
clc
clear all
T=1;%bagging采样的次数
M = importdata('D:\毕业设计\数据集1\australian.txt');  %读取数据
[sm,sn]=size(M);
% for i=1:sm             %归一化
%     mins=min(M(i,1:sn-1));
%     maxs=max(M(i,1:sn-1));
%     for j=1:sn-1
%         M(i,j)=2*(M(i,j)-mins)/(maxs-mins)-1;
%     end
% end
indices=crossvalind('Kfold',M(1:sm,sn),10); %十折交叉,划分训练集和测试集
testindices=(indices==1); %测试集索引
trainindices=~testindices;%训练集索引
trainset=M(trainindices,:); %获取训练集
testset=M(testindices,:);%获取测试集
[testm,~]=size(testset);
[trainm,trainn]=size(trainset);

predict=zeros(trainm,T);
for t=1:T %开始bagging采样
    D=[];%训练集
    for i=1:trainm%采样
        k=randperm(trainm,1);
        D=[D;trainset(k,:)];
    end
    [~,sn]=size(D);
    a=ones(sn-1,1);%属性集合a,1代表该属性未被划分
  
    tree=maketree(D,a);%递归构造简单决策树
    
    for i=1:trainm
        treet=tree;
        while 1
           
            if treet.isnode==0
                predict(i,T)=treet.a;
                break;
            end
            if trainset(i,treet.mark)<=treet.a
                treet=treet.child(1);
            else
                treet=treet.child(2);
            end
          
        end
    end
    
end
acc=0;
for i=1:trainm
    if trainset(i,end)==mode(predict(i,:))
        acc=acc+1;
    end
end
acc=acc/trainm



 
end

猜你喜欢

转载自blog.csdn.net/Justin_bibo/article/details/84143307