.. _weighted_event_probabilistic:

# Weighted event-based probabilistic models

## Background

A weighted event-based model in RiskScape is when each event in the dataset
has a specific probability or rate of occurrence associated with it.
As opposed to an :ref:`event-based model <event_based_probabilistic>`, where
each event has an equal-probability within the model itself.

A weighted event-based model allows a smaller dataset to be used
when very rare events need to be included in the dataset. Whereas an event-based approach
might require billions of events in order to include very rare events in the model.

Each event in the weighted event-based dataset has a _rate_ associated with it.
This is the rate at which this event occurs over the defined time period (usually annually).
For example, a rate of `0.1` for a time period of one year would mean, on average, an event like this is likely to occur every ten years.

### Model parameters

The pipeline examples on this page will assume your model defines the following parameter:
- `$loss_levels`: the loss-levels you are interested in for reporting the Annual Exceedance Probability.

An example `project.ini` definition might look like the following.
Here the default values for the parameters match our examples.

```ini

[model event-based]
framework = pipeline
location = pipeline.txt
# we are interested in whether any given event exceeds the following loss bands or not 
param.loss_levels = [100, 250, 500, 750, 1000]
```

## Event loss table

Refer to :ref:`probabilistic_event_loss` for how to produce a total loss for each event,
based on the hazard data you are using.

.. note::
    You need to ensure the annual occurrence rate for each event is included in the event-loss results.
    Here we have assumed this attribute is called ``occurrence_rate``.

For example, the `group` step that you use to produce your event-loss table might look like this:

```none
# Aggregate the losses by event to get a total loss per event.
group(
    by: event,
    select: {
      event.id as eventid,
      sum(loss) as total_loss,
      event.rate as occurrence_rate
}) as event_loss_table
```

## Annualized Average Loss

To calculate the Annualized Average Loss (AAL) from weighted event-based data, the example pipeline on this page uses the formula:

.. math::
   μ = \sum_{e=1}^{N}(Rate_\text{e})(Loss_\text{e})

Calculating the standard deviation uses the formula:

.. math::
   σ = \sqrt{\sum_{e=1}^{N}(Rate_\text{e})(Loss_\text{e})^2}

This is based on the model calculating :math:`Loss_\text{e}` as the _average_ loss if the event occurs.

.. note::
    This page is intended as a demonstrative example pipeline for a weighted event-based model.
    It is *not* intended to be an definitive guide to mathematical practices for risk analysis.
    We recommend that you use an AAL calculation that is appropriate for the specific scenario you are modelling.

### Worked example

Given this event loss table:

| event | occurrence rate | loss  |
| ----- | ----------------| ----- |
| 1     | 0.01            | $1100 |
| 2     | 0.035           | $500  |
| 3     | 0.04            | $600  |
| 4     | 0.1             | $200  |
| 5     | 0.05            | $800  |

To calculate the AAL we sum `rate x loss`, which gives us an AAL of $112.50.

| event | occurrence rate | loss  | rate x loss |
| ----- | --------------- | ----- |-------------|
| 1     | 0.01            | $1100 | $11.0       |
| 2     | 0.035           | $500  | $17.5       |
| 3     | 0.04            | $600  | $24.0       |
| 4     | 0.1             | $200  | $20.0       |
| 5     | 0.05            | $800  | $40.0       |
| Total | 0.235           | $3200 | $112.50     |

You will notice that the AAL is lower than the loss from any individual event, but this is because it is _annualized_.
For example, the event with the highest loss ($1100) is likely to occur every hundred years,
so averaging it over that period gives us an $11 annual loss from that specific event.

To calculate the standard deviation we use `rate x loss²`.
Summing this gives us $71250.
Taking the square root of that then gives us a standard deviation of $266.93.

| event | occurrence rate | loss  | rate x loss²  |
| ----- | --------------- | ----- |---------------|
| 1     | 0.01            | $1100 | 12100         |
| 2     | 0.035           | $500  | 8750          |
| 3     | 0.04            | $600  | 14400         |
| 4     | 0.1             | $200  | 4000          |
| 5     | 0.05            | $800  | 32000         |
| Total |                 |       | 71250         |

### Pipeline

The following pipeline code will apply the above weighted event-based AAL calculations to
the probabilistic model results.

```none
event_loss_table
  ->
group(
    select: {
        sum(total_loss * occurrence_rate) as AAL_mean,
        square_root(
            sum(
                pow(total_loss, 2) * occurrence_rate
            )
        ) as AAL_stddev
    })
  ->
save('average-loss', format: 'csv')
```

.. _weighted_event_AEP:

## Annual Exceedance Probability

Each event in the results already has an annual rate associated with it, which
we can use to calculate the rate of exceedance of any given loss level.

### Worked example

Given this event loss table:

| event | occurrence rate    | loss  |
| ----- | ------------------ | ----- |
| 1     | 0.01               | $1100 |
| 2     | 0.035              | $500  |
| 3     | 0.04               | $600  |
| 4     | 0.1                | $200  |
| 5     | 0.05               | $800  |

We then sum the occurrence rate for each event that exceeds a given loss level, which gives us the total rate of exceedance.
Applying this to our example event loss table gives us:

| loss level  | rate of exceedance           |
| ----------- | ---------------------------- |
| 100         | 0.235                        |
| 250         | 0.135                        |
| 500         | 0.1                          |
| 750         | 0.06                         |
| 1000        | 0.01                         |

We can then use the rate of exceedance to calculate the Annual Exceedance Probability (AEP) with `1 - exp(-λ * T)`.

| loss level  | rate of exceedance | calculation           | AEP   |
| ----------- | -------------------|-----------------------|-------|
| 100         | 0.235              | `1 - exp(-0.235 * 1)` | 0.209 |
| 250         | 0.135              | `1 - exp(-0.135 * 1)` | 0.126 |
| 500         | 0.1                | `1 - exp(-0.1 * 1)`   | 0.095 |
| 750         | 0.06               | `1 - exp(-0.06 * 1)`  | 0.058 |
| 1000        | 0.01               | `1 - exp(-0.01 * 1)`  | 0.01  |

A return period, or Average Recurrence Interval (ARI), can also be calculated from the rate.

| loss level  | rate of exceedance | calculation | ARI   |
| ----------- | -------------------|-------------|-------|
| 100         | 0.235              | `1 / 0.235` | 4.26  |
| 250         | 0.135              | `1 / 0.135` | 7.41  |
| 500         | 0.1                | `1 / 0.1`   | 10.0  |
| 750         | 0.06               | `1 / 0.06`  | 16.67 |
| 1000        | 0.01               | `1 / 0.01`  | 100.0 |

### Pipeline

The following pipeline code will produce an AEP table for a weighted event-based probabilistic model.

First, we match every loss-level we are interested in to every event-loss result.

We then _sum_ the occurrence rates for each event that exceeds a given loss-level.
This gives us the total rate of exceedance for that particular loss level.

We then use the `rate_of_exceedance` to calculate the AEP and return period.

```none
event_loss_table
  ->
select({*, $loss_levels as loss_level})
  ->
unnest('loss_level')
  ->
group(
    by: loss_level,
    select: {
      loss_level,
      count(total_loss >= loss_level) as count,
      sum(if(total_loss >= loss_level, occurrence_rate, 0.0)) as rate_of_exceedance,
   })
  ->
# convert the rate of exceedance to a probability */
select({*,
        annual_exceedance_probability: 1 - exp((0.0 - rate_of_exceedance) * 1),
        return_period: 1 / rate_of_exceedance
     })
  ->
sort('loss_level')
  ->
save('exceedance-table', format: 'csv')
```

