Matlab代码分析(核心代码)
根据上一节的伪代码,逐行分析!
decisionTree.m
function decisionTreeModel=decisionTree(data, label, propertyname, delta)
% data 训练数据 m*p 个数*维数
% label 训练数据的标签
% propertyname 属性值
% delta 阈值 信息增益或增益率小于阀值 停止树
% 返回 决策树模型
global Node; % 全局变量 所有函数都可以直接调用
Node = struct('level',-1,'fathernodename',[],'edgeproperty',[],'nodename'[]); % 创建一个结构体,level 为tree的层数
BuildTree(-1,'root','stem',data,label,propertyname,delta); %调用BulidTree函数
Node(1)=[];
model.Node = Node;
decisionTreeModel = model;
BulidTree.m
function BulidTree(fatherlever,fathernodename,edge,data,label,propertyname, delta)
global Node; %调用Node结构体
sonNode=struct('level',0,'fathernodename',[],'edgeproperty',[],'nodename'[]);
sonNode.level = fatherlevel+1;
sonNode.fathername = fathernodename;
sonNode.egdeproperty = edge;
if length(unique(label)==1)
sonNode.Nodename = label(1); %本句有bug 还没想通
Node = [Node sonNode];
return;
end %伪代码中: 如果examples都属于同一类,则返回单节点的树
if (length(propertyname)<1)
labelset = unique(label);
k = length(labelset);
labelNum = zeros(k,1);
for i=1:k
labelNum(i,1)=length(find(label==labelset(i)));
end
[~,labelIndex] = max(labelNum);
sonNode.Nodename = labelset(labelIndex);
Node = [Node, sonNode];
return;
end % 如果属性值为空,返回单节点树,标签为最常见的目标属性值
[sonIndex, BuildNode]=CalcuteNode(data,label,delta); %否则调用函数计算分类样例最好的属性
if BuildNode % 选取一个属性值(属性中分类能力最好的属性)(如A),作为根节点
dataRowIndex=setdiff(1:length(propertyName),sonIndex);
%setdiff函数:判断2个数组中不同元素 相当于 伪代码中 Attribute-{A}
sonNode.Nodename=propertyname{sonIndex};
Node = [Node,sonNode];
propertyname(sonIndex)=[];
sondata = data(:,sonIndex);
sonedge = unique(sondata);
for i =1:length(sonedge)
edgeDataIndex=find(sondata==sonedge(i));
BuildTree(sonNode.level, sonNode.NodeName,sonedge(i),data(edgeDataIndex,dataRowIndex),label(edgeDataIndex,:),propertyName,delta)
end
else % if examplesi为空 then 创建标号为最普遍分类的叶节点
labelset = unique(label);
k = length(labelset);
labelNum = zeros(k,1);
for i=1:k
labelNum(i,1)=length(find(label==labelset(i)));
end
[~,labelIndex] = max(labelNum);
sonNode.Nodename = labelset(labelIndex);
Node = [Node, sonNode];
return;
end
CalcuteNode.m
function [NodeIndex, BulidNode]=CalcuteNode(data,label,delta)
% NodeIndex 是分类最好的属性的索引值,
% BulidNode 是为了标记 在属性A下的子集是否为空?
largeEntropy = CEntropy(label); % 调用函数 计算样例集合的熵
%接下来计算信息增益
[m,n] =size(data);
BulidNode = true; % 标记
for i=1:n
Vi=data(:,i); % 属性A值的子集
itemlist = unique(Vi);
for j=1:length(itemlist)
itemlength = length(find(Vi==itemlist(j)));
Gain(i)= repmat(largeEntropy,1,n)-itemlength/m*CEntropy(label(find(Vi==itemlist(j))));
end % 求得信息增益Gain(S,A)
end
[maxGain,NodeIndex] = max(Gain); % 获得信息增益最大的值和索引
if maxGain% 标记为false 有何用处???
end
CEntropy.m
function result = CEntropy(propertylist)
%输入属性列表值
%返回 熵
result = 0;
totallength(length(propertylist)); %返回属性的总个数
itemlist = unique(propertylist); %属性分类
pnum = length(itemlist); %属性分类个数
for i=1:pnum:
itemlenght = length(find(propertylist==itemlist(i)));
temp = itemlength/totallength; % 计算某一类在总数中的比例
result = result-temp*log2(temp); % 计算熵
end
决策树 一个小例子:matlab
链接:http://pan.baidu.com/s/1bpGE62V 密码:q1jl