csdn上python代码感觉都写的挺复杂,要用各类函数,但没有体现ID3算法原理,matlab语言也没有看到免费的相关代码,决定手敲一份。比预期艰难,最后决策图没有用二叉树绘制,但也能看。
先将代码免费分享,仅供参考。
main.c函数如下:
%利用ID3算法实现校门口小贩的收益判断决策树 可推广使用
clc;clear;
load('datau') %原始数据转化成0、1矩阵
[m,n]=size(datau);
place=zeros(1,n-1);
yon=zeros(2,n-1);
for find_node=1:n-1
[datau,place,yon,contin]=cal_e(datau,place,yon); %找到每一个根节点和属性取值
if contin==2 %找到叶子结点
break;
end
end
name={'天气','学生放假','促销','收入低','收入高'}; %绘制决策图
for creat_graph=1:n-1 %寻找根节点、目标节点、权重
array=creat_graph*2-1;
s(array)=name(place(creat_graph));
s(array+1)=name(place(creat_graph));
t(array)=name(yon(2,creat_graph)+n);
if creat_graph==n-1
t(array+1)=name(length(name)-yon(2,creat_graph));
else
t(array+1)=name(place(creat_graph+1));
end
weight(array)=yon(1,creat_graph);
weight(array+1)=1-yon(1,creat_graph);
end
G = digraph(s,t,weight,name);
plot(G, 'EdgeLabel', G.Edges.Weight, 'linewidth', 2)
计算总的信息熵函数如下:
function I=cal_I(data) %计算总的信息熵 data为决策列向量
len=length(data);
a=sum(data==1)/len;
b=sum(data==0)/len;
I=-a*log2(a)-b*log2(b);
end
根据ID3原理计算出每个根节点:
function [data,pla,yon,contin] =cal_e(data,pla,yon) %data为总数据 pla存储每个根节点 yon存储节点走向 是/否
I_ALL=cal_I(data(:,end)); %计算总的信息熵
[m,n]=size(data);
for i=1:n-1 %计算每个因素增益值
w=[0,0];
s=[0,0];
for j =1:m
for k=2:3
kk=k-2;
if data(j,i)==kk && data(j,end)==kk
w(kk+1)=w(kk+1)+1;
end
if data(j,i)==kk && data(j,end)==(~kk)
s(kk+1)=s(kk+1)+1;
end
end
for p=1:2
k=w(p)/(w(p)+s(p));
if k==1 || k==0
iab(p)=0;
else
iab(p)=-k*log2(k)-(1-k)*log2(1-k);
end
end
E(i)=iab(1)*(w(1)+s(1))/m+iab(2)*(w(2)+s(2))/m;
Gain(i)=I_ALL-E(i);
end
end
i=1;
while(pla(i)~=0)
i=i+1;
end
[~,pla(i)]=max(Gain); %找到最大信息增益值因素位置
place=pla(i);
num=0;
w=0;s=0;
for j=1:m
if (data(j,place)==1)
w=w+data(j,end);
num=num+1;
end
if (data(j,place)==0)
s=s+data(j,end);
end
end
contin=0; %是否结束寻找下一个根节点
if w/num==1 % 找到叶子结点走向
yon(1,i)=1;
yon(2,i)=1;
contin=contin+1;
elseif w/num==0
yon(1,i)=1;
yon(2,i)=0;
contin=contin+1;
end
if s/(m-num)==1
yon(1,i)=0;
yon(2,i)=1;
contin=contin+1;
elseif s/(m-num)==0
yon(1,i)=0;
yon(2,i)=0;
contin=contin+1;
end
if contin==1
target=yon(1,i);
ar=1;
for j=1:m
if data(j,place)==target
k(ar)=j;
ar=ar+1;
end
end
end
data(k,:)=[]; %更新数据
使用举例;
原始数据如下
将其转化为原始数据存储格式如下(datau)
最后输出结果:
制作不易,如有帮助,欢迎点赞收藏。