matlab 浅浅实现随机森林(Random forest)算法对高光谱图像数据进行分类,输出分类结果图和精度评价

利用随机森林(Random forest)算法对数据进行分类,输出分类结果图; 利用验证样本集计算出分类结果的混淆矩阵, 输出分类结果的整体分类精度 和每一类地 物的分类精度。
emmm不要对下面的内容报有太大的期待,要求使用随机森林算法,我尝试了,但失败了,就只是用matlab自己的函数勉强完成了要求。我的工作量大概在于找到这个函数[大哭]

%利用随机森林(Random forest)算法对数据进行分类
%第一种 利用ClassificationTree.fit构造决策树,总体正确率为85%
 %% 数据导入
load imgreal.mat %待分类数据img
load AVIRIS_Indiana_16class.mat %带标签的验证样本集trainall
[m,n,p]=size(img);
img1=reshape(img,m*n,p);
[m1,n1]=size(trainall);
img1_trainall=zeros(m1,p+2);%第1列为位置,2——p+1列为波段数据,第p+2列为标签
for i=1:m1
    img1_trainall(i,1)=trainall(i,1);
    img1_trainall(i,2:p+1)=img1(trainall(i,1),:);
    img1_trainall(i,p+2)=trainall(i,2);
end
%% 数据预处理
ti=1;si=1;
for i=1:16
    [ri,ci]=find(img1_trainall(:,p+2)==i);
    le=length(ri);
    alli=zeros(le,p+2);
    for j=1:le
        alli(j,:)=img1_trainall(ri(j),:);
    end
    mi=floor(le*0.9);%每类样本的前90%作为训练集,剩下的为验证集
    ni=le-mi;
    %训练集
    train_data(si:si+mi-1,:)=alli(1:mi,2:p+1);
    train_label(si:si+mi-1,:)=alli(1:mi,p+2);
    %测试集
    test_data(ti:ti+ni-1,:)=alli(mi+1:end,2:p+1);
    test_label(ti:ti+ni-1,:)=alli(mi+1:end,p+2);
    si=si+mi;ti=ti+ni;
end
mi=length(train_label);ni=length(test_label);
%% 随机森林
%第一种 利用ClassificationTree.fit构造决策树,总体正确率为0.727476755370311
%200棵决策树
shu=200;
correct_rate_tree=zeros(shu,1);%每棵决策树的准确率
test_label_tree=zeros(ni,shu);%记录测试集根据每棵树的分类结果
img1_tree=zeros(m*n,200);%记录待分类数据根据每棵树的分类结果
for i=1:shu
    tic
    a=randperm(floor(mi*0.85));%随机样本,为训练集数据的99%
    Train_Data = train_data(a(1:end),:);
    Train_Label =train_label(a(1:end),:);
%     leaf=randi([800 1500]);%随机minleaf 
    Tree= ClassificationTree.fit(Train_Data,Train_Label);
%     view(Tree);% 查看决策树视图
%     view(Tree,'mode','graph');
    %测试每棵决策树的结果
    testi= predict(Tree,test_data);
    test_label_tree(:,i)=testi;
    aa=testi-test_label;tt=0;
    for j=1:ni
        if aa(j)==0
            tt=tt+1;
        end
    end
    correct_rate_tree(i)=tt/ni;%每棵决策树的正确率
    %待分类数据进入决策树的结果
    img1_treei=predict(Tree,img1);
    img1_tree(:,i)=img1_treei;
    toc
    %程序运行可视化
    disp(['进度--',num2str(i/shu*100),'%']);
end
%% 测试集总体分类正确率
 test_label_label=zeros(ni,1);
for i=1:ni
    lea=zeros(16,1);
    for j=1:shu
        lea(test_label_tree(i,j))=lea(test_label_tree(i,j))+1;
    end
    ma=max(lea);
    test_label_label(i)=find(lea==ma,1);
end
ss= test_label_label-test_label;ttr=0;
for i=1:ni
    if ss(i)==0
        ttr=ttr+1;
    end
end
ttrt=ttr/ni;%分类正确率
%% 混淆矩阵
%第m行第n列a表示有a个实际归属第m类的实例被预测为第n类
hun_xiao=zeros(16,16);
for i=1:ni
   
        hun_xiao(test_label(i),test_label_label(i))=hun_xiao(test_label(i),test_label_label(i))+1;
    
end
%每一类的分类精度
%每一行的数据总数表示该类别的数据实例的数目
jingdu=zeros(16,1);
for i=1:16
    jingdu(i)=hun_xiao(i,i)/sum(hun_xiao(i,:));
end   
%% 投票法得出待分类数据真正类别
img1_label=zeros(m*n,1);
for i=1:m*n
    lea=zeros(16,1);
    for j=1:shu
        lea(img1_tree(i,j))=lea(img1_tree(i,j))+1;
    end
    ma=max(lea);
    img1_label(i)=find(lea==ma,1);
end
%存储数据
img1_label=reshape(img1_label,m,n);
xlswrite('img1_label_1.xls', img1_label);   
%可视化分类结果图
figure(1); imshow(img1_label,[]);
%% 随机森林
%第二种 利用TreeBagger构造随机森林 200棵决策总体正确率0.868868226995832
disp('TreeBagger');
tic
model=TreeBagger(200,train_data,train_label);
toc
[predict_labelS,scores]=predict(model,test_data);
% predict_label=zeros(ni,1);
% for i=1:ni
%     predict_label(i)=eval(predict_labelS(i));
% end
predict_label=str2num(char(predict_labelS));
sss=predict_label-test_label;
st=length(find(sss==0));
str=st/ni;%总体分类正确率;0.774774774774775
%% 混淆矩阵
hun_xiaoi=zeros(16,16);
for i=1:ni
    
        hun_xiaoi(test_label(i),predict_label(i))=hun_xiaoi(test_label(i),predict_label(i))+1;
 
end
%每一类的分类精度
%每一行的数据总数表示该类别的数据实例的数目
jingdui=zeros(16,1);
for i=1:16
    jingdui(i)=hun_xiaoi(i,i)/sum(hun_xiaoi(i,:));
end   
%% 分类结果
[img1_labeli,scores]=predict(model,img1);
img1_labeli=str2num(char(img1_labeli));%cell转double
img1_labeli=reshape(img1_labeli,m,n);
xlswrite('img1_label_2.xls', img1_labeli);   
%可视化分类结果图
figure(2); imshow(img1_label,[]);


这里就不上传数据了,大概说下数据是啥样子的吧,待分类数据img是一个145乘145乘220的数据,145是位置,220是光谱信息;带标签的验证样本集trainall是一个10366乘2的数据,第一列是img数据reshape后的位置,第二列是标签。至于写的两种方法ClassificationTree.fit和TreeBagger其实只要用第二种就可以了。(我留下是为了显示偶滴工作量[手动狗头],表示我干活了,就是没做出来[大哭])
还有一件事,感觉这种的数据输入,就是样本输入那块一定要注意是不是取的每一类样本的90%,这里trainall的数据是按照标签顺序排的且每类样本的数目相差有些多,一开始没注意还找了好久的问题(也可能只有我会犯这样的错误吧。[大哭double])

你可能感兴趣的:(matlab)