Block bootstrapping time series data

The usual bootstrapping method doesn't preserve the ordering of time series data, and it is, therefore, unsuitable for trend estimation. In the block bootstrapping approach, we split data into non-overlapping blocks of equal size and use those blocks to generate new samples. In this recipe, we will apply a very naive and easy-to-implement linear model with annual temperature data. The procedure for this recipe is as follows:

  1. Split the data into blocks and generate new data samples.
  2. Fit the data to a line or calculate the first differences of the new data.
  3. Repeat the previous step to build a list of slopes or medians of the first differences.

How to do it...

  1. The imports are as follows:
    import dautil as dl
    import random
    import matplotlib.pyplot as plt
    import pandas as pd
    import numpy as np
    import seaborn as sns
    import ch6util
    from IPython.display import HTML
  2. Define the following function to bootstrap the data:
    def shuffle(temp, blocks):
        random.shuffle(blocks)
        df = pd.DataFrame({'TEMP': dl.collect.flatten(blocks)},
                          index=temp.index)
        df = df.resample('A')
    
        return df
  3. Load the data and create blocks from it:
    temp = dl.data.Weather.load()['TEMP'].resample('M').dropna()
    blocks = list(dl.collect.chunk(temp.values, 100))
    random.seed(12033)
  4. Plot a couple of random realizations as a sanity check:
    sp = dl.plotting.Subplotter(2, 2, context)
    cp = dl.plotting.CyclePlotter(sp.ax)
    medians = []
    slopes = []
    
    for i in range(240):
        df = shuffle(temp, blocks)
        slopes.append(ch6util.fit(df))
        medians.append(ch6util.diff_median(df))
        
        if i < 5:
            cp.plot(df.index, df.values)
            
    sp.label(ylabel_params=dl.data.Weather.get_header('TEMP'))
  5. Plot the distribution of the first difference medians using the bootstrapped data:
    sns.distplot(medians, ax=sp.next_ax(), norm_hist=True)
    sp.label()
  6. Plot the distribution of the linear regression slopes using the bootstrapped data:
    sns.distplot(slopes, ax=sp.next_ax(), norm_hist=True)
    sp.label()
  7. Plot the confidence intervals for a varying number of bootstraps:
    mins = []
    tops = []
    xrng = range(30, len(medians))
    
    for i in xrng:
        min, max = dl.stats.outliers(medians[:i])
        mins.append(min)
        tops.append(max)
    
    cp = dl.plotting.CyclePlotter(sp.next_ax())
    cp.plot(xrng, mins, label='5 %')
    cp.plot(xrng, tops, label='95 %')
    sp.label()
    HTML(sp.exit())

Refer to the following screenshot for the end result:

How to do it...

The following code comes from the block_boot.ipynb file in this book's code bundle.

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset