基于随机森林的分类算法的matlab简单实现

基于随机森林的分类算法的matlab简单实现

2023年6月22日发(作者:)

基于随机森林的分类算法的matlab简单实现说明关于熵、信息增益、信息增益⽐、基尼指数的计算不再写出决策树构建——使⽤最简单的ID3算法1.输⼊:训练数据集D,特征集A,阈值(后⾯会说明数据集的内容)2.输出:决策树T(1)若D中所有实例属于同⼀类Ck,则T为单结点树,并将Ck作为该结点的类标记,返回T;(2)若A是空集,则T为单结点树,并将D中实例数最⼤的类Ck作为该结点的类标记,返回T;(3)否则,计算A中各特征对D的信息增益,选择信息增益最⼤的特征Ag;(4)如果Ag的信息增益⼩于阈值,则置T为单结点树,并将D中实例数最⼤的类Ck作为该结点的类标记,返回T;(5)否则,对Ag的每⼀可能值ai,依Ag=ai将D分割为若⼲⾮空⼦集Di,将Di中实例数最⼤的类作为标记,构建⼦结点,由结点及其⼦结点构成树T,返回T;(6)对第i个⼦结点,以Di为训练集,以A-{Ag}为特征集,递归的调⽤步(1)到步(5),得到⼦树Ti,返回Ti。注:如果采⽤C4.5算法构建决策树,则只需要把ID3算法中的信息增益更换为信息增益⽐。数据集说明训练集1500个数据,测试集为500个数据。表⽰的是银⾏对是否同意贷款的分类预测。如图:第⼀列:1代表青年;2代表中年;3代表⽼年。第⼆列:2代表收⼊最⾼;1代表收⼊⼀般;0代表收⼊低。第三列:1代表有房;0代表没房第四列:1表⽰信⽤很好;2表⽰信⽤好;3表⽰信⽤⼀般。第五列:1代表男;0代表⼥。第六列:1表⽰城市;0表⽰农村。第七列:1表⽰同意贷款;2表⽰还需考虑;3表⽰不同意。随机森林的构建1.随机森林是集成学习的⼀种,它的基础单元是决策树。2.随机森林有两个随机,(假设训练集数⽬为N)⼀是训练决策树时随机有放回的抽取n(n

%% 样本测试 T=xlsread('loan_'); %TData=roundn(T,-1); TData=roundn(T(:,1:end-1),-1); len=length(TData(:,1));%测试样本的数⽬ type=zeros(len,1); for j=1:len %统计函数,对输⼊的测试向量进⾏投票,然后统计出选票最⾼的标签类型输出 [type(j)]=statistics(tn,rnode,rchild_value,rchild_node_num,TData(j,:)); end xlswrite('loan_',[T type]);%输出测试报告 gd = T(:,end); count = sum(type==gd); fprintf('共有%d个样本,判断正确的有%dn准确率为:百分之%sn',len,count,count/len*100);

2.决策树构建程序——ID3.m% 函数返回⼀棵决策树function [node,child_value,child_node_num]=ID3(S,Feature)%%% clear clear global node child_value child_node_num; global node child_value child_node_num %S=xlsread('');%%% DValue=S(:,1:6);

DValue=roundn(DValue,-1);%四舍五⼊保留⼀位⼩数 CN=S(:,7); CN=num2str(CN);%将标签设为string(字符串)型 for i=1:length(CN) A(i)=i; end [Feature,~]=sort(Feature); ClassPNum=Feature; CLASSPNUM=[1 2 3 4 5 6]; [CHA,~] = setdiff(CLASSPNUM,ClassPNum) ; DValue(:,CHA)=0;%把没⽤到的特征置0 m=0; [node,child_value,child_node_num]=TreeNode( DValue, CN, A, ClassPNum,m );

end% ⽣成树结点% DValue--前6列数据% A--参与划分的⾏号% CN--属性值的集合(第7列数据)% ClassPNum为划分的剩余属性编号% 当前node的⽗亲结点为node{m}function [node,child_value,child_node_num]=TreeNode( DValue, CN, A, ClassPNum,m) global node child_value child_node_num n=length(node); if m>0 %如果⽗亲结点存在,将本结点的序号存⼊⽗亲结点的⼦结点序号集中 k=length(child_node_num{m}); child_node_num{m}(k+1)=n+1;

end

% 1、样本为空,则树为空 if isempty(DValue) node{ n+1 }=[]; child_value{ n+1 }=[]; child_node_num{ n+1 }=[]; return; end

% 2、⽤于划分的剩余属性为空,选择多数元组所在的类作为结点 if isempty( ClassPNum )

node{ n+1 }=find_most( CN,A ); child_value{ n+1 }=[]; child_node_num{ n+1 }=[]; return; end

% 3、样本中所有数据都属于同⼀类,将此类作为结点 CNRowNum=CN_sta( CN, A); if length( find(CNRowNum==0) )>=2 %表⽰两类为空,则都属于⼀类 node{ n+1 }=CN(A(1)); child_value{ n+1 }=[]; child_node_num{ n+1 }=[]; return; % 4、样本中所有数据不属于同⼀类 else I=Exp( CN,A ); for i=1:length( ClassPNum ) %计算针对所有特征的信息增益

Entropy(i)=avg_entropy( DValue(:,ClassPNum(i)), A, CN); Gain(i)=I-Entropy(i); end % 4.1、各属性的信息增益均⼩于0,选择多数元组所在的类作为结点 if max(Gain)<=0 node{ n+1 }=find_most( CN,A ); child_value{ n+1 }=[]; child_node_num{ n+1 }=[]; return; % 4.2、在信息增益最⼤的属性上进⾏划分 else maxG=find( Gain==max(Gain) ); [PValue RowNum]=type_sta( DValue(:,ClassPNum(maxG(1))), A ); node{ n+1 }=ClassPNum(maxG(1)); child_value{ n+1 }=PValue; child_node_num{ n+1 }=[]; ClassPNum(maxG)=[]; % 删除ClassPNum(maxG)--已经进⾏划分的属性 for i=1:length(PValue) [node,child_value,child_node_num]=TreeNode( DValue, CN, RowNum{i}, ClassPNum,n+1 ); end return; end endend% A--参与划分的⾏号% DValue--数据集的前四列% 本函数⽤于统计参与划分的⾏⼤多数属于哪⼀个类function most_type=find_most( CN,A ) TypeName={'1','2','3'}; CNRowNum=CN_sta( CN, A); %1 2 3总数存在⾥⾯ n=max(CNRowNum);%求最⼤数量 maxn=find( CNRowNum==n );%maxn就是最多的类别对应的数 most_type=TypeName{maxn};%返回最多类别的字符串end% 计算属性P的熵% A--参与计算的⾏号,即计算的⾏范围% Attri--求属性Attri的熵% CN--类别属性值function entropy=avg_entropy( Attri, A, CN ) k=0;entropy=0; n=length(A); I=Exp( CN,A ); [PValue,RowNum]=type_sta( Attri, A ); for i=1:length( PValue ) CI=Exp( CN, RowNum{i}); entropy=entropy-length( RowNum{i} )/n*CI; endend% 计算样本分类的期望% A--参与计算的⾏号% Attri--求期望的属性值的集合function I=Exp(CN,A) CNRowNum=CN_sta( CN, A ); n=length(A); I=0; for i=1:3 if CNRowNum(i)>0 P(i)=CNRowNum(i)/n; I=I-P(i)*log2( P(i) ); end endend% 统计属性的取值及各取值对应的⾏号集合% A为参与统计的记录的⾏号集合% Attri为属性值的集合function [PValue,RowNum]=type_sta( Attri, A) k=1; PValue=Attri( A(1) ); RowNum{1}=A(1); for i=2:length(A) n1=find( PValue==Attri( A(i) ) ); if isempty(n1) k=k+1; PValue(k)=Attri( A(i) ); RowNum{k}=A(i); else n2=length( RowNum{n1} ); RowNum{n1}(n2+1)=A(i); end end end

end% 统计类别属性的取值及各取值对应的⾏号集合% A为参与统计的记录的⾏号集合% CN为类别属性值的集合function CNRowNum=CN_sta( CN, A) CNRowNum=[0 0 0]; TypeName={'1','2'}; for i=1:length( A ) if strcmp( CN(A(i)),TypeName{1}) CNRowNum(1)=CNRowNum(1)+1; elseif strcmp( CN(A(i)),TypeName{2} ) CNRowNum(2)=CNRowNum(2)+1; else CNRowNum(3)=CNRowNum(3)+1; end end

end3.统计及投票代码——ion [type] = statistics(tn,rnode,rchild_value,rchild_node_num,PValue) TypeName={'1','2','3'}; TypeNum=[0 0 0];

for i=1:tn %对测试向量进⾏投票,共有tn棵树 [type]=vote(rnode,rchild_value,rchild_node_num,PValue,i); if strcmp( type,TypeName{1}) TypeNum(1) = TypeNum(1) + 1; elseif strcmp( type,TypeName{2}) TypeNum(2) = TypeNum(2) + 1; else TypeNum(3) = TypeNum(3) + 1; end end maxn=find( TypeNum==max(TypeNum) ); type=str2num(TypeName{maxn(1)});end

function [type] = vote(rnode,rchild_value,rchild_node_num,PValue,j) n=1; %从树的根结点(即node{1})开始查找 k=0;

while ~isempty(rchild_node_num{j,1}{n})%不为空则进⼊循环 for i=1:length(rchild_value{j,1}{n}) if PValue(rnode{j,1}{n})==rchild_value{j,1}{n}(i) n=rchild_node_num{j,1}{n}(i); k=0; break; end

end

if i==length(rchild_value{j,1}{n}) % 若这个值在分类器中不存在,则取其最近的值进⾏分类 PValue(rnode{j,1}{n})=PValue(rnode{j,1}{n})+0.1*k; PValue=roundn(PValue,-1); end

k=(-1)^k*( abs(k)+1 );

end type=rnode{j,1}{n};

type=rnode{j,1}{n}; end分类结果1.决策树的结构可以从rnode、rchild_node_num、rchild_value三个数组中对照着读出来。2.分类结果为3.测试集的分类结果将保存到loan_⽂件中。代码缺点1.只适⽤于属性值是标签值也就是离散值的类型,如果训练集中含有连续属性样本,那么训练出的决策树将存在较严重的过拟合现象。2.未设置阈值,导致训练出的决策树结点数过多(可认为阈值为0,可以适当调⼤)3算法在部分情形下不太合适。⽂件

发布者:admin,转转请注明出处:http://www.yc00.com/news/1687384984a6095.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信