Part II — Predictive analytics · Chapter 2

Time series, decomposition and the empirical STL

~38 min read6 interactive widgets

In this chapter

  1. Predictive analytics: forecast now, decide now
  2. Horizons, and what a forecast actually is
  3. A taxonomy of prediction models
  4. Time series: definition, examples, plots
  5. Univariate, multivariate, exogenous — statistics or machine learning
  6. Regression, prediction, forecast: residuals and forecast errors
  7. Decomposition: trend, season, cycle, noise, accident
  8. The empirical STL, step by step on the fil rouge
  9. Correlograms and finding the period
  10. Seasonal coefficients, deseasoning and the projected forecast
  11. Sampling: train, test, and why k-fold does not apply
  12. Check your understanding

1. Predictive analytics: forecast now, decide now

The deck opens with a compact definition: predictive analytics is an area of statistics that deals with extracting information from data and using it to predict trends and behavior patterns. And then the mechanism: its core relies on capturing relationships between explanatory variables and the predicted variables from past occurrences, and exploiting them to predict the unknown outcome.

The slides then split the name in two, and the split is the whole justification of the discipline:

Half of the nameWhat it commits you to
PredictiveThe primary objective is the prediction of future events on the basis of data — time series or other — available now.
AnalyticsForecasts are used to take decisions now.

A forecast nobody acts on is a hobby. The management examples given are all decisions with a lead time attached: forecast of goods or services demand; forecast of workforce availability or need; forecast of material requirements and warehouse availabilities; forecast of revenues, profits and losses in order to define future investments.

2. Horizons, and what a forecast actually is

Different decisions need different distances into the future, and the slides organise them into three bands. The band you are in determines both the model and the tolerance for error.

Resource requirements · workforce shifts · retail sales.

These are the operational decisions of chapter 1: the ones taken again tomorrow. Data is plentiful relative to the horizon, and the series structure (seasonality, day-of-week effects) usually carries most of the signal.

Sales by product category · workforce needs · resource requirements.

The tactical band. Note that resource requirements and workforce appear both here and in the short band: the same quantity is forecast at different granularities for different decisions.

Growth trends · storage needs · sales patterns, market trends.

Here the trend component dominates and the seasonal detail matters less. It is also the band where the occasional component of section 7 — wars, technological breakthroughs, political crises — can invalidate a model outright.

Four attributes of any forecast

The slides state four properties that a student is expected to repeat without hesitation, starting with the least flattering one.

AttributeConsequence
Forecasts are usually wrong.Design the decision so that being wrong is survivable, not so that being right is required.
Forecasts are usually not just numbers.They include mean and dispersion measures, and they include a confidence interval. A bare point forecast has thrown away half of the output.
Aggregate forecasts are more reliable than detail ones.Total sales of a category are easier to predict than the sales of one SKU in one store.
Reliability decreases with distance in the future.The prediction interval widens with the horizon — chapter 4 shows how to estimate it when the library does not give it to you.
For the exam

"Forecasts are usually wrong" plus "forecasts include a confidence interval" are one statement, not two. The correct output of a forecasting model is a distribution, summarised by a mean, a dispersion and an interval, and the interval must widen with the horizon.

3. A taxonomy of prediction models

The deck lays out the space of forecasting methods as a tree with two big branches — objective and subjective — and it is worth keeping the subjective branch in mind, because the rest of the course lives entirely on the objective one.

Taxonomy of forecasting models: forecasts split into objective (causal econometric models and time series, themselves stationary or trended) and subjective (expert judgement, Delphi, market research). FORECASTS OBJECTIVE SUBJECTIVE causal models time series econometric stationary trend expert judgement Delphi market research chapters 2-7 of this site live entirely inside the “time series” box
Plate 2.1 — The model taxonomy from the slides. The subjective branch is not a joke: Delphi and sales-force composites are how many organisations actually forecast when there is no history to fit.

Subjective models

Very varied. The slides list: sales force composite (aggregation of estimates made by sales agents); polls among customers; opinions of managers; and Delphi — ask the question, gather individual opinions, share the opinions anonymously, re-ask the question, repeat the procedure until consensus. The anonymity is the mechanism: it is what stops the loudest voice from anchoring the room.

Objective models and their three phases

Objective models are based on mathematical models, and the slides break the workflow into three high-level phases which recur in every later chapter, under different names.

PhaseAlso calledWhat it does
Model specificationidentificationThe choice of the forecast technique to use.
Model fittingparameter settingGiven the model, sets its parameters to maximise the coherence of forecasts with actual data.
Model diagnosisvalidationDetermines the level of coherence between actual and forecast data.
Editor's note

These three phases are exactly the Box-Jenkins methodology you will meet in chapter 4 (identification, parameter estimation, model checking), and exactly the neural modelling process of chapter 5 (architecture choice, training, validation). Recognising the same three-step skeleton under three vocabularies is most of what "knowing the field" means here.

4. Time series: definition, examples, plots

A time series is simply a set of time-indexed values, and it represents the dynamics of a process over time. In the model, we assume to have n observations coming from as many dependent random variables. And the objective of studying them is stated with disarming honesty: to find patterns in past data which can be assumed to repeat in the future. The assumption is doing all the work; when it breaks, so does the forecast.

A time-series plot (timeplot, time series graph) is a bidimensional chart of the series: the vertical axis is the variable of interest, the horizontal axis the time units.

Series are everywhere

OrganizationSeries
Sales agentDaily, weekly, monthly sales
Manufacturing companyMonthly labor costs (hours or euros)
Manufacturing companyTrimestral sales (units or euros)
Local governmentFiscal income (monthly)
Local governmentWeekly building permits
ParishAttendance at masses, weekly
UniversityNumber of students enrolled (absolute, percent)
BankLoans granted, weekly (number, euro)
Agricultural companyProduction per hectare, yearly
HospitalMan-days of hospitalization, monthly
FamilyTelephone costs, bimestrial

The three series this course keeps coming back to

SeriesWhat it isFile
THE time seriesInternational airline passengers, monthly totals in thousands, Jan 49 – Dec 60 (G.E.P. Box, G.M. Jenkins, 1976). The canonical trended, multiplicatively seasonal series.BoxJenkins.csv
Jewelry salesJewelry market sales, USA, millions of dollars.gioiellerie.csv
Fil rougeDaily TV sales, 20 quarters from 2004 to 2008. Twenty points is deliberately too few, which is why every method can be traced by hand on it.FilRouge.csv
df = pd.read_csv("BoxJenkins.csv")
plt.plot(df.Passengers, label="passengers")
plt.legend()

df = pd.read_csv("FilRouge.csv")
plt.plot(df.sales, label="TV sales")
plt.grid(); plt.legend(); plt.show()

The fil rouge itself, quarter by quarter, is worth having in front of you for the rest of the chapter:

t12345678910
sales12818187219407226214383505387
t11121314151617181920
sales278523572354404673752468419725
Careful

The slides point at Tyler Vigen's spurious correlations when introducing the timeplot. Two series can track each other beautifully for a decade with no causal relation whatsoever. Correlation between series is a hypothesis generator, never evidence.

5. Univariate, multivariate, exogenous — statistics or machine learning

Forecasting a time series means predicting the values it is going to take in the future. The slides distinguish three settings, and the third is the one most real problems fall into.

SettingInputsWhere it appears later
UnivariateOnly the previous values of the series itself.AR, MA, ARIMA, SES, HW (ch. 4)
MultivariatePredicts the values of multiple time series.VAR, VARMA, VARMAX (ch. 4)
In-betweenUses predictors other than the single series (exogenous variables) to forecast one series.SARIMAX (ch. 4), tree and neural models with features (ch. 5-6)

Two approaches, and an honest comparison

The slides put the two families side by side without pretending the choice is obvious.

Based on a well-defined theoretical corpus, and it yields justified results. After training on historical data, an equation presents the relationship between the load and its corresponding factors. Regression models, Box-Jenkins models, exponential smoothing and Kalman filters all belong here.

More recent, often provides better results but without justification of the applied models. The slides note, with a visible eyebrow raised — three question marks in the original — that AI methods are said to copy "the human way of thinking". Expert systems, evolutionary programming and fuzzy systems were tried; by far the most effective are machine learning methods, neural or otherwise.

Statistical methods have difficulties in identifying complex nonlinear relationships among factors, but are explainable in their results. That single sentence is the reason the exam project demands one method from each family: you are expected to be able to feel the difference on your own data, not to be told about it.

6. Regression, prediction, forecast: residuals and forecast errors

Regression analysis tries to estimate the relationships among variables, usually between a dependent variable and one or more independent variables (or predictors). It estimates a function. It is not limited to prediction and forecasting: more generally, it wants to determine the value of the dependent variable when the independent variables are fixed.

Then comes a vocabulary distinction the slides are emphatic about, because ML literature blurs it. Regression is the general term often used in the machine learning literature to refer to prediction tasks. But:

TermDefinitionError is called
PredictionIn-sample observations: a model of the data. Predicted values are calculated for observations in the sample used to estimate the regression.Residual — the difference between the actual value of Y and its predicted value for observations in the sample.
ForecastOut-of-sample observations: made for some date beyond the data used to estimate the regression; the data of the forecasted variable is not in the estimation sample.Forecast error — the difference between the future value of Y, not contained in the estimation sample, and the forecast of that future value.
For the exam

Residual ≠ forecast error. A residual is measured on data the model has already seen; a forecast error on data it has not. A model can drive residuals to zero and still forecast disastrously — which is precisely the definition of overfitting in section 11. When someone quotes an "error" for a model, the first question is always: in-sample or out-of-sample?

7. Decomposition: trend, season, cycle, noise, accident

Time series decomposition deconstructs a time series into several components, each representing one of the underlying categories of patterns. The common decomposition is into trend, seasonal, cyclical and random components — plus, in the slides, an occasional component that deserves its own discussion.

ComponentDefinition from the slides
TrendTypically a persistent increasing or decreasing direction in the data. Usually modelled by a linear, quadratic or exponential function.
SeasonalRepetitive patterns, typically over periods of weeks, months or years. Has a fixed period L.
CyclicalRepeated but non-periodic fluctuations (non-seasonal) lasting at least two years, typically due to changes in economic conditions (recessions, expansions).
Random (irregular, noise)Random, irregular influences.
OccasionalRare: war events, important technological innovations, political crises. Needs a model change.

The camper sales example from the slides shows all three of the structured components at once: a seasonality where Q3 > Q2 > Q1 > Q4 of the previous year, a long-term trend, and economic cycles visible as the recessions of the 1980s and 1990s. The GDP of Italy from 1861 to 2017, and a power-energy forecast, are shown as cases where an occasional component forces a model change: no amount of parameter fitting rescues a model across a structural break.

Four stacked panels showing the same series decomposed into observed values, a rising trend, a repeating seasonal pattern and irregular residual noise. OBSERVED y(t) TREND T(t) linear, quadratic or exponential SEASONAL s(t), period L = 4 L L RANDOM e(t) additive y = T + s + c + e multiplicative y = T × s × c × e mixed y = T × s × c + e
Plate 2.2 — Decomposition. The cyclical component is not drawn separately because, as the slides note for STL, it is folded into the trend panel: STL returns seasonal, trend and irregular only.

Additive, multiplicative, mixed

The hypothesis behind decomposition is that the observed values result from the combination of different components. How they combine is a modelling choice with a clear rule of thumb:

ModelFormUse it when
Additivey = T + s + c + ethe variations around the trend do not vary with the level of the time series
Multiplicativey = T × s × c × ethe trend is proportional to the level of the time series
Mixedy = T × s × c + eseasonal amplitude scales with level, but the noise does not

STL, and multiple seasonalities

A common model is STL — seasonal decomposition of time series by Loess, where Loess is short for local regression. It decomposes the series into seasonal, trend and irregular, with the cyclical component included in the trend plot.

from statsmodels.tsa.seasonal import seasonal_decompose
plt.rcParams['figure.figsize'] = (10.0, 6.0)
df = pd.read_csv('BoxJenkins.csv', usecols=["Passengers"])
ds = df[df.columns[0]]                  # converts to series
result = seasonal_decompose(ds, model='multiplicative', period=12)
result.plot()
plt.show()

Real series often have more than one period at once — a daily and a weekly rhythm, say. The slides list three packages that can identify multiple seasonalities: MSTL (in statsmodels), Facebook's Prophet, and BATS / TBATS.

8. The empirical STL, step by step on the fil rouge

Rather than call a library and admire the plot, the deck rebuilds STL by hand on the fil rouge, and projects it into the future. Three ingredients are defined first.

ToolDefinition from the slides
Linear regressionComputes a linear function that minimises the global distance from the dataset points.
Moving averageCreates a series of averages of different subsets of the full data set. Subsets are modified by shifting forward: excluding the first number of the series and including the next value.
Centered moving average (CMA)Aligns each moving average with the middle of the time span of the observations it averages. If computed on an even number of terms, you need to average the averaged values.

The trend by least squares

We look for the interpolation line y = a·x + b minimising the mean square error over all data pairs (xi, yi). Analytically, with mean values and :

a = Σ(xᵢ - x̄)(yᵢ - ȳ) / Σ(xᵢ - x̄)²
b = ȳ - a · x̄

which in the vectorised form the slides use for Python becomes:

On the twenty fil rouge points the arithmetic gives x̄ = 10.5, ȳ = 395.25, and

quantityvalue
slope a25.88796992
intercept b123.4263158
trend at t = 1149.3142857
trend at t = 20641.1857143

Sanity check on the first row: 25.888 × 1 + 123.426 = 149.314, against an observed 128. The gap is what the seasonal coefficient will absorb.

9. Correlograms and finding the period

Seasonality induces periodic fluctuations around the trend, and to model it we need a coefficient to multiply the trend by. But first we must find the periodicity (wavelength) — the number of seasons. The slides pick autocorrelograms, noting that the correlation of two time series can be quantified by Pearson's index (parametric) or Spearman's (nonparametric).

A correlogram, or autocorrelation plot, is a chart that represents the autocorrelation of a time series as a function of the lag used for computing the autocorrelation. Concretely: build a table where beside the column yt you place the columns yt-1, yt-2, …, yt-K, start from the (K+1)-th row so that all the compared series have equal length, and compute for each k the correlation

rₖ = Σₕ(yₜ - ȳ)(yₜ₋ₖ - ȳ) / Σₕ(yₜ - ȳ)²

Pairs (k, rₖ) are then plotted with lags on the x-axis and the corresponding correlation on the y-axis.

The fil rouge correlogram

Computed on the raw fil rouge with Pearson, the slides report:

lag k012345678
rₖ1.0000.126-0.3800.3700.9070.139-0.2710.5600.842

The reading is immediate and is the one the slides write on the chart: peaks at lag 4 and lag 8, therefore seasonality of 4. Quarterly data, four seasons, as the calendar column of the original table promised.

Correlogram of the fil rouge series: autocorrelation bars for lags zero to eight, with tall positive bars at lags four and eight identifying a seasonality of four. +1.0 0.0 -1.0 0 1.000 1 .126 2 -.380 3 .370 4 .907 5 .139 6 -.271 7 .560 8 .842 peaks at 4 and 8 → seasonality of 4
Plate 2.3 — The fil rouge correlogram with the values reported in the slides. The lag-0 bar is 1 by construction; what identifies the period is the pair of peaks at 4 and 8.

Three typical shapes

Correlograms can be widely different, but the slides single out three cases you should be able to recognise on sight: the correlogram of the original data series; the correlogram of the residuals after detrending; and the correlogram of the residuals after detrending and deseasoning. A slowly decaying correlogram means a trend is still present; a comb of peaks at multiples of L means seasonality is still present; a flat correlogram near zero means there is nothing structured left to model — which is the goal.

import numpy as np, pandas as pd, matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

df = pd.read_csv('FilRouge.csv', usecols=[1], names=['value'], header=0)
plt.rcParams.update({'figure.figsize':(9,7), 'figure.dpi':120})
fig, axes = plt.subplots(2, 2, sharex=True)
axes[0, 0].plot(df.value); axes[0, 0].set_title('Original Series')
plot_acf(df.value, ax=axes[0, 1])
# 1st Differencing
axes[1, 0].plot(df.value.diff()); axes[1, 0].set_title('1st Order Differencing')
plot_acf(df.value.diff().dropna(), ax=axes[1, 1])
plt.show()

10. Seasonal coefficients, deseasoning and the projected forecast

With the period known, the seasonal coefficient is built in three moves.

  1. Relative elongation. For each point, divide the observation by the trend value: yt / Tt. For t = 1: 128 / 149.3143 = 0.857252.
  2. Average by season index. Group the elongations by t mod 4 and average each group. The slides do it in Excel with a SUMPRODUCT over rows matching the modulus, divided by the number of complete seasons.
  3. Look the coefficient up per period (a VLOOKUP on the modulus) and multiply the trend by it.

The four coefficients that come out of the fil rouge are:

quarter position (t mod 4)1230
coefficient s1.2923400.8757490.6573161.142187
readingpeak quarter, +29%-12%trough, -34%+14%

Multiplying trend by coefficient reconstructs the seasonal model: at t = 1, 149.314 × 1.29234 = 192.96; at t = 5, 252.866 × 1.29234 = 326.79; at t = 20, 641.186 × 1.142187 = 732.35.

Deseasoning

To eliminate the effect of st we divide by st; what is left is trend plus random component. The slides tabulate it:

tytstdeseasoned
11281.2999.05
21810.88206.68
3870.66132.36
42191.14191.74
194190.66637.44
207251.14634.75

The projected forecast

Having the coefficients of the trend and of the seasonal components, we can project the model onto future periods. Extend the trend line past t = 20 and multiply by the coefficient of the corresponding season:

ttrendstforecast
21667.0741.29862.09
22692.9620.88606.86
23718.8500.66472.51
24744.7381.14850.63

The empirical STL, live on the fil rouge

The trend and the four seasonal coefficients are exactly the ones computed in the slides. Toggle the layers, and push the horizon to see the projection of section 10.

4
Careful — the slides flag their own result

Under the forecast chart the deck writes: variance grows too much. A log transform preprocessing was in order. The multiplicative seasonal model amplifies the swing as the trend rises, and by t = 24 the peaks and troughs are implausibly far apart. This is the hand-off to chapter 3: the fix is not a better model, it is a transform applied before modelling.

11. Sampling: train, test, and why k-fold does not apply

The slides are categorical: in any learning process, performance should be estimated with out-of-sample validation, withholding some of the sample data from model identification (the training phase), then using the model to make forecasts for the hold-out data (the test data). The testing dataset should never be used in the learning step.

Two definitions follow, and they close the loop with section 6: predictions on train values are called fitted values, and the corresponding errors are called residuals.

Key idea

k-fold cross validation repeats the split by dividing the data into k groups, each given a chance to be held out — but it cannot be used when learning on data series. The reason is temporal: a fold taken from the middle of a series would train the model on the future to predict the past. Series validation must respect the arrow of time, which in practice means a split point, or a rolling origin.

Overfitting

Errors on train data can be much smaller than those on test data, in case of overfitting. The slides name two circumstances in which it is likely:

  1. a model with a large number of parameters has been fitted to a too small sample of data;
  2. the model has been selected from a large set of potential models precisely by minimising the RMSE in the estimation period.

The second is subtler and more common: if you grid-search a hundred configurations and keep the one with the lowest in-sample error, the winning score is a selection artefact, not a performance estimate. Chapter 9 returns to this when it discusses grid search and Optuna.

Making the split

The mechanics are mundane: select an arbitrary split point in the ordered list of observations and create two datasets. Depending on how much data you have and how much the model needs, splits of 50-50, 70-30 or 90-10 are used.

ds = pd.read_csv('BoxJenkins.csv', header=0)
X = ds.Passengers.values
train_size = int(len(X) * 0.66)
train, test = X[0:train_size], X[train_size:len(X)]
print('Observations: %d' % (len(X)))
print('Training Observations: %d' % (len(train)))
print('Testing Observations: %d' % (len(test)))
plt.plot(train)
plt.plot([None for i in train] + [x for x in test])
plt.show()

Where to cut the fil rouge

Move the split point and watch how much history is left to fit a trend and four seasonal coefficients. With twenty quarterly points, an aggressive test share leaves fewer than two full seasons to learn from.

70%
For the exam

The slides append a self-criticism to the fil rouge worked example: we should have reserved the last data for testing! The empirical STL of sections 8 to 10 was fitted on all twenty points and then projected — so its "forecast" was never validated. Reproducing that mistake in the exam project is the fastest way to lose marks on methodology.

Check your understanding

Split the name "predictive analytics" and say what each half commits you to.

Predictive: the primary objective is the prediction of future events on the basis of data — time series or other — available now. Analytics: forecasts are used to take decisions now. The core of the discipline is capturing relationships between explanatory variables and predicted variables from past occurrences and exploiting them to predict the unknown outcome.

What are the four attributes of a forecast listed in the slides?

(1) Forecasts are usually wrong. (2) They are usually not just numbers: they include mean and dispersion measures and a confidence interval. (3) Aggregate data forecasts are more reliable than detail data ones. (4) Reliability decreases with the distance in the future.

What is the Delphi method and what makes it work?

A subjective forecasting method: ask the question, gather individual opinions, share the opinions anonymously, re-ask the question, and repeat the procedure until consensus. The anonymity is the operative feature — it lets participants revise towards the group without deferring to status. Other subjective methods listed are the sales force composite, polls among customers and opinions of managers.

Name the three high-level phases of an objective model and their synonyms.

Model specification (identification) — choosing the forecast technique to use. Model fitting (parameter setting) — given the model, setting its parameters to maximise coherence of forecasts with actual data. Model diagnosis (validation) — determining the level of coherence between actual and forecast data.

Distinguish prediction from forecast, and residual from forecast error.

Prediction is in-sample: values computed for observations in the sample used to estimate the regression; its error is the residual, the difference between the actual Y and its predicted value inside the sample. Forecast is out-of-sample: made for a date beyond the estimation data; its error is the forecast error, the difference between the future value of Y — not in the estimation sample — and the forecast of it. In ML literature "regression" is often used loosely for both.

List the components of a time series decomposition, with the distinguishing feature of the cyclical one.

Trend (persistent increasing or decreasing direction, modelled by a linear, quadratic or exponential function); seasonal (repetitive patterns over weeks, months or years, with a fixed period L); cyclical (repeated but non-periodic fluctuations, non-seasonal, lasting at least two years, typically caused by economic conditions such as recessions and expansions); random/irregular noise; and the occasional component — rare events such as wars, major technological innovations or political crises, which require a model change.

When do you choose an additive model over a multiplicative one?

An additive model (y = T + s + c + e) is used when the variations around the trend do not vary with the level of the series. A multiplicative model (y = T × s × c × e) is used when the trend is proportional to the level of the series. A mixed model (y = T × s × c + e) combines the two.

What does STL return, and where does the cyclical component go?

STL is seasonal decomposition of time series by Loess (local regression). It decomposes the series into seasonal, trend and irregular. The cyclical component is included in the trend component plot. For series with more than one period, the slides point to MSTL, Facebook's Prophet, and BATS/TBATS.

How is a correlogram built and how did it reveal the fil rouge period?

Beside the column yt you place K lagged columns yt-1 … yt-K, start from the (K+1)-th row so all columns have equal length, and compute the correlation (Pearson, or Spearman for the nonparametric version) between yt and each lagged column. Plot (k, rk). On the fil rouge the coefficients were 1.000, 0.126, -0.380, 0.370, 0.907, 0.139, -0.271, 0.560, 0.842 for lags 0 to 8: the peaks at lag 4 and lag 8 identify a seasonality of 4.

Walk through the empirical STL forecast for t = 21 on the fil rouge.

The least-squares trend on twenty points is y = 25.888·t + 123.426, so at t = 21 the trend value is 667.074. The season index of t = 21 is the same as t = 1, whose coefficient — the average relative elongation y/T over that season position — is 1.29234. The forecast is the product: 667.074 × 1.29234 ≈ 862.09.

The slides criticise their own fil rouge projection. What is the criticism and what is the fix?

The comment is that the variance grows too much: with a multiplicative seasonal model on a rising linear trend, the peak-to-trough swing widens without bound. A log transform as preprocessing was in order — the topic of chapter 3, where the log transform is presented precisely as the way to make a series stationary in variance.

Why can k-fold cross validation not be used on time series, and what is used instead?

k-fold repeatedly splits the data into k groups, each in turn held out. On a data series this breaks the temporal order: a middle fold would have the model trained on future values to predict past ones, leaking information. Instead one chooses a split point in the ordered observations — 50-50, 70-30 or 90-10 — and never lets the test data touch the learning step.

Under what two circumstances is overfitting likely?

(1) When a model with a large number of parameters has been fitted to a too small sample. (2) When the model has been selected from a large set of candidate models precisely by minimising RMSE in the estimation period — the reported score is then a product of the selection, not an estimate of future performance.