简介
这里主要介绍Fitrensemble (Fit ensemble of learners for regression)回归学习器集成的使用方法。
Fitrensemble
用法描述
Mdl = fitrensemble(Tbl,ResponseVarName)
得到回归模型Mdl,包含使用LSBoost回归树结果、预测器和表Tbl对应预测数据。ResponseVarName 是表Tbl中对应变量的名字,即表头。
Mdl = fitrensemble(Tbl,formula)
利用公式拟合模型和对应表Tbl中的数据。公式是一个解释性模型,对应变量和表中变量拟合Mdl。例如: ‘Y~X1+X2+X3’ 拟合Tbl中对应变量。Y是预测器变量Tbl.X1, Tbl.X2, and Tbl.X3的函数。
Mdl = fitrensemble(Tbl,Y)
运用表Tbl中所有变量作为预测器变量。Y是对应Tbl中变量的向量,其不包括在表Tbl中。
Mdl = fitrensemble(X,Y)
预测器数据在矩阵X中,对应因变量数据在向量Y中。
Mdl = fitrensemble(___,Name,Value)
运用附加设置通过一个或多个:名-值对。
例子1
此例介绍如何使用fitrensemble函数如何创建回归集合,使用carsmall数据集基于汽车的马力和重量预测汽车行驶里程。
clc
clear all
close all
% 加载车辆数据
load carsmall
% 输入变量为马力和重量
X = [Horsepower Weight];
% 自变量数据为里程,采用方法是LSBoost
Mdl = fitrensemble(X,MPG,'Method','LSBoost','NumLearningCycles',100)
% 绘制第一个训练的回归树
view(Mdl.Trained{1},'Mode','graph');
% 使用模型进行预测,150马力,2750磅车辆的里程
mileage = predict(Mdl,[150 2750])

例子2
创建一个回归,以汽缸数、汽缸排量、马力和重量来预测汽车的燃油经济性。然后,使用较少的预测变量训练另一个合集。比较合集的样本预测精度。
加载carsmall数据集。将要在训练中使用的变量存储在表中。
clc
clear all
close all
% 加载车辆数据,并存储在表中
load carsmall
Tbl = table(Cylinders,Displacement,Horsepower,Weight,MPG);
% 训练回归模型
% Mdl1是RegressionEnsemble模型。Mdl1一些显着特征是:
% 聚合算法为'LSBoost'最小二乘增强。
% 由于聚合方法是一种增强算法,因此最多允许10个拆分的回归树。
% 一百棵树组成。
Mdl1 = fitrensemble(Tbl,'MPG');
% 使用训练好的模型,预测 四缸、排量为200立方英寸、
% 功率为150马力、重量为3000磅的四缸汽车的燃油经济性。
pMPG = predict(Mdl1,[4 200 150 3000])
% 使用表中所有变量训练模型,除了Displacement变量
formula = 'MPG ~ Cylinders + Horsepower + Weight';
Mdl2 = fitrensemble(Tbl,formula);
% 比较两个模型的mse,在所有预测变量上训练的集合的样本中MSE较低。
mse1 = resubLoss(Mdl1)
mse2 = resubLoss(Mdl2)
例子3——广义误差估计
估计提升的回归树集合的泛化误差。
clc
clear all
close all
% 加载车辆数据,并存储在表中
load carsmall
X = [Cylinders Displacement Horsepower Weight];
% 使用10-折交叉验证对回归树进行交叉验证。指定每棵树应仅拆分一次。
rng(1); % For reproducibility
t = templateTree('MaxNumSplits',1);
Mdl = fitrensemble(X,MPG,'Learners',t,'CrossVal','on');
% Mdl是RegressionPartitionedEnsemble模型。
% 绘制累积的10-折交叉验证的均方误差(MSE)。显示集合的广义误差。
kflc = kfoldLoss(Mdl,'Mode','cumulative');
figure;
plot(kflc);
ylabel('10-fold cross-validated MSE');
xlabel('Learning cycle');
estGenError = kflc(end)
默认情况下,kfoldLoss返回广义误差。 但是,通过绘制累积损失,可以监督弱学习器累积时损失的变化。
在积累了大约30个弱学习器之后,该组合的MSE约为23.5。
如果广义误差可以接受,则要创建预测模型。调整超参数(例如,每棵树的最大决策拆分数和学习周期数)是一个好习惯。

例子4-自动优化回归
本示例说明如何自动优化超参数fitrensemble。
在此示例中,设置随机种子并使用’expected-improvement-plus’采集函数。另外,为了重现随机森林算法,指定’Reproducible’为true学习器。
clc
clear all
close all
% 加载车辆数据,并存储在表中
load carsmall
% 通过使用自动超参数优化来最大程度减少五倍交叉验证损失
Mdl = fitrensemble([Horsepower,Weight],MPG,'OptimizeHyperparameters','auto')
rng('default')
t = templateTree('Reproducible',true);
Mdl = fitrensemble([Horsepower,Weight],MPG,'OptimizeHyperparameters','auto','Learners',t, ...
'HyperparameterOptimizationOptions',struct('AcquisitionFunctionName','expected-improvement-plus'))

例子5-使用交叉验证优化回归
创建具有令人满意的预测性能的增强回归树集成的一种方法是使用交叉验证来调整决策树的复杂度。在搜索最佳复杂度级别时,调整学习速率以最大程度地减少学习周期。
本示例通过使用交叉验证选项('KFold’名称-值对参数)和kfoldLoss函数来手动查找最佳参数。或者,使用“ 'OptimizeHyperparameters’名称-值”对参数来自动优化超参数。
clc
clear all
close all
% 加载车辆数据,并存储在表中
load carsmall
Tbl = table(Cylinders,Displacement,Horsepower,Weight,MPG);
% 对deep树和stump树进行交叉验证。
rng(1) % For reproducibility
MdlDeep = fitrtree(Tbl,'MPG','CrossVal','on','MergeLeaves','off', ...
'MinParentSize',1,'Surrogate','on');
MdlStump = fitrtree(Tbl,'MPG','MaxNumSplits',1,'CrossVal','on', ...
'Surrogate','on');
% 对于每个变量,使用集合{0.1,0.25,0.5,1}中的每个值来调整学习率。
n = size(Tbl,1);
m = floor(log2(n - 1));
learnRate = [0.1 0.25 0.5 1];
numLR = numel(learnRate);
maxNumSplits = 2.^(0:m);
numMNS = numel(maxNumSplits);
numTrees = 150;
Mdl = cell(numMNS,numLR);
for k = 1:numLR
for j = 1:numMNS
t = templateTree('MaxNumSplits',maxNumSplits(j),'Surrogate','on');
Mdl{j,k} = fitrensemble(Tbl,'MPG','NumLearningCycles',numTrees, ...
'Learners',t,'KFold',5,'LearnRate',learnRate(k));
end
end
% 估计每个集合的累积、交叉验证的MSE。
kflAll = @(x)kfoldLoss(x,'Mode','cumulative');
errorCell = cellfun(kflAll,Mdl,'Uniform',false);
error = reshape(cell2mat(errorCell),[numTrees numel(maxNumSplits) numel(learnRate)]);
errorDeep = kfoldLoss(MdlDeep);
errorStump = kfoldLoss(MdlStump);
% 绘制出交叉验证的MSE随着集成树的数量增加而表现的方式。
% 在同一图中绘制关于学习率的曲线,并针对不同的树复杂性水平绘制单独的图。
% 选择树复杂度级别的子集进行绘制。
mnsPlot = [1 round(numel(maxNumSplits)/2) numel(maxNumSplits)];
figure;
for k = 1:3
subplot(2,2,k)
plot(squeeze(error(:,mnsPlot(k),:)),'LineWidth',2)
axis tight
hold on
h = gca;
plot(h.XLim,[errorDeep errorDeep],'-.b','LineWidth',2)
plot(h.XLim,[errorStump errorStump],'-.r','LineWidth',2)
plot(h.XLim,min(min(error(:,mnsPlot(k),:))).*[1 1],'--k')
h.YLim = [10 50];
xlabel('Number of trees')
ylabel('Cross-validated MSE')
title(sprintf('MaxNumSplits = %0.3g', maxNumSplits(mnsPlot(k))))
hold off
end
hL = legend([cellstr(num2str(learnRate','Learning Rate = %0.2f')); ...
'Deep Tree';'Stump';'Min. MSE']);
hL.Position(1) = 0.6;
% 每条曲线都包含一个最小的经过交叉验证的MSE,该MSE发生在集合中的最佳树数处。
% 确定产生最大MSE最低的最大拆分数,树数和学习率。
[minErr,minErrIdxLin] = min(error(:));
[idxNumTrees,idxMNS,idxLR] = ind2sub(size(error),minErrIdxLin);
fprintf('\nMin. MSE = %0.5f',minErr)
fprintf('\nOptimal Parameter Values:\nNum. Trees = %d',idxNumTrees);
fprintf('\nMaxNumSplits = %d\nLearning Rate = %0.2f\n',...
maxNumSplits(idxMNS),learnRate(idxLR))
% 基于最佳超参数和整个训练集创建预测性合奏。
tFinal = templateTree('MaxNumSplits',maxNumSplits(idxMNS),'Surrogate','on');
MdlFinal = fitrensemble(Tbl,'MPG','NumLearningCycles',idxNumTrees, ...
'Learners',tFinal,'LearnRate',learnRate(idxLR))
t = templateTree('Surrogate','on');
mdl = fitrensemble(Tbl,'MPG','Learners',t, ...
'OptimizeHyperparameters',{'NumLearningCycles','LearnRate','MaxNumSplits'})

