%另一个文件中测试代码 p = node([1;2], [1,2,3;2,1,4;2,3,1;3,2,1;2,3,4;4,2,1;3,2,1], 0.6)
classdef node
properties
%该节点的y标记
y
%该节点所选择的特征X在D中的下标
x
%该节点的特征集合,其元素为该特征在数据集中的下标
xs
%该节点的数据集NxM,M=(x特征数量+1列y值)
D
%1表示叶节点,0表示非叶
flag
%sigma为该节点信息增益或者信息增益比的阈值,当该节点D中所有X特征的信息增益(比)
%都比该阈值小,则该节点仍为叶节点
sigma
end
methods
function obj = node(xs,D,sigma)
obj.xs = xs;
obj.D = D;
obj.sigma = sigma;
%获取数据集中的y列
dy = D(:, size(D, 2));
%计算xs中所有特征的信息增益,xs为特征在D矩阵中的下标
%计算HD
hd = node.HD(dy);
%计算HD|A
hd_a = zeros(size(xs, 1), 1);
for i=1:1:size(xs, 1)
hd_a(i, 1) = node.HD_A(D, xs(i, 1));
end
%作差得到信息增益
gd_a = -1 * hd_a + hd;
%c4.5算法获取信息增益比利用HAD可以获取D关于每个特征的经验熵
%node.HAD(D, 1); 在数据集合中 下标为1的特征X D关于X的经验熵
%获取最大信息增益,及其对应特征的下标
[gmax, gpos] = max(gd_a);
%获取数据集中频率最高的y值
uy = unique(dy);
[yMaxTimes, ypos] = max(hist(dy, size(uy, 1)));
yMax = uy(1, ypos);
if((dy / dy(1,1)) == ones(size(D, 1), 1))
%y的值都相同,即属于同一类,则为叶节点
obj.flag = 1;
obj.y = dy(1, 1);
elseif(isempty(xs))
%可选的特征为空,则不得不为叶节点
obj.flag = 1;
obj.y = yMax;
elseif(gmax < sigma)
%当最大特征的信息增益小于阈值,则为叶节点
obj.flag = 1;
obj.y = yMax
else
%记录该节点所选的特征
%获取特征下标,xs的排列与gd_a的排列是相同的
x = xs(gpos, 1);
%将x特征从xs中除去
xs(gpos, :) = [];
obj.flag = 0;
end
end
function f = isLeaf(obj)
f = obj.flag;
end
function xs = getXsLeft(obj)
xs = obj.xs;
end
function setY(obj, y)
obj.y = y;
end
end
methods(Static)
%计算数据集D的经验熵
function hd = HD(y)
%获取不同值出现频率/总数,依赖于hist以及unique函数按数升序展示频率
py = hist(y, size(unique(y), 1)) / size(y, 1);
%通过行列乘法求熵
hd = -1 * py * transpose(log2(py));
end
%计算特征A给定的条件下D的经验条件熵
function hd_a = HD_A(D, XIndice)
%提取所需考量的第XIndice个特征值在数据D中的值
X = D(:, XIndice);
%升序X的所有取值
xValue = unique(X);
%由于经验条件熵为 特征值出现概率*特征值出现时的经验熵 的累加,HDi用于存储
%该特征值去 unique[i]个值的经验熵
HDi = zeros(size(unique(X), 1), 1);
for i=1:1:size(xValue, 1)
Dyi = D(find(X(:, 1) == xValue(i, 1)), size(D, 2));
HDi(i, 1) = node.HD(Dyi);
end
%计算特征取不同值的概率,同样升序
pxi = hist(X, size(xValue, 1)) / size(X, 1);
%实现累计加
hd_a = pxi * HDi;
end
%计算数据集D关于特征A的熵
function had = HAD(D, XIndice)
had = node.HD(D(:, XIndice));
end
end
end
|
|