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

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

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

Используйте данные ионосферы с 351 наблюдением и 34 реальными предикторами. Переменная отклика категориальна с двумя уровнями:

  • 'g' представляет хорошие радиолокационные возвраты.

  • 'b' представляет плохие радиолокационные возвраты.

Цель состоит в том, чтобы предсказать хорошие или плохие возвраты с помощью набора из 34 измерений.

Исправьте начальный случайный seed, вырастите 50 деревьев, проверьте, как изменяется ошибка ансамбля с накоплением деревьев, и оцените значимость функции. Для классификации лучше всего задать минимальный размер листа 1 и выбрать квадратный корень из общего количества функций для каждого разделения решения случайным образом. Эти настройки по умолчанию для TreeBagger используется для классификации.

load ionosphere
rng(1945,'twister')
b = TreeBagger(50,X,Y,'OOBPredictorImportance','On');
figure
plot(oobError(b))
xlabel('Number of Grown Trees')
ylabel('Out-of-Bag Classification Error')

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

Метод обучает ансамбли с небольшим количеством деревьев наблюдениям, которые находятся в мешке для всех деревьев. Для таких наблюдений невозможно вычислить истинное предсказание вне мешка, и TreeBagger возвращает наиболее вероятный класс для классификации и среднее значение выборки для регрессии. Вы можете изменить значение по умолчанию, возвращенное для наблюдений в мешке с помощью DefaultYfit свойство. Если вы устанавливаете значение по умолчанию в пустой символьный вектор для классификации, метод исключает наблюдения в мешке из расчета ошибки вне мешка. В этом случае кривая более переменная, когда количество деревьев мало, либо потому, что некоторые наблюдения никогда не выходят из мешка (и поэтому исключены), либо потому, что их предсказания основаны на немногих деревьях.

b.DefaultYfit = '';
figure
plot(oobError(b))
xlabel('Number of Grown Trees')
ylabel('Out-of-Bag Error Excluding In-Bag Observations')

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

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

finbag = zeros(1,b.NumTrees);
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.

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

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

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

Выберите функции, дающую меру важности больше 0,75. Этот порог выбирается произвольно.

idxvar = find(b.OOBPermutedPredictorDeltaError>0.75)
idxvar = 1×5

     3     5     7     8    27

Отобрав самые важные функции, вырастите большой ансамбль на уменьшенном наборе функций. Сэкономьте время, не переставая наблюдения вне мешка, чтобы получить новые оценки важности функции для сокращенного набора функций (set OOBVarImp на 'off'). Вы все еще были бы заинтересованы в получении вне мешка оценок ошибки классификации (set OOBPred на 'on').

b5v = TreeBagger(100,X(:,idxvar),Y,'OOBPredictorImportance','off','OOBPrediction','on');
figure
plot(oobError(b5v))
xlabel('Number of Grown Trees')
ylabel('Out-of-Bag Classification Error')

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

Для классификационных ансамблей, в дополнение к ошибке классификации (доля неправильно классифицированных наблюдений), можно также контролировать средний запас классификации. Для каждого наблюдения запас определяется как различие между счетом для истинного класса и максимальным счетом для других классов, предсказанных этим деревом. Совокупный классификационный запас использует счета, усредненные по всем деревьям, а средний совокупный классификационный запас является совокупным запасом, усредненным по всем наблюдениям. The oobMeanMargin метод с 'mode' для аргумента задано значение 'cumulative' (по умолчанию) показывает, как средний совокупный запас изменяется по мере роста ансамбля: каждый новый элемент возвращаемого массива представляет совокупный запас, полученный путем включения нового дерева в ансамбль. Если обучение успешно, вы ожидаете постепенного увеличения среднего запаса классификации.

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

Для деревьев решений классификационная оценка является вероятностью наблюдения образца этого класса в этом древовидном листе. Например, если лист выращенного дерева решений имеет пять 'good' и три 'bad' обучающие наблюдения в нем, счета, возвращенные этим деревом решений для любого наблюдения, упавшего на этот лист, 5/8 для 'good' класс и 3/8 для 'bad' класс. Эти вероятности называются 'scores' для согласованности с другими классификаторами, которые могут не иметь очевидной интерпретации для числовых значений возвращенных предсказаний.

figure
plot(oobMeanMargin(b5v));
xlabel('Number of Grown Trees')
ylabel('Out-of-Bag Mean Classification Margin')

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

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

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.

Найдите класс экстремальных выбросов.

extremeOutliers = b5v.Y(b5v.OutlierMeasure>40)
extremeOutliers = 6x1 cell
    {'g'}
    {'g'}
    {'g'}
    {'g'}
    {'g'}
    {'g'}

percentGood = 100*sum(strcmp(extremeOutliers,'g'))/numel(extremeOutliers)
percentGood = 100

Все экстремальные выбросы маркированы 'good'.

Что касается регрессии, можно построить график масштабированных координат, отобразив два класса в разных цветах с помощью аргумента пары "имя-значение" 'Colors' mdsProx. Этот аргумент принимает вектор символов, в котором каждый символ представляет цвет. Программа не ранжирует имена классов. Поэтому лучшей практикой определить положение классов в ClassNames свойство ансамбля.

gPosition = find(strcmp('g',b5v.ClassNames))
gPosition = 2

The 'bad' класс является первым и 'good' класс - второй. Отобразите масштабированные координаты, используя красный цвет для 'bad' класс и синий для 'good' наблюдения классов.

figure
[s,e] = mdsProx(b5v,'Colors','rb');
xlabel('First Scaled Coordinate')
ylabel('Second Scaled Coordinate')

Figure contains an axes. The axes contains 2 objects of type scatter. These objects represent b, g.

Постройте график первых 20 собственных значений, полученных путем масштабирования. Первое собственное значение явно доминирует, и первая масштабированная координата наиболее важна.

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

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

Другой способ исследования эффективности классификационного ансамбля - построить кривую рабочей характеристики приемника (ROC) или другую кривую эффективности, подходящую для текущей задачи. Получите предсказания для наблюдений вне мешка. Для классификационного ансамбля, oobPredict метод возвращает массив ячеек с метками классификации в качестве первого выходного аргумента и числовой массив счетов в качестве второго выходного аргумента. Возвращенный массив счетов имеет два столбца, по одному для каждого класса. В этом случае первый столбец предназначен для 'bad' Классы и второй столбец предназначен для 'good' класс. Один столбец в матрице счетов избыточен, потому что счета представляют вероятности классов в древовидных листьях и по определению складываются в 1.

[Yfit,Sfit] = oobPredict(b5v);

Использование perfcurve для вычисления кривой эффективности. По умолчанию perfcurve возвращает стандартную кривую ROC, которая является истинной положительной частотой по сравнению с ложноположительной частотой. perfcurve требуются метки истинного класса, счета и положительная метка класса для входа. В этом случае выберите 'good' класс как положительный.

[fpr,tpr] = perfcurve(b5v.Y,Sfit(:,gPosition),'g');
figure
plot(fpr,tpr)
xlabel('False Positive Rate')
ylabel('True Positive Rate')

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

Вместо стандартной кривой ROC можно хотеть построить график, например, точности ансамбля от порога по счету для 'good' класс. The ycrit входной параметр perfcurve позволяет вам задать критерий для y-ось и третий выходной аргумент perfcurve возвращает массив порогов для положительного счета класса. Точность - это доля правильно классифицированных наблюдений, или, эквивалентно, 1 минус ошибка классификации.

[fpr,accu,thre] = perfcurve(b5v.Y,Sfit(:,gPosition),'g','YCrit','Accu');
figure(20)
plot(thre,accu)
xlabel('Threshold for ''good'' Returns')
ylabel('Classification Accuracy')

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

Кривая показывает плоскую область, указывающую, что любой порог от 0,2 до 0,6 является разумным выбором. По умолчанию в perfcurve назначает метки классификации, используя 0,5 в качестве контура между этими двумя классами. Вы можете точно найти, какой точности это соответствует.

accu(abs(thre-0.5)<eps)
ans = 0.9316

Максимальная точность немного выше, чем точность по умолчанию.

[maxaccu,iaccu] = max(accu)
maxaccu = 0.9345
iaccu = 99

Поэтому оптимальный порог.

thre(iaccu)
ans = 0.5278

См. также

| | | | | | |

Похожие темы