利用随机森林(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])