1. Концепция
1.1 League of Legends или AdaBoost?
Идея игры ЛОЛ группой такова: когда противник начинает группу, у каждого из пяти героев своя роль, танк должен быть мясистым, а АЦП должно хватать на вывод... Итак , чем комплекснее тип, тем легче противнику уничтожить группу. По сути, модель AdaBoost такая же, как и у группы LOL. Столкнувшись с набором данных, каждый базовый ученик (герой) имеет свою собственную направленность, и чем полнее охват, тем лучше эффект обучения. При этом ** имеет определенную последовательность: ** сначала управление, а потом вывод. . .
1.2 Настоящий АдаБуст
1.2.1 Пример пространства
Предположим, что задан двоичный набор обучающих данных.,вЯвляетсяразмерный вектор, метка.
1.2.2 Выражения
в формулесередина,результат вычисления слабого ученика,модель слабого ученика,число слабых учащихся. Во время каждой итерации каждая итерация выбирает слабого ученика и присваивает ему вес., то для первогоДля образца, вся модель AdaBoostошибка обучения за эпохуможно выразить как:
в формулесерединаоснован на предыдущемМодель, полученная итерацией,является слабым учеником этого раунда обучения и будет добавлен в окончательную модель после завершения обучения.
1.2.3 Функция потерь AdaBoost
Выражение функции:
1.2.4 Прошлое и настоящее AdaBoost
Предположим, послепосле генерации(), дляДля примера общественностьЭто может быть выражено как
По формулеимеют
Когда функция потерь экспоненциальная потеря:
формула, так какявляется фиксированным значением, обозначаемым как. Итак, предположим, и когдакогда есть, то формуламожно записать как:
Если модель AdaBoost может правильно классифицировать в демонстрационном пространстве, есть:; при неправильной классификации:. Следовательно, формуламожно записать как:
в формуле, чтобы сделать классификацию модели AdaBoost максимально корректной, то есть найтисделатьсрок как можно меньше (при условии), так чтоискать выводимеют:
Пусть формулаза:
так какиневажно, формулаВозьмем логарифм слева и справа:
потому чтоСпустя время частота ошибокза:
Итак, формулаза
Наконец, обновивзаПроизводительность модели AdaBoost можно улучшить.
1.2.5 Основной процесс
2. Другое понимание AdaBoost
3. Дерево усиления
На самом деле дерево бустинга не такое уж и высокое, то есть дерево решений используется как слабый ученик в приведенной выше модели AdaBoost, и, строго говоря, онорешение, ниже показан каштан, иллюстрирующий, как строится повышающее дерево на основе классификации.
3.1 Данные
Предположим, у нас есть набор данных, показанный на рисунке 1. Цель: использовать повышающее дерево для прогнозирования сердечных заболеваний (зеленый столбец), трех признаков (боль в груди, закупорка артерий, вес пациента).
1. Присвойте каждой выборке одинаковый вес, указав, что они в первую очередь одинаково важны для классификатора.
2. Подсчитать количество правильных и неправильных классификаций при разных собственных значениях и вычислить их коэффициенты Джини.
Поскольку коэффициент Джини признака «Вес пациента» наименьший, в качестве первого классификатора выбирается пень дерева принятия решений, образованный этим признаком.Когда функция «Вес пациента» используется в качестве критерия принятия решения, только на всем тренировочном набореошибка, то есть. По формуле, вес классификатора можно рассчитать как:
3. Перемасштабировать распределение данных по весам.
-
Для неправильных образцов увеличьте вес.
-
Для правильно классифицированных образцов уменьшите веса.
-
Регулярные веса.
4. Создайте новое распределение данных (чтобы оно имело ту же форму, что и исходные данные).
В этом случае рассмотрите данные на рис. 3.5 как распределение вероятностей. выбрать один наугадцифры внутри:
- как, то первый0данные бара (Да, Да, 205, Да) добавляются вновый набор данных;
- как, то первый2данные бара (Нет, Да, 180, Да) добавляются вновый набор данных;
- как, то первый2данные (Да, Да, 167, Да) добавляются вновый набор данных; ... и так далее
Очевидно, что данные, неправильно классифицированные первым классификатором, имеют высокую вероятность попасть в новый набор данных, и их может быть больше одного. Предположим, что новый набор данных выглядит так:
Перейдите к шагу 1. Заканчивается до тех пор, пока в модели не окажется указанное количество классификаторов.
4. Код
class AdaBoost(object):
def __init__(self, n_estimator, weaker_learner, column_type):
'''
AdaBoost 模型初始化
:param n_estimator: 选取n_estimator个弱学习器
'''
# 弱学习器的数量
self.n_estimator = n_estimator
# 每一列数据的类型(连续/离散)
self.column_type = column_type
# 初始化每个学习器权重
self.alpha = [1] * n_estimator
# 初始弱学习器数组
self.weaker_learners = []
# 初始化样本数据集大小以及特征数量
self.data_size, self.feature_size = 0, 0
# 特征的索引值
self.feature_indices = []
# 初始化弱学习器
self.weaker_learner = weaker_learner
# 初始化训练集的权值分布
self.w = None
def __initArgs__(self, _X, _Y):
'''
相关参数初始化
:param _X: 训练集特征值
:param _Y: 训练集标签值
:return:
'''
self.train_x = _X
self.train_y = _Y
self.data_size, self.feature_size = _X.shape
self.feature_indices = [_ for _ in range(self.feature_size)]
def getErrorRate(self, true_y, fake_y):
'''
计算第ith_estimator个弱学习器的误差
:param fake_y: 弱学习器的编号
:return: 弱学习器的错误率
'''
aggErrors = np.multiply(np.mat(true_y) != np.mat(fake_y), np.ones(fake_y.shape))
return aggErrors.sum() / true_y.shape[0]
def getAlpha(self, error_rate):
'''
计算第ith_estimator个弱学习器的权重
:param error_rate: 错误率
:return: 弱学习器对应的权重
'''
return 0.5 * np.log((1-error_rate)/error_rate)
def fit(self, _X, _Y):
'''
AdaBoost 模型训练
:param _X: 特征值
:param _Y: 标签值
:return:
'''
self.__initArgs__(_X, _Y)
for ith_estimator in range(self.n_estimator):
print('%d\'s estimator:' % ith_estimator)
# 初始化分布
self.w = 1 / self.data_size * np.ones((self.data_size, 1))
# 新建一个弱学习器
# 寻找最优的划分节点
weaker_learner = self.weaker_learner(ith_estimator, self.column_type)
weaker_learner.fit(_X, _Y)
weaker_learner_result = weaker_learner.predict(_X)
self.weaker_learners.append((weaker_learner.__root__.feature_index, weaker_learner))
# 计算错误率
error_rate = self.getErrorRate(self.train_y, weaker_learner_result)
print('error_rate:', error_rate)
# 计算该弱学习器的权重
ith_alpha = self.getAlpha(error_rate)
print('alpha:', ith_alpha)
self.alpha[ith_estimator] = ith_alpha
print(self.train_y)
print(weaker_learner_result)
# 更新w
w_tmp = - ith_alpha * np.multiply(self.train_y, weaker_learner_result)
self.w = np.multiply(self.w, np.exp(w_tmp))
print('update weights:', self.w)
# 规范化w
self.w /= self.w.sum()
print('normal weights:', self.w)
# 如果错误率比随机猜还差,那就停止
if error_rate > 0.5:
break
else:
_X, _Y = self.resampleData()
print('resample data')
print(_X)
print(_Y)
print('train done')
def resampleData(self):
'''
数据重采样,先计算每个样本需要被抽取的次数,
然后列索引按照抽取次数从大到小排序(注意是列)
:return:
'''
# 确定每个样本需要抽取的次数
nums = list(np.multiply(self.w.T[0], self.data_size))
# 将权重的索引按 权重的大小排序(从大到小)
idx = list(np.argsort(self.w.T[0]))
idx.reverse()
new_index = []
for id in idx:
num_arr = (int(nums[id]) + 1) * [id]
new_index.extend(num_arr)
if len(new_index) == self.data_size:
break
return self.train_x[new_index], self.train_y[new_index]
def predict(self, X):
'''
预测
:param x: 1*d 维的特征值
:return: 预测结果
'''
print('predict')
result = []
for x in X:
res = 0
for index, weaker_learner in enumerate(self.weaker_learners):
res += self.alpha[index] * weaker_learner[1].predict(
np.array([x])
)
result.append(1 if res > 0 else -1)
return np.array([result]).T
5. Резюме
Самая большая проблема в машинном обучении — работа с наборами данных.пространственная катастрофаВообще говоря, после уменьшения количества признаков, несмотря на то, что скорость вычислений улучшилась, призрак знает, уменьшилась ли точность подгонки модели после удаления признаков. Модель AdaBoost отличается от алгоритмов SVM и нейронных сетей.В модели AdaBoost вам нужно выбрать только те функции, которые вы считаете полезными.Пока есть достаточное количество братьев (основных учеников), можно нарисовать любую модель (конечно , такого рода переоснащение модели того не стоит).
PS: после того, как вы привыкли к индексу строк и столбцов pandas, использование Numpy — это просто яма.
6. Ссылки
- Википедия говорит лучше большинства блоггеров!
- Одна статья для понимания функции потерь, обычно используемой в машинном обучении (функция потерь).
- арбузная книга
- Статистические методы обучения