MATLAB实现随机森林(RF)回归与自变量影响程度分析
本文介绍基于MATLAB,利用随机森林(RF)算法实现回归预测,以及自变量重要性排序的操作。
本文分为两部分,首先是对代码进行分段、详细讲解,方便大家理解;随后是完整代码,方便大家自行尝试。另外,关于基于MATLAB的神经网络(ANN)代码与详细解释,我们将在后期博客中介绍。
1 分解代码
1.1 最优叶子节点数与树数确定
首先,我们需要对RF对应的叶子节点数与树的数量加以择优选取。
%% Number of Leaves and Trees Optimization
for RFOptimizationNum=1:5
RFLeaf=[5,10,20,50,100,200,500];
col='rgbcmyk';
figure('Name','RF Leaves and Trees');
for i=1:length(RFLeaf)
RFModel=TreeBagger(2000,Input,Output,'Method','R','OOBPrediction','On','MinLeafSize',RFLeaf(i));
plot(oobError(RFModel),col(i));
hold on
end
xlabel('Number of Grown Trees');
ylabel('Mean Squared Error') ;
LeafTreelgd=legend({'5' '10' '20' '50' '100' '200' '500'},'Location','NorthEast');
title(LeafTreelgd,'Number of Leaves');
hold off;
disp(RFOptimizationNum);
end
其中,RFOptimizationNum是为了多次循环,防止最优结果受到随机干扰;大家如果不需要,可以将这句话删除。
RFLeaf定义初始的叶子节点个数,我这里设置了从5到500,也就是从5到500这个范围内找到最优叶子节点个数。
Input与Output分别是我的输入(自变量)与输出(因变量),大家自己设置即可。
运行后得到下图。

首先,我们看到MSE最低的线是红色的,也就是5左右的叶子节点数比较合适;再看各个线段大概到100左右就不再下降,那么树的个数就是100比较合适。
1.2 循环准备
由于机器学习往往需要多次执行,我们就在此先定义循环。
%% Cycle Preparation
RFScheduleBar=waitbar(0,'Random Forest is Solving...');
RFRMSEMatrix=[];
RFrAllMatrix=[];
RFRunNumSet=10;
for RFCycleRun=1:RFRunNumSet
其中,RFRMSEMatrix与RFrAllMatrix分别用来存放每一次运行的RMSE、r结果,RFRunNumSet是循环次数,也就是RF运行的次数。
1.3 数据划分
接下来,我们需要将数据划分为训练集与测试集。这里要注意:RF其实一般并不需要划分训练集与测试集,因为其可以采用袋外误差(Out of Bag Error,OOB Error)来衡量自身的性能。但是因为我是做了多种机器学习方法的对比,需要固定训练集与测试集,因此就还进行了数据划分的步骤。
%% Training Set and Test Set Division
RandomNumber=(randperm(length(Output),floor(length(Output)*0.2)))';
TrainYield=Output;
TestYield=zeros(length(RandomNumber),1);
TrainVARI=Input;
TestVARI=zeros(length(RandomNumber),size(TrainVARI,2));
for i=1:length(RandomNumber)
m=RandomNumber(i,1);
TestYield(i,1)=TrainYield(m,1);
TestVARI(i,:)=TrainVARI(m,:);
TrainYield(m,1)=0;
TrainVARI(m,:)=0;
end
TrainYield(all(TrainYield==0,2),:)=[];
TrainVARI(all(TrainVARI==0,2),:)=[];
其中,TrainYield是训练集的因变量,TrainVARI是训练集的自变量;TestYield是测试集的因变量,TestVARI是测试集的自变量。
因为我这里是做估产回归的,因此变量名称就带上了Yield,大家理解即可。
1.4 随机森林实现
这部分代码其实比较简单。
%% RF
nTree=100;
nLeaf=5;
RFModel=TreeBagger(nTree,TrainVARI,TrainYield,...
'Method','regression','OOBPredictorImportance','on', 'MinLeafSize',nLeaf);
[RFPredictYield,RFPredictConfidenceInterval]=predict(RFModel,TestVARI);
其中,nTree、nLeaf就是本文1.1部分中我们确定的最优树个数与最优叶子节点个数,RFModel就是我们所训练的模型,RFPredictYield是预测结果,RFPredictConfidenceInterval是预测结果的置信区间。
1.5 精度衡量
在这里,我们用RMSE与r衡量模型精度。
%% Accuracy of RF
RFRMSE=sqrt(sum(sum((RFPredictYield-TestYield).^2))/size(TestYield,1));
RFrMatrix=corrcoef(RFPredictYield,TestYield);
RFr=RFrMatrix(1,2);
RFRMSEMatrix=[RFRMSEMatrix,RFRMSE];
RFrAllMatrix=[RFrAllMatrix,RFr];
if RFRMSE<400
disp(RFRMSE);
break;
end
disp(RFCycleRun);
str=['Random Forest is Solving...',num2str(100*RFCycleRun/RFRunNumSet),'%'];
waitbar(RFCycleRun/RFRunNumSet,RFScheduleBar,str);
end
close(RFScheduleBar);
在这里,我定义了当RMSE满足<400这个条件时,模型将自动停止;否则将一直执行到本文1.2部分中我们指定的次数。其中,模型每一次运行都会将RMSE与r结果记录到对应的矩阵中。
1.6 变量重要程度排序
接下来,我们结合RF算法的一个功能,对所有的输入变量进行分析,去获取每一个自变量对因变量的解释程度。
%% Variable Importance Contrast
VariableImportanceX={};
XNum=1;
% for TifFileNum=1:length(TifFileNames)
% if ~(strcmp(TifFileNames(TifFileNum).name(4:end-4),'MaizeArea') | ...
% strcmp(TifFileNames(TifFileNum).name(4:end-4),'MaizeYield'))
% eval(['VariableImportanceX{1,XNum}=''',TifFileNames(TifFileNum).name(4:end-4),''';']);
% XNum=XNum+1;
% end
% end
for i=1:size(Input,2)
eval(['VariableImportanceX{1,XNum}=''',i,''';']);
XNum=XNum+1;
end
figure('Name','Variable Importance Contrast');
VariableImportanceX=categorical(VariableImportanceX);
bar(VariableImportanceX,RFModel.OOBPermutedPredictorDeltaError)
xtickangle(45);
set(gca, 'XDir','normal')
xlabel('Factor');
ylabel('Importance');
这里代码就不再具体解释了,大家会得到一幅图,是每一个自变量对因变量的重要程度,数值越大,重要性越大。
其中,我注释掉的这段是依据我当时的数据情况来的,大家就不用了。
更新:这里请大家注意,上述代码中我注释掉的内容,是依据每一幅图像的名称对重要性排序的X轴(也就是VariableImportanceX)加以注释(我当时做的是依据遥感图像估产,因此每一个输入变量的名称其实就是对应的图像的名称),所以使得得到的变量重要性柱状图的X轴会显示每一个变量的名称。大家用自己的数据来跑的时候,可以自己设置一个变量名称的字段元胞然后放到VariableImportanceX,然后开始figure绘图;如果在输入数据的特征个数(也就是列数)比较少的时候,也可以用我上述代码中间的这个for i=1:size(Input,2)循环——这是一个偷懒的办法,也就是将重要性排序图的X轴中每一个变量的名称显示为一个正方形,如下图红色圈内。这里比较复杂,因此如果大家这一部分没有搞明白或者是一直报错,在本文下方直接留言就好~

1.7 保存模型
接下来,就可以将合适的模型保存。
%% RF Model Storage
RFModelSavePath='G:\CropYield\02_CodeAndMap\00_SavedModel\';
save(sprintf('%sRF0410.mat',RFModelSavePath),'nLeaf','nTree',...
'RandomNumber','RFModel','RFPredictConfidenceInterval','RFPredictYield','RFr','RFRMSE',...
'TestVARI','TestYield','TrainVARI','TrainYield');
其中,RFModelSavePath是保存路径,save后的内容是需要保存的变量名称。
2 完整代码
完整代码如下:
%% Number of Leaves and Trees Optimization
for RFOptimizationNum=1:5
RFLeaf=[5,10,20,50,100,200,500];
col='rgbcmyk';
figure('Name','RF Leaves and Trees');
for i=1:length(RFLeaf)
RFModel=TreeBagger(2000,Input,Output,'Method','R','OOBPrediction','On','MinLeafSize',RFLeaf(i));
plot(oobError(RFModel),col(i));
hold on
end
xlabel('Number of Grown Trees');
ylabel('Mean Squared Error') ;
LeafTreelgd=legend({'5' '10' '20' '50' '100' '200' '500'},'Location','NorthEast');
title(LeafTreelgd,'Number of Leaves');
hold off;
disp(RFOptimizationNum);
end
%% Notification
% Set breakpoints here.
%% Cycle Preparation
RFScheduleBar=waitbar(0,'Random Forest is Solving...');
RFRMSEMatrix=[];
RFrAllMatrix=[];
RFRunNumSet=50000;
for RFCycleRun=1:RFRunNumSet
%% Training Set and Test Set Division
RandomNumber=(randperm(length(Output),floor(length(Output)*0.2)))';
TrainYield=Output;
TestYield=zeros(length(RandomNumber),1);
TrainVARI=Input;
TestVARI=zeros(length(RandomNumber),size(TrainVARI,2));
for i=1:length(RandomNumber)
m=RandomNumber(i,1);
TestYield(i,1)=TrainYield(m,1);
TestVARI(i,:)=TrainVARI(m,:);
TrainYield(m,1)=0;
TrainVARI(m,:)=0;
end
TrainYield(all(TrainYield==0,2),:)=[];
TrainVARI(all(TrainVARI==0,2),:)=[];
%% RF
nTree=100;
nLeaf=5;
RFModel=TreeBagger(nTree,TrainVARI,TrainYield,...
'Method','regression','OOBPredictorImportance','on', 'MinLeafSize',nLeaf);
[RFPredictYield,RFPredictConfidenceInterval]=predict(RFModel,TestVARI);
% PredictBC107=cellfun(@str2num,PredictBC107(1:end));
%% Accuracy of RF
RFRMSE=sqrt(sum(sum((RFPredictYield-TestYield).^2))/size(TestYield,1));
RFrMatrix=corrcoef(RFPredictYield,TestYield);
RFr=RFrMatrix(1,2);
RFRMSEMatrix=[RFRMSEMatrix,RFRMSE];
RFrAllMatrix=[RFrAllMatrix,RFr];
if RFRMSE<1000
disp(RFRMSE);
break;
end
disp(RFCycleRun);
str=['Random Forest is Solving...',num2str(100*RFCycleRun/RFRunNumSet),'%'];
waitbar(RFCycleRun/RFRunNumSet,RFScheduleBar,str);
end
close(RFScheduleBar);
%% Variable Importance Contrast
VariableImportanceX={};
XNum=1;
% for TifFileNum=1:length(TifFileNames)
% if ~(strcmp(TifFileNames(TifFileNum).name(4:end-4),'MaizeArea') | ...
% strcmp(TifFileNames(TifFileNum).name(4:end-4),'MaizeYield'))
% eval(['VariableImportanceX{1,XNum}=''',TifFileNames(TifFileNum).name(4:end-4),''';']);
% XNum=XNum+1;
% end
% end
for i=1:size(Input,2)
eval(['VariableImportanceX{1,XNum}=''',i,''';']);
XNum=XNum+1;
end
figure('Name','Variable Importance Contrast');
VariableImportanceX=categorical(VariableImportanceX);
bar(VariableImportanceX,RFModel.OOBPermutedPredictorDeltaError)
xtickangle(45);
set(gca, 'XDir','normal')
xlabel('Factor');
ylabel('Importance');
%% RF Model Storage
RFModelSavePath='G:\CropYield\02_CodeAndMap\00_SavedModel\';
save(sprintf('%sRF0410.mat',RFModelSavePath),'nLeaf','nTree',...
'RandomNumber','RFModel','RFPredictConfidenceInterval','RFPredictYield','RFr','RFRMSE',...
'TestVARI','TestYield','TrainVARI','TrainYield');
至此,大功告成。
MATLAB实现随机森林(RF)回归与自变量影响程度分析的更多相关文章
- 吴裕雄 python 机器学习——集成学习随机森林RandomForestRegressor回归模型
import numpy as np import matplotlib.pyplot as plt from sklearn import datasets,ensemble from sklear ...
- 随机森林RF、XGBoost、GBDT和LightGBM的原理和区别
目录 1.基本知识点介绍 2.各个算法原理 2.1 随机森林 -- RandomForest 2.2 XGBoost算法 2.3 GBDT算法(Gradient Boosting Decision T ...
- 【机器学习】随机森林RF
随机森林(RF, RandomForest)包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定.通过自助法(boot-strap)重采样技术,不断生成训练样本和测试样本,由训练样本 ...
- Bagging与随机森林(RF)算法原理总结
Bagging与随机森林算法原理总结 在集成学习原理小结中,我们学习到了两个流派,一个是Boosting,它的特点是各个弱学习器之间存在依赖和关系,另一个是Bagging,它的特点是各个弱学习器之间没 ...
- 随机森林RF
bagging 随机森林顾名思义,是用随机的方式建立一个森林,森林里面有很多的决策树组成,随机森林的每一棵决策树之间是没有关联的.在得到森林之后,当有一个新的输 入样本进入的时候,就让森林中的每一棵决 ...
- 随机森林实现 MATLAB
matlab 中随机森林工具箱的下载地址: http://code.google.com/p/randomforest-matlab/downloads/detail?name=Windows-Pre ...
- 机器学习总结(二)bagging与随机森林
一:Bagging与随机森林 与Boosting族算法不同的是,Bagging和随机森林的个体学习器之间不存在强的依赖关系,可同时生成并行化的方法. Bagging算法 bagging的算法过程如下: ...
- SIGAI机器学习第十九集 随机森林
讲授集成学习的概念,Bootstrap抽样,Bagging算法,随机森林的原理,训练算法,包外误差,计算变量的重要性,实际应用 大纲: 集成学习简介 Boostrap抽样 Bagging算法 随机森林 ...
- 机器学习-树模型理论(GDBT,xgboost,lightBoost,随机森林)
tree based ensemble algorithms 主要介绍以下几种ensemble的分类器(tree based algorithms) xgboost lightGBM: 基于决策树算法 ...
- MATLAB随机森林回归模型
MATLAB随机森林回归模型: 调用matlab自带的TreeBagger.m T=textread('E:\datasets-orreview\discretized-regression\10bi ...
随机推荐
- python基础类型,字符串
python基本类型小结 # str,可以用索引取值,但是不能通过索引改变值, # a = "123" a[0]=10,直接TypeError因为字符串是不可变类型 # list, ...
- docker支持ipv6
方法 方法一.Pv6地址 不为容器中的服务特别分配IPv6地址. 只要Docker把外部的IPv6地址端口映射到容器的IPv4端口上,随后访问主机的IPv6相应端口即可. 方法二.为Docker网络分 ...
- CH58X/CH57X/V208 Observer(观察者)例程讨论讲解
使用的是沁恒的CH582M的Observer例程与官方的demo板. 本例程的功能是主机扫描到从机的MAC地址并打印出来. 先对宏定义进行理解讨论. 最大响应扫描数为8,在串口调试助手那里可以看到打印 ...
- Python中Print方法
1 number1 = int(input("请输入第一个数:")) 2 number2 = int(input("请输入第二个数:")) 3 4 # 方法一: ...
- mindxdl--common--k8s_utils.go
// Copyright (c) 2021. Huawei Technologies Co., Ltd. All rights reserved.// Package common define co ...
- 禁用显卡自动更新(解决官办驱动和OEM驱动相冲)
起因 有一天打开MC(我的世界)时候突然显示显卡不支持,想了想可能是自己捣鼓电脑的时候弄坏了,提示说版本不支持,一看自己的驱动还是上古版本,但是之前都是可以正常玩的,想着更新下驱动就行了呗,更新完&q ...
- 9 STL-queue
重新系统学习c++语言,并将学习过程中的知识在这里抄录.总结.沉淀.同时希望对刷到的朋友有所帮助,一起加油哦! 生命就像一朵花,要拼尽全力绽放!死磕自个儿,身心愉悦! 写在前面,本篇章主要介绍S ...
- 【Linux】通过Crontab和shell脚本实现定期备份和删除PG数据库表数据
〇.参考资料 一.Crontab使用 1.查看状态 service crond status 2.新建crontab任务 crontab -e 输入字符串 * * * * * cd /home/big ...
- 【SQL查询】必会的常用函数:条件函数、日期函数、文本函数、窗口函数
〇.概述 1.内容 选择(双分支.多分支) 一.条件函数 1.计算25岁以上和以下的用户数量 CASE THEN END多分支选择 SELECT (CASE WHEN age>=25 THEN ...
- Pycharm介绍下载指南
Pycharm的基本介绍 PyCharm是一种Python IDE是可以帮助用户在使用Python语言开发时提高其效率的开发工具. Pycharm的官网:https://www.jetbrains.c ...