Агрегация Bootstrap (Bagging) регрессионых деревьев с использованием TreeBagger

Statistics and Machine Learning Toolbox™ предлагает два объекта, поддерживающих агрегирование (пакетирование) загрузочных полосок деревьев регрессии: TreeBagger создан при помощи TreeBagger и RegressionBaggedEnsemble создан при помощи fitrensemble. Сравнение TreeBagger и упакованных ансамблей для различий между TreeBagger и RegressionBaggedEnsemble.

В этом примере показан рабочий процесс классификации с использованием функций в TreeBagger только.

Используйте базу данных импорта автомобилей 1985 года с 205 наблюдениями, 25 предикторами и 1 ответом, который является рейтингом страхового риска или «символизацией». Первые 15 переменных являются числовыми, а последние 10 категориальными. Индекс символизации принимает целочисленные значения от -3 до 3.

Загрузите набор данных и разделите его на массивы предикторов и ответов.

load imports-85
Y = X(:,1);
X = X(:,2:end);
isCategorical = [zeros(15,1);ones(size(X,2)-15,1)]; % Categorical variable flag

Поскольку упаковка в мешки использует рандомизированные чертежи данных, ее точный результат зависит от начального случайного seed. Чтобы воспроизвести результаты в этом примере, используйте настройки случайного потока.

rng(1945,'twister')

Нахождение оптимального размера листа

Для регрессии общее правило состоит в том, чтобы задать размер листа 5 и выбрать одну треть входных функций для разделения решения случайным образом. На следующем этапе проверьте оптимальный размер листа, сравнив средние квадратичные невязки, полученные регрессией для различных размеров листа. oobError вычисляет MSE в зависимости от количества выращенных деревьев. Вы должны задать OOBPred на 'On' получить вне мешка предсказаний позже.

leaf = [5 10 20 50 100];
col = 'rbcmy';
figure
for i=1:length(leaf)
    b = TreeBagger(50,X,Y,'Method','R','OOBPrediction','On',...
			'CategoricalPredictors',find(isCategorical == 1),...
            'MinLeafSize',leaf(i));
    plot(oobError(b),col(i))
    hold on
end
xlabel('Number of Grown Trees')
ylabel('Mean Squared Error') 
legend({'5' '10' '20' '50' '100'},'Location','NorthEast')
hold off

Figure contains an axes. The axes contains 5 objects of type line. These objects represent 5, 10, 20, 50, 100.

Красная кривая (размер листа 5) приводит к самым низким значениям MSE.

Оценка важности функции

В практических применениях вы обычно выращиваете ансамбли с сотнями деревьев. Например, предыдущий блок кода использует 50 деревьев для более быстрой обработки. Теперь, когда вы оценили оптимальный размер листа, вырастите более крупный ансамбль со 100 деревьями и используйте его, чтобы оценить функцию важность.

b = TreeBagger(100,X,Y,'Method','R','OOBPredictorImportance','On',...
    'CategoricalPredictors',find(isCategorical == 1),...
    'MinLeafSize',5);

Еще раз проверьте кривую ошибки, чтобы убедиться, что во время обучения ничего не пошло не так.

figure
plot(oobError(b))
xlabel('Number of Grown Trees')
ylabel('Out-of-Bag Mean Squared Error')

Figure contains an axes. The axes contains an object of type line.

Способность предсказания должна зависеть больше от важных функций, чем от неважных функций. Можно использовать эту идею для измерения важности функции.

Для каждой функции переместите значения этой функции через каждое наблюдение в наборе данных и измерьте, насколько хуже становится MSE после сочетания. Это можно повторить для каждой функции.

Постройте график увеличения MSE из-за перестановки наблюдений вне сумки для каждой входной переменной. The OOBPermutedPredictorDeltaError массив хранит увеличение MSE, усредненное по всем деревьям ансамбля и разделенное на стандартное отклонение, взятое над деревьями, для каждой переменной. Чем больше это значение, тем важнее переменная. Наложение произвольного среза в 0,7, можно выбрать четыре наиболее важные функции.

figure
bar(b.OOBPermutedPredictorDeltaError)
xlabel('Feature Number') 
ylabel('Out-of-Bag Feature Importance')

Figure contains an axes. The axes contains an object of type bar.

idxvar = find(b.OOBPermutedPredictorDeltaError>0.7)
idxvar = 1×4

     1     2    16    19

idxCategorical = find(isCategorical(idxvar)==1);

The OOBIndices свойство TreeBagger отслеживает, какие наблюдения находятся вне мешка для каких деревьев. Используя это свойство, можно контролировать долю наблюдений в обучающих данных, которые находятся в мешке для всех деревьев. Кривая начинается примерно с 2/3, что является частью уникальных наблюдений, выбранных одной репликой bootstrap, и снижается до 0 примерно на 10 деревьях.

finbag = zeros(1,b.NTrees);
for t=1:b.NTrees
    finbag(t) = sum(all(~b.OOBIndices(:,1:t),2));
end
finbag = finbag / size(X,1);
figure
plot(finbag)
xlabel('Number of Grown Trees')
ylabel('Fraction of In-Bag Observations')

Figure contains an axes. The axes contains an object of type line.

Выращивание деревьев на сокращенном наборе функций

Используя всего четыре наиболее мощные функции, определите, возможно ли получить аналогичную прогностическую степень. Для начала выращивайте 100 деревьев только на этих функциях. Первые два из четырёх выбранных функций являются числовыми, а последние два - категориальными.

b5v = TreeBagger(100,X(:,idxvar),Y,'Method','R',...
    'OOBPredictorImportance','On','CategoricalPredictors',idxCategorical,...
    'MinLeafSize',5);
figure
plot(oobError(b5v))
xlabel('Number of Grown Trees')
ylabel('Out-of-Bag Mean Squared Error')

Figure contains an axes. The axes contains an object of type line.

figure
bar(b5v.OOBPermutedPredictorDeltaError)
xlabel('Feature Index')
ylabel('Out-of-Bag Feature Importance')

Figure contains an axes. The axes contains an object of type bar.

Эти четыре наиболее мощные функции дают тот же MSE, что и полный набор, и ансамбль, обученный на сокращённом наборе, ранжирует эти функции аналогично друг другу. Если вы удалите функции 1 и 2 из редуцированного набора, то прогнозирующая степень алгоритма может значительно не уменьшиться.

Нахождение выбросов

Чтобы найти выбросы в обучающих данных, вычислите матрицу близости с помощью fillProximities.

b5v = fillProximities(b5v);

Метод нормализует эту меру путем вычитания среднего измерения выбросов для всей выборки. Затем он принимает величину этого различия и делит результат на медианное абсолютное отклонение для всей выборки.

figure
histogram(b5v.OutlierMeasure)
xlabel('Outlier Measure')
ylabel('Number of Observations')

Figure contains an axes. The axes contains an object of type histogram.

Обнаружение кластеров в данных

Применяя многомерное масштабирование к вычисленной матрице близостей, можно просмотреть структуру входных данных и искать возможные кластеры наблюдений. The mdsProx метод возвращает масштабированные координаты и собственные значения для вычисленной матрицы близости. Если вы запускаете его с Colors аргумент name-value-pair, затем этот метод создает график поля точек двух масштабированных координат.

figure(8)
[~,e] = mdsProx(b5v,'Colors','K');
xlabel('First Scaled Coordinate')
ylabel('Second Scaled Coordinate')

Figure contains an axes. The axes contains an object of type scatter.

Оцените относительную важность масштабированных осей путем построения первых 20 собственных значений.

figure
bar(e(1:20))
xlabel('Scaled Coordinate Index')
ylabel('Eigenvalue')

Figure contains an axes. The axes contains an object of type bar.

Сохранение строения ансамбля для будущего использования

Чтобы использовать обученный ансамбль для предсказания отклика на невидимых данных, храните ансамбль на диске и извлекайте его позже. Если вы не хотите вычислять предсказания для данных вне сумки или повторно использовать обучающие данные каким-либо другим способом, нет необходимости хранить сам объект ансамбля. Экономии компактной версии ансамбля в данном случае достаточно. Извлеките компактный объект из ансамбля.

c = compact(b5v)
c = 
  CompactTreeBagger
Ensemble with 100 bagged decision trees:
              Method:           regression
       NumPredictors:                    4

  Properties, Methods

Можно сохранить получившееся CompactTreeBagger модель в *.mat файл.

См. также

| | | | |

Похожие темы