当前位置:   article > 正文

C4.5决策树算法(MATLAB完整代码)_决策树c4.5matlab

决策树c4.5matlab

C4.5决策树算法是一种常见的机器学习方法,由Ross Quinlan在1993年提出。它是ID3算法的扩展和改进,主要用于分类任务,可以处理连续值和离散值属性的数据。

C4.5决策树算法的基本思路是通过特征选择的方式,将具有最佳分类能力的特征作为决策树的根节点。然后,根据这个特征的取值将数据集划分为多个子集,对每个子集递归地生成子树。在生成过程中,C4.5算法使用了信息增益比作为特征选择的准则,有效地解决了ID3算法偏向于选择取值多的特征的问题。

在处理连续值属性时,C4.5算法首先对属性值进行排序,然后在每两个相邻值的中间点设置一个可能的划分点,计算以该点为划分点的信息增益比,选择信息增益比最大的点作为划分点。在处理缺失值时,C4.5算法引入了一种概率权重的方法,即根据属性值缺失的比例,给每个可能的划分赋予一个概率权重。

C4.5决策树算法还包括了一种剪枝策略,可以有效地处理过拟合问题。具体来说,C4.5算法在生成决策树的同时,对每个节点计算一个错误率,然后从叶节点开始,逐步向上比较替换前后的错误率,如果替换后的错误率降低或不变,则进行剪枝。

总体来看,C4.5决策树算法是一种强大且灵活的机器学习方法。其优势在于可以处理各种类型的数据,包括连续值和离散值属性,可以处理缺失值,同时还具有较好的分类性能。此外,C4.5生成的决策树易于理解和解释,对于理解数据的内在结构和特征有很大的帮助。

主要代码如下:

%% 主函数
clear all;close all;clc;
%% ----------------------数据处理部分开始-------------------------------
% 读取部分
filename='train.csv';
traindata=readtraindata(filename);
traindata.targets

filename='validate.csv';
validatedata=readvalidatedata(filename,traindata);
validatedata.Data;
validatedata.targets;

filename='test.csv';
testdata=readtestdata(filename,traindata);
testdata.Data;
%% ----------------------数据处理部分结束-------------------------------
X=traindata.Data;
a=traindata.targets;
Y=cell(length(a),1);
for i=1:length(a)
    Y{i,1}=num2str(a(i));
end

b=validatedata.targets;
Yt=cell(length(b),1);
for i=1:length(b)
    Yt{i,1}=num2str(b(i));
end

T1=classregtree(X,Y);
view(T1)
Xt=validatedata.Data;

E=test(T1,'test',Xt,Yt)

T2 = prune(T1,'criterion','error');

Y1=eval(T1,validatedata.Data);%预测
Yt;
ss1=str2double(Y1);
ss2=str2double(Yt);
E2=1-sum(abs(ss1-ss2))/length(ss2)

function Vdata=readvalidatedata(filename,data)
% 输入数据
%filename=文件名
%输出数据
%data是输出数据
%% ------------------------------------数据处理部分开始---------------------------------------------------
% 读取部分
dim=data.dim;
DataTypes=data.DataTypes;%1表示离散,0表示连续
fid = fopen(filename);
dcells = textscan(fid, '%s');
fclose(fid);
A=dcells{1};
s1=A{1};
str=strrep(s1,',',' ');
str2=textscan(str, '%s %s %s %s %s %s %s %s %s %s %s %s %s');
[k11,k12]=size(A);
data01=cell(k11-1,dim);
wait_hand = waitbar(0,'正在读取数据,请等待……', 'tag', 'TMWWaitbar');
for i=2:k11
    waitbar(i/k11,wait_hand);%每循环一次更新一次进步条
    s1=A{i};
    str=strrep(s1,',',' ');
    str2=textscan(str, '%s %s %s %s %s %s %s %s %s %s %s %s %s');
    for j=1:dim
        data01{i-1,j}=str2{j}{1};
    end
end
delete(wait_hand);%执行完后删除该进度条
datatemp3=data01(:,dim);%记录分类数据
Vdata.targets=str2double(datatemp3);
%% --------------以上ok----------------------------------------
%% 求离散类别的个数
[k21,k22]=size(DataTypes);
[k31,k32]=size(data01);
data02=data01;%初始化处理后的数据集
%%
%进度条
wait_hand = waitbar(0,'正在处理数据,请等待……', 'tag', 'TMWWaitbar');
for i=1:k22
    waitbar(i/k22,wait_hand);%每循环一次更新一次进步条
    if (DataTypes(i))%如果该列是离散的,求类个数
        datatemp1=data01(:,i);
        %% ---------------------处理离散不完整数据开始---------------
        datatemp3=data01(:,dim);%记录分类数据
        ind1=strcmp(datatemp1,'?');%找原始的一列数据是有'?'元素的位置
        [ind2,v2]=find(ind1==1);
        if ~isempty(ind2)
            a1=length(ind2);%数据长度
            for j=1:a1
                type1=data01{ind2(j),dim};%求是哪个分类
                ind3=strcmp(datatemp3,type1);%同一分类的数据在那些位置
                [ind4,v2]=find(ind3==1);%找出所在的行标,由于datatemp3是列向量,所以ind3是列向量,因此ind4要在第一个输出参数
                if ~isempty(ind4)
                    temp1=data01(ind4,i);
                    temp2=unique(temp1);%剔除相同元素
                    ind10=strcmp(temp2,'?');%找是否有'?'元素
                    if sum(ind10)==1%有'?'元素
                        [ind12,v1]=find(ind10==1);
                        temp2(ind12)=[];
                    end
                    a3=length(temp2);
                    ElementCount=zeros(a3,1);
                    for t2=1:a3%统计元素概率
                        index5=strcmp(temp1,temp2(t2));
                        [index6,v2]=find(index5==1);
                        ElementCount(t2,1)=length(index6);%第t2个元素有几个,注意对应的是temp2这个集
                    end
                    P=ElementCount./sum(ElementCount);%求概率
                    num=1;%轮盘赌次数设定
                    Select01=Roulette(P,num);
                    data02{ind2(j),i}=temp2{Select01};%把问号改成选择的结果
                end
            end
        end
        %% ---------------------处理离散不完整数据结束---------------
    else%如果该列是连续的,求最大最小值
        %% -----------处理连续数据开始---------------
        datatemp3=data01(:,dim);%记录分类数据
        datatemp1=data01(:,i);
        ind1=strcmp(datatemp1,'?');%找原始的一列数据是有'?'元素的位置
        [ind2,v2]=find(ind1==1);
        if ~isempty(ind2)
            a1=length(ind2);%数据长度
            for j=1:a1
                type1=data01{ind2(j),dim};%求是哪个分类
                ind3=strcmp(datatemp3,type1);%同一分类的数据在那些位置
                [ind4,v2]=find(ind3==1);%找出所在的行标,由于datatemp3是列向量,所以ind3是列向量,因此ind4要在第一个输出参数
                if ~isempty(ind4)
                    temp1=data01(ind4,i);
                    temp2=unique(temp1);%剔除相同元素
                    ind10=strcmp(temp2,'?');%找是否有'?'元素
                    if sum(ind10)==1%有'?'元素
                        [ind12,v1]=find(ind10==1);
                        temp2(ind12)=[];%删除问号
                    end
                    temp3=str2double(temp2);
                    data02{ind2(j),i}=num2str(mean(temp3));%把问号改成选择的结果
                end
            end
        end
        %% -----------处理连续数据结束---------------
    end
    
end
delete(wait_hand);%执行完后删除该进度条
% s08=data02{28,5}
% s06=data02{6,12}
% s20=data02{20,12}
% s81=data02{81,12}
%% ----------------进一步的数据处理,全部数字化开始------------------
wait_hand = waitbar(0,'正在数字化处理数据,请等待……', 'tag', 'TMWWaitbar');
data03=zeros(k11-1,dim-1);
for i=1:k22
    waitbar(i/k22,wait_hand);%每循环一次更新一次进步条
    if (DataTypes(i))%如果该列是离散的
        datatemp2=data.Types(i).Set;%记录类型集
        for j=1:k31
            index1=strcmp(datatemp2,data02{j,i});%对应哪一个
            [index2,v2]=find(index1==1);
            data03(j,i)=index2;
        end
    else%连续的处理方法
        for j=1:k31
            data03(j,i)=str2double(data02{j,i});
        end
    end
end
delete(wait_hand);%执行完后删除该进度条
%% 记录数据
Vdata.Data=data03;
%% ----------------进一步的数据处理,全部数字化结束------------------

%% ----------------------数据处理部分结束------------------------------------------------------

程序结果如下:

ans =

     0

     0

     1

     0

     1

     0

     1

     1

     1

     1

     1

     0

     0

     0

     0

     1

     0

     0

     0

     0

     1

     0

     1

     0

     0

     0

     0

     0

     0

     0

     0

     0

     0

     1

     0

     0

     1

     1

     0

     0

     0

     1

     0

     1

     1

     1

     1

     0

     0

     0

     1

     0

     1

     1

     0

     0

     1

     0

     0

     1

     0

     0

     0

     1

     1

     0

     1

     1

     1

     0

     0

     0

     0

     0

     1

     1

     0

     1

     1

     1

     1

     0

     0

     0

     1

     1

     1

     1

     0

     0

     0

     0

     0

     1

     0

     0

     1

     0

     0

     0

     0

     0

     0

     1

     1

     0

     0

     0

     0

     0

     1

     1

     0

     1

     0

     0

     1

     1

     1

     1

     0

     0

     0

     0

     0

     1

     1

     1

     0

     0

     1

E =

    0.4600

    0.4600

    0.4600

    0.4600

    0.4500

    0.4700

    0.4900

    0.4400

E2 =

    0.5400

>>

完整代码见: https://download.csdn.net/download/corn1949/88792084

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号