В этом примере показано, как выбрать подходящий метод выбора расщепленного предиктора для набора данных при выращивании случайного леса регрессионных деревьев. Этот пример также показывает, как решить, какие предикторы наиболее важны для включения в данные обучения.
Загрузить carbig набор данных. Рассмотрим модель, которая предсказывает экономию топлива автомобиля, учитывая его количество цилиндров, рабочий объем двигателя, лошадиную силу, вес, ускорение, модельный год и страну происхождения. Рассмотреть Cylinders, Model_Year, и Origin в качестве категориальных переменных.
load carbig
Cylinders = categorical(Cylinders);
Model_Year = categorical(Model_Year);
Origin = categorical(cellstr(Origin));
X = table(Cylinders,Displacement,Horsepower,Weight,Acceleration,Model_Year,Origin);Стандартный алгоритм CART имеет тенденцию разделять предикторы со многими уникальными значениями (уровнями), например непрерывными переменными, по сравнению с теми, у которых меньше уровней, например категориальными переменными. Если данные неоднородны или переменные предиктора сильно различаются по количеству уровней, попробуйте использовать тесты кривизны или взаимодействия для выбора разделенного предиктора вместо стандартной CART.
Для каждого предиктора определите количество уровней в данных. Один из способов сделать это - определить анонимную функцию, которая:
Преобразует все переменные в категориальный тип данных с помощью categorical
Определяет все уникальные категории при игнорировании отсутствующих значений с помощью categories
Подсчитывает категории с помощью numel
Затем примените функцию к каждой переменной с помощью varfun.
countLevels = @(x)numel(categories(categorical(x))); numLevels = varfun(countLevels,X,'OutputFormat','uniform');
Сравните количество уровней между переменными предиктора.
figure bar(numLevels) title('Number of Levels Among Predictors') xlabel('Predictor variable') ylabel('Number of levels') h = gca; h.XTickLabel = X.Properties.VariableNames(1:end-1); h.XTickLabelRotation = 45; h.TickLabelInterpreter = 'none';

Непрерывные переменные имеют гораздо больше уровней, чем категориальные переменные. Поскольку количество уровней среди предикторов так сильно варьируется, использование стандартной CART для выбора разделенных предикторов в каждом узле деревьев в случайном лесу может дать неточные оценки важности предиктора. В этом случае используйте тест кривизны или тест взаимодействия. Укажите алгоритм с помощью 'PredictorSelection' аргумент пары имя-значение. Дополнительные сведения см. в разделе Выбор метода выбора разделенного предиктора.
Обучите упакованный ансамбль из 200 деревьев регрессии для оценки значений важности предиктора. Определите учащегося дерева, используя следующие аргументы пары имя-значение:
'NumVariablesToSample','all' - Используйте все переменные предиктора в каждом узле, чтобы гарантировать, что каждое дерево использует все переменные предиктора.
'PredictorSelection','interaction-curvature' - Укажите использование теста взаимодействия для выбора разделенных предикторов.
'Surrogate','on' - Укажите использование суррогатных разделений для повышения точности, поскольку набор данных включает отсутствующие значения.
t = templateTree('NumVariablesToSample','all',... 'PredictorSelection','interaction-curvature','Surrogate','on'); rng(1); % For reproducibility Mdl = fitrensemble(X,MPG,'Method','Bag','NumLearningCycles',200, ... 'Learners',t);
Mdl является RegressionBaggedEnsemble модель.
Оцените модели, используя прогнозы вне пакета.
yHat = oobPredict(Mdl); R2 = corr(Mdl.Y,yHat)^2
R2 = 0.8744
Mdl объясняет 87% вариабельности вокруг среднего.
Оценка значений важности предиктора путем перестановки наблюдений вне пакета между деревьями.
impOOB = oobPermutedPredictorImportance(Mdl);
impOOB является вектором 1 на 7 оценок важности предиктора, соответствующих предикторам в Mdl.PredictorNames. Оценки не смещены к предикторам, содержащим много уровней.
Сравните оценки важности предиктора.
figure bar(impOOB) title('Unbiased Predictor Importance Estimates') xlabel('Predictor variable') ylabel('Importance') h = gca; h.XTickLabel = Mdl.PredictorNames; h.XTickLabelRotation = 45; h.TickLabelInterpreter = 'none';

Оценки большей важности указывают на более важные предикторы. Гистограмма предполагает, что Model_Year является наиболее важным предиктором, за которым следует Cylinders и Weight. Model_Year и Cylinders переменные имеют только 13 и 5 различных уровней соответственно, тогда как Weight переменная имеет более 300 уровней.
Сравните оценки важности предиктора путем перестановки наблюдений вне пакета и те оценки, которые получены путем суммирования выигрышей в среднеквадратичной ошибке из-за расщеплений на каждом предикторе. Кроме того, получите показатели предикторной ассоциации, оцененные суррогатными расщеплениями.
[impGain,predAssociation] = predictorImportance(Mdl); figure plot(1:numel(Mdl.PredictorNames),[impOOB' impGain']) title('Predictor Importance Estimation Comparison') xlabel('Predictor variable') ylabel('Importance') h = gca; h.XTickLabel = Mdl.PredictorNames; h.XTickLabelRotation = 45; h.TickLabelInterpreter = 'none'; legend('OOB permuted','MSE improvement') grid on

В соответствии со значениями impGain, переменные Displacement, Horsepower, и Weight представляется не менее важным.
predAssociation является матрицей 7 на 7 показателей предикторной ассоциации. Строки и столбцы соответствуют предикторам в Mdl.PredictorNames. Предиктивная мера связи - это значение, указывающее на сходство между правилами принятия решений, разделяющими наблюдения. Лучшее разделение суррогатного решения дает максимальную прогностическую меру ассоциации. Вы можете вывести силу отношения между парами предикторов, используя элементы predAssociation. Более высокие значения указывают на более сильно коррелированные пары предикторов.
figure imagesc(predAssociation) title('Predictor Association Estimates') colorbar h = gca; h.XTickLabel = Mdl.PredictorNames; h.XTickLabelRotation = 45; h.TickLabelInterpreter = 'none'; h.YTickLabel = Mdl.PredictorNames;

predAssociation(1,2)
ans = 0.6871
Самая большая связь между Cylinders и Displacement, но значение недостаточно высокое, чтобы указывать на сильную взаимосвязь между двумя предикторами.
Поскольку время прогнозирования увеличивается с увеличением числа предикторов в случайных лесах, хорошей практикой является создание модели, использующей как можно меньше предикторов.
Выращивайте случайный лес из 200 регрессионных деревьев, используя только два лучших предиктора. Дефолт 'NumVariablesToSample' значение templateTree составляет одну треть от числа предикторов регрессии, поэтому fitrensemble использует алгоритм случайного леса.
t = templateTree('PredictorSelection','interaction-curvature','Surrogate','on', ... 'Reproducible',true); % For reproducibility of random predictor selections MdlReduced = fitrensemble(X(:,{'Model_Year' 'Weight'}),MPG,'Method','Bag', ... 'NumLearningCycles',200,'Learners',t);
Вычислите уменьшенной модели.
yHatReduced = oobPredict(MdlReduced); r2Reduced = corr(Mdl.Y,yHatReduced)^2
r2Reduced = 0.8653
уменьшенной модели близок к полной модели. Этот результат говорит о том, что уменьшенная модель достаточна для прогнозирования.
corr | fitrensemble | oobPermutedPredictorImportance | oobPredict | predictorImportance | templateTree