В этом примере показано, как выбрать подходящий метод выбора предиктора для вашего набора данных при выращивании случайного леса регрессионых деревьев. Этот пример также показывает, как решить, какие предикторы наиболее важны для включения в обучающие данные.
Загрузите 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);
Стандартный алгоритм ТЕЛЕЖКА имеет тенденцию разделять предикторы со многими уникальными значениями (уровнями), например, непрерывными переменными, по сравнению с теми с меньшим количеством уровней, например, категориальными переменными. Если ваши данные неоднородны, или переменные предиктора сильно варьируются по количеству уровней, то рассмотрите использование тестов кривизны или взаимодействия для выбора разделенного предиктора вместо стандартной ТЕЛЕЖКИ.
Для каждого предиктора определите количество уровней в данных. Один из способов сделать это - задать анонимную функцию, которая:
Преобразует все переменные в категориальный тип данных с помощью 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';
Непрерывные переменные имеют намного больше уровней, чем категориальные переменные. Поскольку количество уровней среди предикторов изменяется так сильно, использование стандартной ТЕЛЕЖКА для выбора разделенных предикторов в каждом узле деревьев в случайном лесу может привести к неточным оценкам важности предиктора. В этом случае используйте тест кривизны или тест взаимодействия. Задайте алгоритм при помощи '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
. The 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