Эта статья возникла из личного публичного аккаунта:TechFlow, оригинальность это не просто, прошу внимания
СегодняТемы машинного обученияВ 25-й статье поговорим об AdaBoost.
На данный момент мы изучили несколько моделей, и только для деревьев решений существует три алгоритма генерации. Но каждый раз, когда мы классифицируем, мы каждый раз используем модель для обучения и прогнозирования. Принимая решение каждый день, мы часто консультируемся с несколькими людьми и всесторонне принимаем их мнения. Так можно ли скопировать эту идею в область машинного обучения и создать несколько моделей для синтеза результатов?
Конечно можно, такой образ мышления называетсяКомплексный подход(метод ансамбля).
Комплексный подход
Сам ансамблевый метод — это не конкретный метод или алгоритм, а идея для обучения модели машинного обучения. Это означает только одно, т.Обучайте несколько моделей и объединяйте их результаты.
В соответствии с этой идеей в отрасли были разработаны три конкретных метода, а именно: бэггинг, форсирование и штабелирование.
Bagging
Бэггинг — это аббревиатура от bootstrap aggregation, и нам буквально трудно понять, что это значит. Нам просто нужно запомнить это имя.В методе Бэгинга мы будем передаватьслучайная выборка с заменойспособ создания наборов данных K. Для каждого набора данных могут быть отдельные повторяющиеся выборки, а также могут быть некоторые выборки, которые никогда не появляются, но в целом вероятность появления каждой выборки одинакова.
После этого мы используем выборочные наборы данных K для обучения моделей K. Модели здесь не ограничены, и мы можем использовать любую модель машинного обучения. K моделей, естественно, получат K результатов, тогда мы возьмемдемократическое голосованиеK-модели каким-то образом агрегированы.
Например, предположим, что K=25 в задаче бинарной классификации. 10 моделей предсказали 0, а 15 моделей предсказали 1. Тогда окончательный результат предсказания всей модели равен 1, что эквивалентно демократическому голосованию K моделей.Каждая модель имеет одинаковое право голоса. Знаменитый случайный лес использует этот подход.
Boosting
Идея Boosting очень похожа на Bagging, и у них одинаковая логика выборки для сэмплов. Разница в том, что в Boosting,Модели K не обучаются одновременно, но обучается серийно. Каждая модель будет основываться на результатах предыдущей модели во время обучения, и уделять больше внимания образцам, которые были неправильно оценены предыдущей моделью. Точно так же выборка также будет иметь вес, а выборка с более высоким коэффициентом ошибочных оценок имеет больший вес.
И каждая модель отличается по своим возможностям,будут даны разные веса, и, наконец, сделать взвешенную сумму всех моделей вместо честного голосования. Благодаря этому механизму эффективность модели при обучении также различна. Поскольку все модели упаковки в пакеты полностью независимы, мы можем внедрить распределенное обучение. Каждая модель в Boosting будет зависеть от эффекта предыдущей модели, поэтому ее можно обучать только последовательно.
Stacking
Stacking — это метод, который часто используется в соревнованиях Kaggle, и его идея очень проста. Мы выбираем K разных моделей, а затем проходимПерекрестная проверкаспособ обучения и прогнозирования на тренировочном наборе. Убедитесь, что каждая модель дает прогноз для всех обучающих выборок. Тогда для каждой обучающей выборки мы можем получить K результатов.
После этого мы создаем модель второго уровня, обучающими функциями которой являются результаты K. То есть будет использоваться метод Stacking.Структура многослойных моделей, функции обучения модели последнего уровня — это результаты, предсказанные моделью верхнего уровня. Модель должна обучать результаты, какая модель более достойна принятия, и как сочетать сильные стороны моделей.
AdaBoost, который мы представляем сегодня, как следует из названия, является классическим алгоритмом Boosting.
Идеи моделей
Основная идея AdaBoost заключается в построении сильного классификатора с помощью некоторых слабых классификаторов с использованием метода Boosting.
Мы все хорошо понимаем сильные классификаторы, то есть модели с высокой производительностью, так как же нам понимать слабые классификаторы? Сила модели фактически определяется относительно случайного результата.Чем лучше модель, чем случайный результат, тем выше ее производительность. С этого моментаСлабые классификаторы — это классификаторы, которые лишь немного сильнее, чем случайные результаты.. Наша цель состоит в том, чтобы объединить результаты этих слабых классификаторов с эффектами сильных классификаторов, разработав веса выборок и моделей, чтобы можно было принимать оптимальные решения.
Сначала присвоим обучающей выборке вес.Вес каждого образца равен. Слабый классификатор обучается на основе обучающих выборок и вычисляется частота ошибок этого классификатора. Затем снова обучите слабый классификатор на том же наборе данных, и во втором обучении мы скорректируем веса каждой выборки.Вес правильного образца уменьшится, а вес неправильного образца увеличится..
Точно так же каждому классификатору также будет присвоено значение веса., чем выше вес, тем больше право голоса. ЭтиОн рассчитывается на основе частоты ошибок модели. Частота ошибокопределяется как:
Здесь D представляет набор данныхПредставляет набор ошибочных классификаций, равный количеству ошибочно классифицированных образцов, деленному на общее количество образцов.
Имея частоту ошибок, мы можем получить по следующей формуле.
ПолучилПосле этого мы используем его для обновления веса выборки, где вес правильной классификации изменяется на:
Неправильно классифицированные веса выборки изменены на:
Таким образом обновляются все наши веса, что завершает одну итерацию. AdaBoost будетПовторяйте и корректируйте веса итеративно, пока частота ошибок обучения не станет равной 0 или количество слабых классификаторов не достигнет порогового значения.
Код
Во-первых, давайте получим данные, здесь мы выбираем данные прогнозирования рака молочной железы в наборе данных sklearn. Как и в предыдущем примере, мы можем импортировать его напрямую, что очень удобно:
import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
breast = load_breast_cancer()
X, y = breast.data, breast.target
# reshape,将一维向量转成二维
y = y.reshape((-1, 1))
Далее без труда разделяем данные на обучающие и тестовые данные, что тоже является обычной практикой:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=23)
В модели AdaBoost мы выбираемСлабые классификаторы — это пень дерева решений. Так называемый пеньДерево решений с глубиной дерева 1. Глубина дерева равна 1. Очевидно, что как бы мы ни выбирали порог, особо хороших результатов мы не получим, но так как мы все же выберем порог и признаки, то результаты будут не так уж и плохи, по крайней мере, лучше, чем случайный выбор. Так что это гарантирует, что мы можем получить слабый классификатор, который немного лучше, чем случайный выбор, и его реализация очень проста.
Прежде чем мы реализуем модель, давайте реализуем несколько вспомогательных функций.
def loss_error(y_pred, y, weight):
return weight.T.dot((y_pred != y_train))
def stump_classify(X, idx, threshold, comparator):
if comparator == 'lt':
return X[:, idx] <= threshold
else:
return X[:, idx] > threshold
def get_thresholds(X, i):
min_val, max_val = X[:, i].min(), X[:, i].max()
return np.linspace(min_val, max_val, 10)
Эти три функции понять несложно.В первой функции мыПогрешность модели рассчитывается. Так как каждая наша выборка имеет свой вес, мы делаем взвешенную сумму ошибок. Вторая функцияФункция прогнозирования для классификатора пней, логика очень простая, сравниваем размер по порогу. Здесь есть два случая.Возможно, выборки меньше порога являются положительными примерами, или выборки больше порога являются положительными примерами, поэтому нам также нужен третий параметр для записи этой информации. Третья функцияфункция для генерации порогов, так как нам не нужно, чтобы производительность культи была особенно хорошей, нам не нужно обходить все значения порога, а просто разделить диапазон признаков на 10 сегментов.
Далее идет функция генерации одного пня, что эквивалентно функции выбора признаков для разбиения данных в дереве решений Логика аналогична и нуждается лишь в небольшой доработке.
def build_stump(X, y, weight):
m, n = X.shape
ret_stump, ret_pred = None, []
best_error = float('inf')
# 枚举特征
for i in range(n):
# 枚举阈值
for j in get_thresholds(X, i):
# 枚举正例两种情况
for c in ['lt', 'gt']:
# 预测并且求误差
pred = stump_classify(X, i, j, c).reshape((-1, 1))
err = loss_error(pred, y, weight)
# 记录下最好的树桩
if err < best_error:
best_error, ret_pred = err, pred.copy()
ret_stump = {'idx': i, 'threshold': j, 'comparator': c}
return ret_stump, best_error, ret_pred
Следующее, что нужно сделать, это повторить операцию формирования культи, вычисливии обновить вес каждого образца. Во всем процессе не слишком много сложностей, в основном по формуле реализации:
def adaboost_train(X, y, num_stump):
stumps = []
m = X.shape[0]
# 样本权重初始化,一开始全部相等
weight = np.ones((y_train.shape[0], 1)) / y_train.shape[0]
# 生成num_stump个树桩
for i in range(num_stump):
best_stump, err, pred = build_stump(X, y, weight)
# 计算alpha
alpha = 0.5 * np.log((1.0 - err) / max(err, 1e-10))
best_stump['alpha'] = alpha
stumps.append(best_stump)
# 更新每一条样本的权重
for j in range(m):
weight[j] = weight[j] * (np.exp(-alpha) if pred[j] == y[j] else np.exp(alpha))
weight = weight / weight.sum()
# 如果当前的准确率已经非常高,则退出
if err < 1e-8:
break
return stumps
После того, как культя сгенерирована, последней частью является прогноз. Весь процесс прогнозирования по-прежнему очень прост, всего лишьвзвешенная суммапроцесс. Здесь следует отметить, что мы сохраняем вес выборок, чтобы выделять ошибочно предсказанные выборки во время обучения, чтобы у модели были лучшие возможности. тем не мениеПри прогнозировании мы не знаем веса прогнозируемой выборки, поэтому нам нужно только взвесить результаты модели.
def adaboost_classify(X, stumps):
m = X.shape[0]
pred = np.ones((m, 1))
alphs = 0.0
for i, stump in enumerate(stumps):
y_pred = stump_classify(X, stump['idx'], stump['threshold'], stump['comparator'])
# 根据alpha加权求和
pred = y_pred * stump['alpha']
alphs += stump['alpha']
pred /= alphs
# 根据0.5划分0和1类别
return np.sign(pred).reshape((-1, 1))
На данный момент вся наша модель реализована.Давайте сначала посмотрим на производительность одного пня на обучающем наборе:
Видно, что показатель точности составляет всего 0,54, что лишь немного лучше, чем случайное предсказание.
Однако, когда мы объединили результаты 20 пней, мы смогли получить точность 0,9 на тренировочном наборе. На наборе прогнозов он работает лучше с точностью, близкой к 0,95!
Это связано с тем, что в AdaBoost каждый классификатор является слабым классификатором.Нет возможности переобуться вообще, в конце концов, производительность на тренировочном наборе очень низкая, что гарантирует, что то, чему научился классификатор, является реальной способностью к обобщению, которая применима к тренировочному набору, а также с высокой вероятностью применима к тестовому набору. Это также одно из самых больших преимуществ комплексного подхода.
Суммировать
Метод ансамбля можно назвать очень важным скачком в области машинного обучения.Появление метода ансамбля,Значительно упрощает разработку сильного классификатора, а также гарантирует эффект модели.
Потому что в некоторых областях может быть очень сложно разработать сильный классификатор, но гораздо проще разработать более слабый классификатор, а сама модель работает хорошо и не подвержена переоснащению. До популярности моделей глубокого обучения широко использовались ансамблевые методы, и ансамблевое обучение использовалось практически во всех соревнованиях в области машинного обучения.
Конкретные идеи интегрированного обучения могут быть разными, но основные идеи одни и те же. После того, как мы разберемся с AdaBoost, нам будет намного легче изучать другие модели ансамбля.
Если вам понравилась эта статья, пожалуйстаобращать внимание, подбодрите меня и облегчите доступ к другим статьям.
В этой статье используетсяmdniceнабор текста