10. Gradient Boosting

Lecture



Hello everyone! It's time to expand our algorithmic arsenal.

10. Gradient Boosting

Today we'll thoroughly break down one of the most popular and widely used machine learning algorithms in practice — gradient boosting. Where boosting's roots come from and what really happens under the hood of the algorithm — in our colorful journey into the world of boosting, below the cut.

UPD: the course is now available in English under the mlcourse.ai brand, with articles on Medium, and materials on Kaggle (Dataset) and on GitHub.

A video recording of the lecture based on this article, from the second run of the open course (September–November 2017).

List of articles in the series

  1. Primary data analysis with Pandas
  2. Visual data analysis with Python
  3. Classification, decision trees, and the nearest neighbors method
  4. Linear classification and regression models
  5. Ensembles: bagging, random forest. Validation and learning curves
  6. Feature engineering and selection
  7. Unsupervised learning: PCA, clustering
  8. Learning on gigabytes with Vowpal Wabbit
  9. Time series analysis with Python
  10. Gradient boosting

Plan of this article:

  1. Introduction and history of boosting
    • History of the emergence of boosting
    • History of the development of GBM
  2. The GBM algorithm
    • Formulating the ML problem
    • Functional gradient descent
    • Friedman's classic GBM algorithm
    • Step-by-step example of GBM at work
  3. Loss functions
    • Regression loss functions
    • Classification loss functions
    • Weights and custom loss functions
  4. Summary on GBM theory
  5. Homework assignment
  6. Useful links

1. Introduction and history of the emergence of boosting

Most people involved in data analysis have heard about boosting at least once. This algorithm is part of the everyday "gentleman's set" of models worth trying on any given task. Xgboost is often associated with the standard recipe for winning ML competitions, giving rise to the meme about "stacking xgboosts". Boosting is also an important part of most search engines, sometimes even serving as their calling card. For general knowledge, let's take a look at how boosting appeared and developed.

History of the emergence of boosting

It all started with the question of whether it's possible to get one strong model from a large number of relatively weak and simple models. By weak models we don't just mean small and simple models like decision trees as opposed to more "strong" models, such as neural networks. In our case, weak models are arbitrary machine learning algorithms whose accuracy may be only slightly better than random guessing.

An affirmative mathematical answer to this question was found fairly quickly, which in itself was an important theoretical result (a rarity in ML). However, it took several years before workable algorithms and Adaboost appeared. Their general approach consisted of greedily building a linear combination of simple models (base algorithms) by reweighting the input data. Each subsequent model (usually a decision tree) was built in such a way as to give greater weight and preference to previously incorrectly predicted observations.

A bit more about Adaboost

Properly, we should have followed the example of most other machine learning courses and carefully examined its predecessor — Adaboost — before gradient boosting. However, we decided to jump straight to the most interesting part, since Adaboost ended up merging with GBM anyway once it became clear that it's simply a special case of it.

The algorithm itself has a very illustrative visual interpretation of the intuition behind weighting observations. Let's consider a toy classification example, in which on each Adaboost iteration we'll try to split the data with a depth-1 tree (the so-called "stump"). On the first two iterations we'll see the following picture:


10. Gradient Boosting

The size of the point corresponds to the weight it received for an incorrect prediction. And we can see how these weights grow with each iteration — the stumps can't handle such a task on their own. However, once we perform a weighted vote of the previously built stumps, we get the split we're looking for:


10. Gradient Boosting

A more detailed example of Adaboost at work, in which over a series of iterations you can see a gradual increase of the points, especially at the boundary between classes:

Adaboost worked well, but because there were few justifications for how the algorithm and its add-ons worked, a full spectrum of speculation arose around them: some considered it a super-algorithm and a magic bullet, others were skeptical and shared the view that it was a barely applicable approach with severe overfitting. This was especially true regarding its applicability to data with strong outliers, to which Adaboost turned out to be unstable. Fortunately, when the professors of the Stanford Statistics Department, who had already given the world Lasso, Elastic Net, and Random Forest, took up the matter, in 1999 Jerome Friedman came up with a generalization of the boosting algorithms — gradient boosting, aka Gradient Boosting (Machine), aka GBM. With this work, Friedman immediately laid a statistical foundation for creating many algorithms, providing a general approach to boosting as optimization in a functional space.

Stanford's legacy

In general, the team at the Stanford Statistics Department is behind CART, bootstrap, and many other things, having already put their names into future statistics textbooks in advance. By and large, a significant part of our everyday toolkit appeared right there, and who knows what else will appear. Or has already appeared but hasn't yet found sufficient adoption (like, for example, glinternet).

There aren't many video recordings with Friedman himself. However, there is a very interesting interview with him about the creation of CART, and in general about how statistical problems (which we would now classify as data analysis and data science) were solved 40+ years ago:

From the series on the educational history of data analysis, there's also a lecture from Hastie with a retrospective on data analysis from one of the people involved in creating the methods we use every day:

Essentially, there was a shift from engineering-algorithmic exploration in building algorithms (so characteristic of ML) to a full-fledged methodology for how to build and study such algorithms. From the point of view of the mathematical substance, at first glance not much changed: we still add (boost) weak algorithms, growing our ensemble with gradual improvements in the areas of the data where previous models "fell short". But when building the next simple model, it's not simply built on reweighted observations, but in such a way as to best approximate the overall gradient of the objective function. On a conceptual level, this opened up a lot of room for imagination and extensions.

History of the development of GBM

Gradient boosting didn't take its place in the "gentleman's set" right away — it took more than 10 years from its appearance. First, the basic GBM gained many extensions for different statistical tasks: GLMboost and GAMboost as a boost to already existing GAM models, CoxBoost for survival curves, RankBoost and LambdaMART for ranking. Second, many implementations of the same GBM appeared under different names and on different platforms: Stochastic GBM, GBDT (Gradient Boosted Decision Trees), GBRT (Gradient Boosted Regression Trees), MART (Multiple Additive Regression Trees), GBM as Generalised Boosting Machines, and others. On top of that, the machine learning communities were quite fragmented and worked on all sorts of things, which makes it fairly hard to trace boosting's progress.

At the same time, boosting began to be actively applied to search engine results ranking tasks. This task was formulated in terms of a loss function that penalizes errors in the ranking order, which made it convenient to simply plug it into GBM. Among the first to introduce boosting into ranking was AltaVista, soon followed by Yahoo, Yandex, Bing, and others. And when we talk about introducing it, we mean that boosting became the main algorithm inside production engines for years to come, not just another interchangeable research toy living within a couple of academic papers.

10. Gradient BoostingThe main role in popularizing boosting was played by ML competitions, especially Kaggle. Researchers had long lacked a common platform with enough participants and tasks for people with their algorithms and approaches to compete openly for the state of the art. Shadowy German geniuses who grew yet another miracle algorithm in their garage could no longer blame everything on closed data, while real breakthrough libraries, on the contrary, got an excellent platform to develop on. This is exactly what happened with boosting, which took root on Kaggle almost immediately (it's worth looking for GBM in winners' interviews starting from 2011), and xgboost as a library quickly gained popularity soon after it appeared. At the same time, xgboost isn't some new unique algorithm, but simply an extremely efficient implementation of classic GBM with some additional heuristics.

And here we are, in 2017, using an algorithm that has gone through a very typical ML path from a mathematical problem and algorithmic tinkering, through the emergence of proper algorithms and proper methodology, to successful practical applications and mass adoption, years after its appearance.

2. The GBM algorithm

Formulating the ML problem

We will be solving the function approximation problem in the general context of supervised learning. We'll have a set of pairs of features 10. Gradient Boosting and target variables 10. Gradient Boosting, 10. Gradient Boosting, on which we will approximate a dependency of the form 10. Gradient Boosting. We'll approximate it with 10. Gradient Boosting, and to understand which approximation is better, we'll also have a loss function 10. Gradient Boosting, which we'll minimize:

10. Gradient Boosting

10. Gradient Boosting

For now we're not making any assumptions about the type of dependency 10. Gradient Boosting, nor about the model of our approximations 10. Gradient Boosting, nor about the distribution of the target variable 10. Gradient Boosting. Except that the function 10. Gradient Boosting must be differentiable. Since the problem needs to be solved not on all the data in the world, but only on what we have available, let's rewrite everything in terms of expected values. Namely, we'll look for our approximations 10. Gradient Boosting so as to minimize, on average, the loss function on the data we have:

10. Gradient Boosting

Unfortunately, there aren't simply many functions 10. Gradient Boosting in the world — their functional space itself is infinite-dimensional. So, to solve the problem at all, machine learning usually restricts the search space to some specific parameterized family of functions 10. Gradient Boosting. This greatly simplifies the problem, since it reduces to an already quite solvable optimization of parameter values:

10. Gradient Boosting

Analytical one-line solutions for obtaining the optimal parameters 10. Gradient Boosting exist fairly rarely, so the parameters are usually approximated iteratively. First we need to write out the empirical loss function 10. Gradient Boosting, which shows how well we've estimated them based on the data we have. We'll also write out our approximation 10. Gradient Boosting over 10. Gradient Boosting iterations as a sum (both for clarity, and to start getting used to boosting):

10. Gradient Boosting

All that's left is small — we just need to take a suitable iterative algorithm with which we'll minimize 10. Gradient Boosting. The simplest and most commonly used option is gradient descent. For it, we need to write out the gradient 10. Gradient Boosting and add our iterative estimates 10. Gradient Boosting along it (with a minus sign — after all, we want to decrease the error, not increase it). And that's it, we just need to somehow initialize our first approximation 10. Gradient Boosting and choose how many iterations 10. Gradient Boosting we'll continue this procedure for. In our memory-inefficient way of storing approximations 10. Gradient Boosting, the naive algorithm will look as follows:

  1. Initialize the initial approximation of the parameters 10. Gradient Boosting
  2. For each iteration 10. Gradient Boosting repeat:
    1. Calculate the gradient of the loss function 10. Gradient Boosting at the current approximation 10. Gradient Boosting
      10. Gradient Boosting
    2. Set the current iterative approximation 10. Gradient Boosting based on the calculated gradient
      10. Gradient Boosting
    3. Update the approximation of the parameters 10. Gradient Boosting:
      10. Gradient Boosting
  3. Save the final approximation 10. Gradient Boosting
    10. Gradient Boosting
  4. Use the found function 10. Gradient Boosting for its intended purpose

10. Gradient Boosting

Functional gradient descent

Let's expand our minds: imagine for a second that we can perform optimization in a functional space and iteratively look for approximations 10. Gradient Boosting in the form of the functions themselves. Let's write out our approximation as a sum of incremental improvements, each of which is a function. For convenience, we'll immediately count this sum starting from the initial approximation 10. Gradient Boosting:

10. Gradient Boosting

No magic has happened yet, we've simply decided that we'll look for our approximation 10. Gradient Boosting not in the form of one big model with a bunch of parameters (like, for example, a neural network), but in the form of a sum of functions, pretending that this way we're moving through a functional space.

To solve the problem, we'll still have to restrict our search to some family of functions 10. Gradient Boosting. But, first, a sum of models can be more complex than any single model from this family (a sum of two depth-1 stump trees can no longer be approximated by a single stump). Second, the overall problem is still happening in a functional space. Let's immediately take into account that at each step, for the functions, we'll need to pick an optimal coefficient 10. Gradient Boosting. For step 10. Gradient Boosting the problem looks as follows:

10. Gradient Boosting

And now it's time for the magic. We wrote out all our problems in general form, as if we could just go ahead and train any models 10. Gradient Boosting whatsoever with respect to any loss functions 10. Gradient Boosting whatsoever. In practice, this is extremely difficult, so a simple way was devised to reduce the problem to something solvable.

Knowing the expression for the gradient of the loss function, we can calculate its values on our data. So let's train the models so that our predictions are most correlated with this gradient (with a minus sign). That is, we'll be solving an OLS regression problem, trying to fit predictions to these residuals. For classification, for regression, and for ranking, under the hood we'll always be minimizing the squared difference between the pseudo-residuals 10. Gradient Boosting and our predictions. For step 10. Gradient Boosting the final problem looks as follows:

10. Gradient Boosting

10. Gradient Boosting

Friedman's classic GBM algorithm

Now we have everything we need to finally write out the GBM algorithm proposed by Jerome Friedman in 1999. We're still solving the general supervised learning problem. To run the algorithm, we need to gather several components:

  • the dataset 10. Gradient Boosting;
  • the number of iterations 10. Gradient Boosting;
  • a choice of loss function 10. Gradient Boosting with its gradient written out;
  • a choice of family of functions for the base algorithms 10. Gradient Boosting, with a training procedure for them;
  • additional hyperparameters 10. Gradient Boosting, for example, the tree depth for decision trees;

The only point that's been left unattended — the initial approximation 10. Gradient Boosting. For simplicity, a simple constant value 10. Gradient Boosting is used as the initialization. It, as well as the optimal coefficient 10. Gradient Boosting, is found by binary search, or another line search algorithm, with respect to the original loss function (not the gradient). So, the GBM algorithm:

  1. Initialize GBM with the constant value 10. Gradient Boosting
    10. Gradient Boosting
  2. For each iteration 10. Gradient Boosting repeat:
    1. Calculate the pseudo-residuals 10. Gradient Boosting
      10. Gradient Boosting
    2. Build a new base algorithm 10. Gradient Boosting as a regression on the pseudo-residuals 10. Gradient Boosting
    3. Find the optimal coefficient 10. Gradient Boosting for 10. Gradient Boosting with respect to the original loss function
      10. Gradient Boosting
    4. Save 10. Gradient Boosting
    5. Update the current approximation 10. Gradient Boosting
      10. Gradient Boosting
  3. Assemble the final GBM model 10. Gradient Boosting
    10. Gradient Boosting
  4. Conquer Kaggle and the world with the trained model (making predictions with it is up to you to figure out)

Step-by-step example of GBM at work

Let's try to figure out how GBM works using a toy example. We'll use it to recover a noisy function 10. Gradient Boosting.

10. Gradient Boosting

This is a regression problem on a real-valued target variable, so we'll use the mean squared error loss function. We'll generate 300 pairs of observations, and we'll approximate with decision trees of depth 2. Let's put together everything we need to apply GBM:

  • Toy data 10. Gradient Boosting
  • Number of iterations 10. Gradient Boosting ✓;
  • Mean squared error loss function 10. Gradient Boosting
    The gradient 10. Gradient Boosting of the loss is simply the residuals 10. Gradient Boosting ✓;
  • Decision trees as base algorithms 10. Gradient Boosting ✓;
  • Decision tree hyperparameters: tree depth equals 2 ✓;

For the mean squared error, everything is simple, both for the initialization 10. Gradient Boosting and for the coefficients 10. Gradient Boosting. Namely, we'll initialize GBM with the mean value 10. Gradient Boosting, and all 10. Gradient Boosting equal 1.

Let's run GBM and plot two types of charts: the actual approximation 10. Gradient Boosting (blue chart), and each tree we build 10. Gradient Boosting on its pseudo-residuals (green chart). The chart number corresponds to the iteration number:

10. Gradient Boosting

Notice that by the second iteration our trees had reproduced the main shape of the function. However, at the first iteration we can see that the algorithm only built the "left branch" of the function (10. Gradient Boosting). This simply happened because our trees didn't have enough depth to build the symmetric branch right away, and the error on the left branch was larger. So the right branch "grew in" only at the second iteration.

Otherwise, the process went exactly as we expected: at each step our pseudo-residuals decreased, and GBM approximated the original cosine more and more closely. However, trees, by their construction, cannot approximate a continuous function, so in this example GBM is useful but not perfect. To play around with how GBM approximates functions yourself, the Brilliantly wrong blog has an awesome interactive demo:

10. Gradient Boosting

http://arogozhnikov.github.io/2016/06/24/gradient_boosting_explained.html

3. Loss functions

What should we do if we want to solve not ordinary mean-squared regression, but, say, a binary classification task? No problem — we just need to choose, for the target variable 10. Gradient Boosting, a loss function 10. Gradient Boosting appropriate to the task. This is the most important high-level decision, which determines exactly what we will be optimizing and what properties to expect from our final model.

As a rule, we don't need to come up with or derive anything ourselves — researchers have already done it all for us. Today we'll go through the loss functions for the two most commonly encountered tasks: regression 10. Gradient Boosting and binary classification 10. Gradient Boosting. What to do about multiclass classification, ranking, and various intermediate cases like integer regression, we'll cover another time.

Regression loss functions

Let's start with regression 10. Gradient Boosting. When choosing a loss function in this case, we are first of all deciding exactly which property of the conditional distribution 10. Gradient Boosting we want to recover. The most common options are:

  • 10. Gradient Boosting, also known as 10. Gradient Boosting loss, also known as Gaussian loss. This is the classic conditional mean, the most common and simplest option. If there is no additional information or robustness requirements for the model — use this one.
  • 10. Gradient Boosting, also known as 10. Gradient Boosting loss, also known as Laplacian loss. This, at first glance, not-very-differentiable thing, actually defines the conditional median. The median, as we know, is more robust to outliers, so in some tasks this loss function is preferable, since it penalizes large deviations much less harshly than the quadratic function.
  • $inline$ \large \begin{equation} L(y, f) =\left\{ \begin{array}{@{}ll@{}} (1 - \alpha) \cdot |y - f|, & \text{if}\ y-f \leq 0 \\ \alpha \cdot |y - f|, & \text{if}\ y-f >0 \end{array}\right. \end{equation}, \alpha \in (0,1) $inline$, also known as 10. Gradient Boosting loss, also known as Quantile loss. If, say, we wanted not the conditional median with 10. Gradient Boosting, but the conditional 75% quantile, we would use this variant with 10. Gradient Boosting. You can see that this function is asymmetric and penalizes observations on the side of the quantile we need more heavily.


10. Gradient Boosting

Let's try using the 10. Gradient Boosting loss function on our toy data, trying to recover the conditional 75% quantile of the cosine. Let's put it all together:

  • Toy data 10. Gradient Boosting
  • Number of iterations 10. Gradient Boosting ✓;
  • Quantile loss function $inline$ \large \begin{equation} L_{0.75}(y, f) =\left\{ \begin{array}{@{}ll@{}} 0.25 \cdot |y - f|, & \text{if}\ y-f \leq 0 \\ 0.75 \cdot |y - f|, & \text{if}\ y-f >0 \end{array}\right. \end{equation} $inline$ ✓;
  • Gradient 10. Gradient Boosting — an indicator function, weighted by our 10. Gradient Boosting. We will be training trees on something very similar to a classifier:
    10. Gradient Boosting
    10. Gradient Boosting ✓;
  • Decision trees as the base algorithms 10. Gradient Boosting ✓;
  • Hyperparameters of the decision trees: tree depth equals 2 ✓;

We have an obvious initial approximation — simply take the quantile we need 10. Gradient Boosting. However, we know nothing about the optimal coefficients 10. Gradient Boosting, so we'll use a standard line search. Let's see what we got:

10. Gradient Boosting

It's unusual to see that in fact we are training on something very unlike ordinary residuals — at each iteration 10. Gradient Boosting take only two possible values. However, the result of GBM's work is quite similar to our original function.

If we let the algorithm keep training on this toy example, we get almost the same result as with the quadratic loss function, shifted by 10. Gradient Boosting. But if we were looking for quantiles above 90%, computational difficulties could arise. Namely, if the ratio of the number of points above the desired quantile is too small (like imbalanced classes), the model won't be able to train well. It's worth thinking about such nuances when solving atypical tasks.

A bit more about regression loss functions

Quite a lot of loss functions have been developed for the regression task, including ones with additional robustness properties. One such example is the Huber loss function. The essence of this function is that for small deviations it behaves like 10. Gradient Boosting, and starting from a preset threshold, it starts behaving like 10. Gradient Boosting. This makes it possible to reduce the contribution of outliers and the quadratically large errors that follow from them on the overall shape of the function, without focusing too much attention on small inaccuracies and deviations.

We can look at how this loss function works on the following toy example. As a base we'll take toy data for the function 10. Gradient Boosting, to which special noise has been added: a mixture of a Gaussian distribution and a Bernoulli distribution, acting as a one-sided outlier generator. The loss functions themselves are shown in charts A-D, and the corresponding GBMs are shown in charts F-H (chart E shows the original function):

10. Gradient Boosting

And in high resolution.

In this example, splines were used as the base algorithms for visual clarity. After all, we already mentioned that you can boost more than just trees, right?

Based on the results of the example, due to the artificially created noise problem, the difference between 10. Gradient Boosting, 10. Gradient Boosting and Huber loss is quite noticeable. With a well-chosen Huber loss parameter, we can even get the best approximation of the function among our options. This example also clearly shows the difference in the conditional quantiles (10%, 50%, and 90% in our case).

Unfortunately, the Huber loss function is not implemented in all modern libraries (it's implemented in h2o, but not yet in xgboost). The same applies to other interesting loss functions, including conditional quantiles and such exotic things as conditional expectiles. But in general, it's quite useful to know that such options exist and can be used.

Classification loss functions

Now let's look at binary classification, where 10. Gradient Boosting. We've already seen that GBM can be used to optimize even not-very-differentiable loss functions. In fact, one could, without thinking too much, try to solve this case as just another regression task with some 10. Gradient Boostingloss, but that wouldn't be quite right (although it's possible).

Because of the fundamentally different nature of the target variable's distribution, we will predict and optimize not the class labels themselves, but their log-likelihood. To do this, we reformulate the loss functions over the product of the predictions and the true labels 10. Gradient Boosting (it's no accident that we chose labels of different signs). The best-known variants of such classification loss functions are:

  • 10. Gradient Boosting, also known as Logistic loss, also known as Bernoulli loss. An interesting property is that we penalize even correctly predicted class labels. No, that's not a bug. On the contrary, by optimizing this loss function we can keep "pushing apart" the classes and improving the classifier even when all observations are predicted correctly. This is the most standard and frequently used loss function in binary classification.
  • 10. Gradient Boosting, also known as Adaboost loss. As it turns out, the classic Adaboost algorithm is equivalent to GBM with this loss function. Conceptually, this loss function is very similar to Logistic loss, but has a harsher exponential penalty for classification errors and is used less often.


10. Gradient Boosting

Let's generate new toy data for the classification task. As a base, we'll take our noisy cosine, and use the sign function for the target variable's classes. The new data looks as follows (jitter noise has been added for clarity):


10. Gradient Boosting

Let's use Logistic loss to see what we're actually boosting. As before, let's put together what we'll be solving:

  • Toy data 10. Gradient Boosting
  • Number of iterations 10. Gradient Boosting ✓;
  • As the loss function — Logistic loss, its gradient is computed as follows:
    10. Gradient Boosting ✓;
  • Decision trees as the base algorithms 10. Gradient Boosting ✓;
  • Hyperparameters of the decision trees: tree depth equals 2 ✓;

This time the algorithm's initialization is a bit more complicated. First, our classes are imbalanced and split roughly 63% to 37%. Second, no analytical formula for initialization is known for our loss function. So we'll search for 10. Gradient Boosting using a search:


10. Gradient Boosting

The optimal initial approximation was found to be around -0.273. One could have guessed that it would be negative (it's more advantageous for us to predict everyone as the most popular class), but as we already said, there's no formula for the exact value. Now let's finally run GBM and see what's actually happening under the hood:

10. Gradient Boosting

The algorithm worked successfully, recovering the separation of our classes. You can see how the "lower" regions are separated, where the trees are more confident about correctly predicting the negative class, and how two steps form, where the classes were mixed. In the pseudo-residuals, you can see that we have quite a lot of correctly classified observations, and some number of observations with large errors that appeared due to noise in the data. This is roughly what GBM is actually predicting in the classification task (regression on the pseudo-residuals of the logistic loss function).

Weights

Sometimes a situation arises where we want to come up with a more task-specific loss function. For example, when predicting financial time series we might want to give more weight to large movements of the time series, and in the customer churn prediction task — we'd rather better predict churn for customers with a high LTV (lifetime value, how much money a customer will bring us in the future).

10. Gradient Boosting

The true path of the statistical warrior — come up with your own loss function, derive its derivative (and, for more efficient training, its Hessian too), and carefully check whether this function satisfies the required properties. However, there's a high chance of making a mistake somewhere, running into computational difficulties, and overall spending an unreasonable amount of time on research.

Instead, a very simple tool was invented that is rarely remembered in practice — weighting observations and defining weight functions. The simplest example of such weighting is setting weights to balance classes. In the general case, if we know that some subset of the data, whether in the input variables 10. Gradient Boosting or in the target variable 10. Gradient Boosting, has greater importance for our model, we simply assign it a larger weight 10. Gradient Boosting. The main thing is to satisfy the general reasonableness requirements for the weights:

10. Gradient Boosting

Weights make it possible to significantly cut down the time spent adapting the loss function itself to the task at hand, and also encourage experimentation with the target properties of models. Exactly how to set these weights is purely our own creative task. From the point of view of the GBM algorithm and the optimization, we simply add scalar weights, turning a blind eye to their nature:

10. Gradient Boosting

It's clear that for arbitrary weights we don't know any nice statistical properties of our model. In general, by tying the weights to the values 10. Gradient Boosting, we can shoot ourselves in the foot. For example, using weights proportional to 10. Gradient Boosting in the 10. Gradient Boosting loss function is not equivalent to 10. Gradient Boostingloss, since the gradient won't take into account the values of the predictions themselves 10. Gradient Boosting.

We're discussing all this to better understand our capabilities. Let's come up with some very exotic example of weights on our toy data. Let's define a strongly asymmetric weight function as follows:

$$display$$ \large \begin{equation} w(x) =\left\{ \begin{array}{@{}ll@{}} 0.1, & \text{if}\ x \leq 0 \\ 0.1 + |cos(x)|, & \text{if}\ x >0 \end{array}\right. \end{equation} $$display$$

10. Gradient Boosting

With these weights we expect to see two properties: less detail at negative values 10. Gradient Boosting, and a function shape that more closely resembles the original cosine. We take all other GBM settings from our previous classification example, including the line search for the optimal coefficients. Let's see what we got:

10. Gradient Boosting

The result turned out just as we expected. First, we can see how much our pseudo-residuals started to differ, largely repeating our original cosine at the initial iteration. Second, the left part of the function's graph was largely ignored in favor of the right part, which had larger weights. Third, the function we obtained at the third iteration gained quite a lot of detail, becoming more similar to the original cosine (while also starting to slightly overfit).

Weights are a powerful tool that, at our own risk, allow us to significantly control the properties of our model. If you want to optimize your own loss function, it's worth first trying to solve a simpler task, but adding observation weights to it as you see fit.

4. Summary on GBM theory

Today we went through the main theory of gradient boosting. GBM is not just some specific algorithm, but a general methodology for building ensembles of models. Moreover, the methodology is quite flexible and extensible: you can train a large number of models taking into account various loss functions, while also hanging various kinds of weight functions on them.

As both practice and experience from machine learning competitions show, in standard tasks (everything except images and audio, as well as heavily sparse data), GBM is very often the most effective algorithm (not counting stacking and top-level ensembles, where GBM is almost always an integral part of them). There are also adaptations of GBM for Reinforcement Learning (Minecraft, ICML 2016), and the Viola-Jones algorithm, still used in computer vision today, is based on Adaboost.

In this article, we deliberately left out the questions related to GBM regularization, stochasticity, and the algorithm hyperparameters associated with them. It is not by chance that we chose a small number of algorithm iterations everywhere, 10. Gradient Boosting. If we had chosen not 3 but 30 trees and run GBM as described above, the result would have turned out less predictable:

10. Gradient Boosting

We will tell you about what to do in such situations, and how the GBM regularization parameters are related to each other, as well as the hyperparameters of the base algorithms, in the next article. In it we will also cover modern packages — xgboost, lightgbm and h2o, and practice tuning them correctly. In the meantime, we suggest you play around with the GBM settings in yet another very cool interactive demo, Brliiantly wrong:

10. Gradient Boosting

http://arogozhnikov.github.io/2016/07/05/gradient_boosting_playground.html

5. Homework

Current homework assignments are announced during the next session of the course; you can follow them in the VK group and in the course repository.

As an exercise, complete this assignment — you need to beat a simple baseline in the Kaggle Inclass competition on predicting flight delays.

6. Useful links

  • Open Machine Learning Course. Topic 10. Gradient Boosting
  • Video recording of the lecture based on this article
  • Original article on GBM by Jerome Friedman
  • Chapter in Elements of Statistical Learning by Hastie, Tibshirani, Friedman (p. 337)
  • Wiki article on Gradient Boosting
  • Frontiers tutorial article on GBM (a bit of light self-promotion)
  • Video lecture by Hastie on GBM at the h2o.ai conference
  • Video lecture by Vladimir Gulin on algorithm compositions from Tekhnosfera
  • Video lectures by Konstantin Vorontsov (part 1, part 2) on algorithm compositions from the School of Data Analysis

Comments

To leave a comment

If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Lectures and tutorial on "Machine learning"

Terms: Machine learning