GBDT машинного обучения (простое понимание)

машинное обучение искусственный интеллект Python алгоритм

Дерево решений было кратко представлено ранее, а эта статья кратко представляет GBDT (Gradient Boosting Decision Tree).

Gradient Boosting

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

**Ускорение** В задачах классификации он изучает несколько классификаторов, изменяя вес обучающих выборок (увеличивая вес неправильно классифицированных выборок и уменьшая вес отсоединенных выборок) и линеаризуя комбинацию этих классификаторов для повышения производительности классификатора. Следовательно, комбинация дерева решений и бустинга дает множество алгоритмов, в основном включающих бустинг-дерево, GBDT и т. д.

Повышение градиента - это метод повышения Основная идея заключается в том, что каждый раз, когда модель строится, направление градиентного спуска функции потерь модели устанавливается раньше. Функция потерь предназначена для оценки производительности модели (как правило, степень соответствия + регулярный член), Считается, что чем меньше функция потерь, тем лучше производительность. Позволяя функции потерь продолжать уменьшаться, модель может продолжать улучшаться и улучшать свою производительность.Лучший способ - заставить функцию потерь уменьшаться в направлении градиента. Gradient Boosting — это фреймворк, в который можно встроить множество различных алгоритмов.

Gradient Boosting Decision Tree

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

Подкласс дерева решений

class DecisionTree(object):
    """Super class of RegressionTree and ClassificationTree.
 
    def __init__(self, min_samples_split=2, min_impurity=1e-7,
                 max_depth=float("inf"), loss=None):
        self.root = None  # Root node in dec. tree
        # Minimum n of samples to justify split
        self.min_samples_split = min_samples_split
        # The minimum impurity to justify split
        self.min_impurity = min_impurity
        # The maximum depth to grow the tree to
        self.max_depth = max_depth
        # Function to calculate impurity (classif.=>info gain, regr=>variance reduct.)
        # 切割树的方法,gini,方差等
        self._impurity_calculation = None
        # Function to determine prediction of y at leaf
        # 树节点取值的方法,分类树:选取出现最多次数的值,回归树:取所有值的平均值
        self._leaf_value_calculation = None
        # If y is one-hot encoded (multi-dim) or not (one-dim)
        self.one_dim = None
        # If Gradient Boost
        self.loss = loss

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

classification Tree:

class ClassificationTree(DecisionTree):
    def _calculate_information_gain(self, y, y1, y2):
        # 交叉墒
        # Calculate information gain
        p = len(y1) / len(y)
        entropy = calculate_entropy(y)
        info_gain = entropy - p * \
                              calculate_entropy(y1) - (1 - p) * \
                                                      calculate_entropy(y2)
        # print("info_gain",info_gain)
        return info_gain
 
    def _majority_vote(self, y):
      # 计算节点,出现最多
        most_common = None
        max_count = 0
        for label in np.unique(y):
            # Count number of occurences of samples with label
            count = len(y[y == label])
            if count > max_count:
                most_common = label
                max_count = count
        # print("most_common :",most_common)
        return most_common
 
    def fit(self, X, y):
        self._impurity_calculation = self._calculate_information_gain
        self._leaf_value_calculation = self._majority_vote
        super(ClassificationTree, self).fit(X, y)

RegressionTree:

class RegressionTree(DecisionTree):
    def _calculate_variance_reduction(self, y, y1, y2):
        # 平方残差
        var_tot = calculate_variance(y)
        var_1 = calculate_variance(y1)
        var_2 = calculate_variance(y2)
        frac_1 = len(y1) / len(y)
        frac_2 = len(y2) / len(y)
 
        # Calculate the variance reduction
        variance_reduction = var_tot - (frac_1 * var_1 + frac_2 * var_2)
 
        return sum(variance_reduction)
 
    def _mean_of_y(self, y):
        # 平均值
        value = np.mean(y, axis=0)
        return value if len(value) > 1 else value[0]
 
    def fit(self, X, y):
        self._impurity_calculation = self._calculate_variance_reduction
        self._leaf_value_calculation = self._mean_of_y
        super(RegressionTree, self).fit(X, y)

Приложение GDBT — регрессия и классификация

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

Принцип ГБДТ

Как улучшить подгонку модели без изменения структуры исходной модели

Предположим, что имеется выборочный набор (x1, y1), (x2, y2)...., затем используйте модель f(x) для подгонки данных, создав функцию квадратичных потерь:

image.png

минимум. Однако обнаружено, что, хотя эффект подгонки хороший, все же имеется зазор. Поскольку параметры исходной модели не могут быть изменены, это означает, что улучшения должны быть сделаны на основе исходной модели.Интуиция состоит в том, чтобы предложить новую модель fx, чтобы подогнать Fx, чтобы полностью соответствовать остатку реальной выборки, то есть , уФ(х). Набор подобранных выборок, полученных для каждой выборки, становится: (x1, y1 - F(x1)), (x2, y2 - F(x2)), (x3, y3 - F(x3)),..., (xn, yn - F(xn))

GBDT создает новые функции

Особенности определяют модель в последнюю очередь. Если данные могут быть представлены как линейно разделимые данные, то для получения лучших результатов можно использовать простую линейную модель. Построение новых функций в GBDT также направлено на то, чтобы функции лучше выражали данные.在预测Facebook广告点击中,使用一种将决策树与逻辑回归结合在一起的模型,其优于其他方法,超过3%。
Основная идея: путь каждого дерева в GBDT напрямую используется в качестве входного признака LR.
用已有特征训练GBDT模型,然后利用GBDT模型学习到的树来构造新特征,最后把这些新特征加入原有特征一起训练模型。构造的新特征向量是取值0/1的,向量的每个元素对应于GBDT模型中树的叶子结点。当一个样本点通过某棵树最终落在这棵树的一个叶子结点上,那么在新特征向量中这个叶子结点对应的元素值为1,而这棵树的其他叶子结点对应的元素值为0。新特征向量的长度等于GBDT模型里所有树包含的叶子结点数之和。

image.png
Пример 1: На приведенном выше рисунке есть два дерева, левое дерево имеет три листовых узла, а правое дерево имеет два листовых узла Последний признак — пятимерный вектор. Для входа x, если предположить, что он попадает в первый узел левого дерева, кодируя [1,0,0], и попадает во второй узел правого дерева, кодируя [0,1], поэтому общее кодирование равно [1,0, 0,0,1], такие коды используются в качестве признаков и вводятся в модель линейной классификации (LR или FM) для классификации.

Принцип кратко изложен выше, и автор не совсем его понимает. Узнайте больше позже. Код здесь не реализован, пожалуйста, проверьте инструментарий sklearn, если он вам нужен.

Использованная литература:
Принцип GBDT и использование GBDT для создания новых функций — реализация Python
Машинное обучение — понимание принципов GBDT в одной статье — 20171001
Реализация исходного кода Python для GBDT