Time Series Analysis & Climate Change
By: Peter Turner
Tags: Time Series Forecasting, Data Science, Climate Change, Time Series Analysis, Prophet

Wrangling of CO₂ emissions data

This section will tackle the wrangling of our Carbon Dioxide emissions data. We will use some of the same techniques used above, as well as looking at some new ones:

Slicing and Searching

Useful functions

Familiar techniques

From our DataFrame, we will use only the row representing the CO₂ emissions for the entire world. Like before, we will create a new DataFrame that uses a DateTime index — and then use the raw data to populate it.

Creating a DataFrame — and populating it — with world emissions data

Resulting emissions DataFrame

Slicing and Searching

DateTime indexes make for convenient slicing of data, let’s select all of our data after the year 2011:

e[e.index.year>2011]

Slice of emissions data after the year 2011 (notice the missing data)

Hmm. There seems to be a few NaN’s towards the end of our data — lets use Panda’s fillna method to deal with this.

e.fillna(method='ffill', inplace=True)

e[e.index.year>2011]

Slice of emissions data after the year 2011 (no missing data)

Much better! We can also make use of the DateTime index to search for values within a specific range:

e['1984-01-04':'1990-01-06']

Resulting slice of emissions data within the specified range

This functionality starts to become very useful with more granular time-based data — in our case we have years, and so a range index would probably have been sufficient.

Useful functions

Pandas provides a whole range of other functions that can be very useful when dealing with time series data — we cannot cover them all in this tutorial, but some are listed below:

DataFrame.rolling → provides rolling window calculations

Pandas.to_datetime → a replacement for datetime.datetime’s strptime function, it is more useful as it can infer the format

TimSeries.shift & TimSeries.tshift → allows for shifting or lagging of the values of a time series backward and forwards in time

For more information and functionality, see this great Pandas page on time series.

Visualizing

Now that we have our datasets nicely wrangled, let’s look at how to plot them. We will be using two plotting libraries, namely:

Matplotlib

Plotly

Plotting with Matplotlib

Matplotlib is a very popular 2D plotting library for Python, and can easily be downloaded using pip.

Let's plot our temperature data again using Matplotlib, this time we will do it more fancily — adding axis labels and titles, etc.:

Code to plot temperature anomalies using Matplotlib

Resulting temperature plot using Matplotlib

And our CO₂ emissions data:

Code to plot emissions using Matplotlib

Resulting emissions plot using Matplotlib

Plotting with Plotly

Plotly is a great library for generating plots that are both interactive and suitable for the web. The Plotly Python package is an open-source library built on plotly.js — which is in turn built on d3.js. In this tutorial, we will be using a wrapper called cufflinks — this makes it easy to use Plotly with Pandas DataFrames.

Importing Plotly and Cufflinks correctly for offline mode

Now that we have the library correctly imported, let’s plot both datasets again, this time using Plotly and Cufflinks:

Plotting temperature data using Plotly

Plotting emissions data using Plotly

The resulting plots look much nicer — and are interactive:

Resulting temperature plot using Plotly

Resulting emissions plot using Plotly

Time Series Correlation

Although it seems relatively obvious that both series are trending upwards, what we’d actually like to do here is determine whether the temperature change is as a result of the CO₂ emissions.

Granger Causality

Now, proving causation is actually very difficult — and just because two things are correlated, does not mean that one causes the other (as any statistician will earnestly tell you!). What we will do instead is determine how helpful the CO₂ emissions data is in forecasting the temperature data; to do this we will use the Granger Causality test.

Do not be fooled by the name, Granger Causality does not test for true causality. It would actually be more apt to call it Granger Predictability, or something along those lines.

Anyway — what this test does is determine whether one time series will be useful in forecasting another.

Dynamic Time Warping

We, humans, have developed a number of clever techniques to help us measure the similarity between time series — Dynamic Time Warping (DTW) is one such technique. What DTW is particularly good at, as measuring similarities between series that ‘differ in speed’.

For example, and to quote Wikipedia:

“Similarities in walking could be detected using DTW, even if one person was walking faster than the other, or if there were accelerations and decelerations during the course of an observation.”

As this blog post was running awfully long, I have decided to separate out both the Granger Causality, as well as the Dynamic Time Warping stuff, into a separate post.

Modeling and Forecasting

Okay so we can pull, wrangle and visualize our data — and we can do Granger Causality tests to determine whether one time series can be used to predict another; but what about forecasting?

Forecasting is fun because it allows us to take a stab at predicting the future.

In this section, we will look at forecasting using a library, namely Facebook’s Prophet library.

We will also briefly look at ARIMA models — though so as to keep this blog post from getting unmanageably long, we will not go through ARIMA in too much detail (at least not in this post).

Forecasting using Facebook’s Prophet

Our blue overlords — Facebook — have released an extremely powerful and user-friendly library named ‘Prophet’. Prophet makes is possible for those with little-to-no experience to predict time series, whilst providing intuitive parameters that are simple to tune. The library works in a similar way to the models in sklearn — an instance of the Prophet is instantiated, and then the fit and predict methods are called. This may come as a breath-of-fresh-air to you machine learning enthusiasts out there, it certainly did to me.

Creating, fitting and plotting a model for Temperature

We will first import Prophet, and then create a separate DataFrame into which we will copy the data across in the correct format — Prophet takes a DataFrame with two columns, one for the date and one for the values. The date column must be called ‘ds’ whilst the value column must be called ‘y’. You could do this by modifying your original DataFrame, but I opted to just create a new one:

Python code to train a temperature anomaly model using Prophet

Resulting forecast for temperature anomalies

And there we have it, a prediction for global temperature anomalies over the next 100 years! Notice the light blue region, which widens as we move further into the future? That is the forecast’s uncertainty; which grows as we proceed further forward in time.

Remember that this forecast only takes into account past anomaly data and nothing else. In reality, this could prove problematic as the heat retained may actually increase exponentially with increased CO₂ in the atmosphere. The picture below shows NASA’s current global surface temperature forecast for different levels of emissions into the future (hey, we didn’t do too badly!).

NASA’s forecast

Decomposition

As was stated at the beginning of this article, it can be useful to think of a time series as being made up of several components; and luckily for us, Prophet can help us break up our model into these components — so that we can see them visually.

We have already instantiated our model above, to split the model up into its components — run the following code:

# Plot the forecast components

m.plot_components(forecast);

By default, you’ll see the trend and yearly seasonality of the time series. If you include holidays, you’ll see those here, too. (With more granular data — the weekly seasonality will be shown too).

What can you tell by looking at the components? Leave your comments below.

Forecasting using ARIMA

Autoregressive Integrated Moving Average — or ARIMA — is a forecasting technique which is able to project future values of a series.

ARIMA is part of a broader class of time series models, all of which are very useful in that they provide a means through which we can use linear regression type models on non-stationary data.

Stationarity basically means that your data is not evolving with time (see explanation in the next section). Linear models require stationarity; they are good at dealing with and predicting stationary data.

So the basic intuition is that we’d like to achieve a stationary time series that we can do linear regression on, and ARIMA is just linear regression with some terms which ‘force’ your time series to be stationary.

As this blog post is getting rather long — I have decided to leave Autoregressive Integrated Moving Average Modeling for another day, and another post. For now, see this post for a great introduction to the various forecasting methods (including ARIMA).

General Tips, Terms, and Common Pitfalls

Terms

Autocorrelation

Autocorrelation is an important concept to understand when doing time series analyses; the term refers to (and is a mathematical representation of) the degree of similarity between a given time series, and a lagged version of itself over successive time intervals. Think of autocorrelation as the correlation of a time series with itself — it is thus sometimes referred to as lagged correlation (or serial correlation). If you are interested in doing ARIMA modeling (see below) — an understanding of autocorrelation is doubly important.

Spurious Correlation

Spurious correlations are actually not-altogether uncommon phenomena in statistics; a spurious correlation is a mathematical relationship in which two or more events or variables are associated but not causally related. This can be due to either coincidence or the presence of a third, unseen factor (sometimes called a “common response variable”, “confounding factor”, or “lurking variable”).

Stationarity

A stationary time series is one in which several statistical properties — namely the mean, variance, and covariance — do not vary with time. This means that, although the values can change with time, the way the series itself changes with time does not change over time.

Stationary vs. Non-Stationary Time Series

For more on this, check here and here. We will not dive too deep into stationarity — but we will do go over a how we can test for stationarity, and how we can make our two series stationary (for the purpose of the Granger Causality test) in this post.

Tips

Correlation is not Causation

What has come to be a basic mantra in the world of statistics is that correlation does not equal causation. This means that just because two things appear to be related to one another does not mean that one causes the other. This is a worthwhile lesson to learn early on.

Correlation does not have to equal causation (original)

Beware of trend

Trends occur in many time series, and before embarking on an exploration of the relationship between two different time series, you should first attempt to measure and control for this trend. In doing so, you will lessen the chance of encountering spurious correlations. But even de-trending a time series cannot protect you from all spurious correlations — patterns such as seasonality, periodicity and autocorrelation can too.

Be aware of how you deal with a trend

It is possible to de-trend naively. Attempting to achieve stationarity using (for example) a first differences approach may spoil your data if you are looking for lagged effects.