Tail events, why they matter and how to model them | by Conor Mc. | Towards Data Science

How to model the unexpected and unlikely the Bayesian way.
Rare events are by definition, well, rare. But, inevitably they do happen and when they do they have outsized consequences. 9/11 was a tail event. The financial crisis of 2007/08 was a tail event. Coronavirus was a tail event. Many of the every day products you use, services you engage with and companies you work for are tail events. So, yes, tail events are rare but when they happen their impact is huge.
Predicting a tail event or extreme value is intrinsically hard. In fact, one of the most challenging problems I have worked on as a data scientist involved estimating the likelihood of extreme values across business critical systems. Whilst predicting rare events with precision is virtually impossible, estimating their probability is possible, but it requires a departure from business as usual modelling. Specifically, it requires using modelling approaches that allow for the possibility of values or events that lie significantly beyond the conditional mean.
Principled approaches to estimating the probability of rare events can help inform decision making, risk adjustments and countermeasures. Whilst there are many ways to approach these problems, in my experience, the approach that is most interpretable, robust and pragmatic is the Bayesian approach. In this post, I’ll provide a worked example of tail events and how a Bayesian model can be used to estimate their probability.
Extreme value theory (EVT) is a branch of statistics that deals with values that significantly deviate from the central tendency of a probability distribution. It’s worth noting that an extreme value problem differs fundamentally from rare event prediction problems. For example, fraud detection is a type of rare event classification problem but this is not an extreme value problem. Why? Because a rare event such as fraud is rare, but predictable, whereas the type of extreme values that EVT is concerned with are typically difficult to predict.
The ultimate aim of EVT is to estimate the probability of an extreme value occurring. This has many use cases, particularly across natural sciences (e.g. extreme weather events such as earthquakes and Tsunamis), but also across many applied problems in economics, finance and engineering.
An extreme value can be extremely low or high. The direction of the value doesn’t really matter. What does matter is the statistical distributions that are used to estimate their likelihood. These distributions are collectively referred to as extreme value distributions. There are many extreme value distributions, but the one that I find most straightforward and useful in practice is the Gumbel distribution.
The Gumbel distribution is similar to a Normal distribution in that it is defined solely by two parameters — location and scale. But, unlike the Normal distribution it is asymmetric. This means that the tail of the distribution can skew in the direction of the extreme values. In practice this means that the Gumbel distribution assigns greater likelihood to more extreme events (i.e. events or values in the tail of the distribution) than the Normal distribution. You can see this in the plot below.
np.random.seed(123)n = 100000fs = {"fontsize" : 16}plt.figure(figsize=(20, 12))sns.kdeplot(stats.distributions.gumbel_r().rvs(n), label="Gumbel") sns.kdeplot(stats.distributions.norm().rvs(n), label="Normal")plt.legend(**fs)plt.xticks(**fs)plt.yticks(**fs)plt.ylabel("Density", **fs)plt.xlabel("X", **fs);
To demonstrate EVT in practice I’ll use this data set on wind speeds which includes extreme values. The data is plotted below. You can a strong seasonal pattern in this data, but also periodic values that fall significantly outside of the normal range. The first thing that we need to do is to isolate these values. To do so, we can use the block maxima approach. This method simply extracts the maximum value of the data across a range (i.e. a block). In this case we’ll extract the maximum value for each month in the data. These points are marked by the red dots in the plot.
block_maxima_month = (    df    .set_index("date")    .resample("M")    .max()    .wind_speed    .reset_index()    .query("wind_speed > 5"))fs = {"fontsize" : 16}plt.figure(figsize=(24, 10))plt.scatter(df.date, df.wind_speed, alpha=.3)plt.plot(df.date, df.wind_speed, alpha=.7, c="b")plt.scatter(block_maxima_month.date, block_maxima_month.wind_speed, c="red", s=80)plt.xticks(**fs)plt.yticks(**fs)plt.ylabel("Wind speed", **fs)plt.xlabel("Date", **fs);
The next step is to fit a distribution to the block maxima values (shown in he plot below). To do so I’ll fit a simple Bayesian model to the distribution using PyMC3. For illustration purposes I’ll fit both a Normal and Gumbel distribution to the data.
The code below fits the distributions to the block maxima values. In both cases I use the same priors.
The trace plots display the fit for the Gumbel (top) and Normal distribution (bottom). In both cases the distributions reliably fit the data as indicated by the consistent exploration across each parameter. It is interesting to compare both distributions given that they are defined by the same two parameters, yet have each estimated different parameter values. Let’s see how well each distribution fits the actual distribution of the extreme values.
For each model we first need to sample from the posterior distribution. This essentially involves drawing independent samples from the distribution that is defined by the estimated location and scale parameters. Once, we have the posterior distributions we can compare their fit to the actual data.
# Extract posterior distributionsev_post = pm.sample_posterior_predictive(ev_trace, model=ev_model)["lik"].Tnorm_post = pm.sample_posterior_predictive(norm_trace, model=norm_model)["lik"].T# Plot density plt.figure(figsize=(20, 10))pm.plot_dist(ev_post, label="Gumbel", textsize=20, hist_kwargs=fs)pm.plot_dist(norm_post, label="Normal", textsize=20, )sns.kdeplot(block_maxima_month.wind_speed, label="Actual")plt.legend(fontsize=14)
The plot above shows the fitted Gumbel and Normal distributions alongside the actual distribution of the data. You can see that whilst the Normal distribution does a reasonable job in fitting the data, it does not follow the distribution as well as the Gumbel. For example, you can see that the Normal distribution misses the location of the actual distribution by quite a bit and also has a lighter tail. The Gumbel by comparison appears to fit the actual data much better. It’s also worth noting the long tail of the Gumbel distribution — the Gumbel does not discount the possibility of even more extreme events beyond what was observed in the data. This is exactly why we use these distributions!
Now that we have the distributions, one thing that we might like to do is to estimate the probability of an extreme value being exceeded. This is often a very useful and important thing to quantify in practice. To do this we can use the posterior distribution of the Gumbel. The question is; What is the probability that we will see a value that exceeds a specified threshold?
The code above simple iterates over specified values and uses the posterior Gumbel distribution to estimate the probability of seeing a greater value. These exceedance probabilities are plotted below. For example, there is around a 0.38 probability that wind speed will exceed 20.
Extreme value prediction is an interesting, but challenging problem. This post shows a general approach that you can use to get started on these problems, but this can get much more sophisticated. Also, in this post, I haven’t conditioned the likelihood of an extreme value on any covariate. One interesting extension of this analysis would be to see if there is any value in including additional covariates in the model (e.g. the previous day or week’s wind speed or other weather patterns such as humidity). The most important takeaway is the use of extreme value distributions, such as the Gumbel. When the likelihood of a value or event falls significantly beyond the conditional mean of the distribution then you need an approach that allows for the plausibility of tail events.
Thanks for reading!
P.S. All code for this post can be found here.