Using Keras and TensorFlow to Predict Dengue Fever Outbreaks
By: Giovanni Rosati
Tags: Time Series Forecasting, Public Health, Keras, TensorFlow, Machine Learning

Machine learning prediction models using time-series weather data.

Image licensed from Adobe Stock

What is Dengue?

Dengue, commonly called dengue fever, is a mosquito-borne disease that occurs in tropical and sub-tropical parts of the world. In mild cases, symptoms are similar to the flu: fever, rash, and muscle and joint pain. In severe cases, Dengue can cause severe bleeding, low blood pressure, and even death.

Because it is carried by mosquitoes, the transmission dynamics of Dengue are related to climate variables such as temperature and precipitation. Although the relationship to climate is complex, a growing number of scientists argue that climate change is likely to produce distributional shifts that will have significant public health implications worldwide.

In recent years Dengue has been spreading. Historically, the disease has been most prevalent in Southeast Asia and the Pacific islands. These days many of the nearly half-billion cases per year are occurring in Latin America (DengAI: Predicting Disease Spread, Challenge Summary).

The ability to accurately forecast the number of people in a given area that will be infected with Dengue is of great value to public health officials, physicians, and ultimately anyone at risk of infection. Using historical data from the U.S. National Oceanic and Atmospheric Administration (NOAA) and Dark Sky, my goal was to create a machine learning model able to accurately predict the number of weekly cases of Dengue that will occur at two locations: San Juan, Puerto Rico and Iquitos, Peru.

This graph shows the weekly reported cases of Dengue in San Juan, Puerto Rico from mid-1990 through early 2008.

In San Juan, reported dengue cases often spike during the later part of the year and clearly some years have significant increases in the number of infections. This is understood to be correlated to increases in the number of mosquitos present. Mosquitos reproduce more readily in warm, humid conditions and when rainfall is plentiful. These conditions create more areas of standing water and thus more locations suitable for laying eggs.

Aedes aegypti and “Domain Knowledge”

Image licensed from Adobe Stock

After a female Aedes aegypti feeds on blood, she lays an average of 100 to 200 eggs and can do this up to five times in her lifespan. Eggs are laid on damp surfaces in areas likely to temporarily flood, such as tree holes and man-made containers like barrels, drums, jars, pots, buckets, flower vases, plant saucers, tanks, discarded bottles, tins, tires, water cooler, etc. and a lot more places where rain-water collects or is stored. She lays her eggs separately, unlike most species. Not all eggs are laid at once, but they can be spread out over hours or days, depending on the availability of suitable substrates. Eggs will most often be placed at varying distances above the waterline. Additionally, she will not lay the entire clutch at a single site, but rather spread out the eggs over several sites. The eggs can survive in a dry environment for over a year but when they are in a wet environment they can hatch in as little as two days. The remaining growth stages to adulthood can occur in as little as six days (denguevirusnet.com).

Having knowledge of this life-cycle is useful when training a machine learning model because there are likely relationships between weather events and/or conditions that create standing water that persists long enough for an egg to reach maturity. This type of information is referred to as “domain knowledge” in the realm of data science. A data scientist with extensive domain knowledge has an advantage in developing machine learning models within their area of expertise.

Getting the Data

As mentioned above the data was obtained from two sources. The NOAA weekly data was already prepared as CSV files available for download. The Dark Sky data, which is more detailed and daily, had to be obtained using an API (Application Programming Interface). About 15,000 API calls were made to Dark Sky to obtain daily weather data for the two cities. The data was saved to text files and subsequently processed to create CSV files for repeated use.

The type of data for this project is referred to as time-series. Time-series data requires unique models, considerations, and pre-processing for machine learning. Missing values, in particular, must be addressed prior to training any models. Here’s a sampling of the weather variables available on a daily frequency for these two locations, including the count of missing values for each variable in the 6,073 records For San Juan:

date 16

latitude 0

longitude 0

timezone 0

offset 0

apparentTemperatureHigh 18

apparentTemperatureHighTime 18

apparentTemperatureLow 17

apparentTemperatureLowTime 17

apparentTemperatureMax 18

apparentTemperatureMaxTime 18

apparentTemperatureMin 18

apparentTemperatureMinTime 18

cloudCover 175

dewPoint 18

humidity 18

icon 16

moonPhase 16

precipIntensity 3695

precipIntensityMax 3695

precipIntensityMaxTime 5041

precipProbability 3695

precipType 1561

pressure 18

summary 16

sunriseTime 16

sunsetTime 16

temperatureHigh 18

temperatureHighTime 18

temperatureLow 17

temperatureLowTime 17

temperatureMax 18

temperatureMaxTime 18

temperatureMin 18

temperatureMinTime 18

time 16

uvIndex 16

uvIndexTime 16

visibility 3918

windBearing 18

windGust 4854

windGustTime 4854

windSpeed 18

Almost all variables had missing values, some at nearly 80%. The details of how I addressed this missing data can be viewed in the Jupyter notebook at GitHub. If you want to read more about dealing with missing data, I wrote a brief article about the subject here: Towards Data Science.

After all the data was obtained, scrubbed, and evaluated it was ready for use in some machine learning models.

Building a Sequential Model

I used the Keras and Tensorflow libraries to construct my models. Just skip this section if the details of a recurrent neural network using LSTM sounds boring.

As I write this, LSTM (Long Short Term Memory) is the most powerful layer in the Keras library for time-series data, but it is also the most computationally expensive. If your hardware platform is adequately powerful for a given time-series project, I recommend trying LSTM.

The base model I started with was as follows:

model = models.Sequential()

model.add(LSTM(103, input_shape=(train_X.shape[1],

train_X.shape[2])))

model.add(Dense(50, activation='relu'))

model.add(Dense(1)) model.compile(loss='mae', optimizer='adam')

Then I experimented with adding a dropout layer of varying proportions:

model = models.Sequential()

model.add(LSTM(103, input_shape=(train_X.shape[1],

train_X.shape[2])))

model.add(Dropout(0.3)) # 0.3, 0.4, and 0.5 were tested

model.add(Dense(50, activation='relu'))

model.add(Dense(1)) model.compile(loss='mae', optimizer='adam')

Adding a dropout layer increased the model’s performance significantly. Dropout layers can be an effective tool to prevent model overfitting — a common issue in machine learning — and I plan to write more about using dropout layers soon.

This model is using the mean absolute error to evaluate its performance.

Making Predictions

Another challenge in working with time-series data is the inability of using sophisticated data splitting methods like cross-validation. With temporal data the available methods for train/validate/test splits are limited and beyond the scope of this article. For more information on this subject see this excellent article by Jason Brownlee, Ph.D.

I wanted both the training and testing data to include years with both low and high dengue infections. I found the following splits to work well for this project:

Here’s an example of the output I used to evaluate models:

In this example, the model is using four weeks of weather data to predict the following week’s number of dengue cases. The blue line represents the model’s performance on the training data — lower is better — and the orange line represents performance on data the model has never “seen”. From left to right represents each successive iteration (“epochs”, in machine leaning vernacular) of the model. The example above represents the best performing combination of model parameters that I tested:

lookback period (number of prior weeks the model uses for a prediction)

dropout proportion (the proportion of nodes to be randomly “turned off” during an epoch.

number of epochs to run

I ran tests using several combinations of these parameters.

Here’s a chart showing the number of cases the best model predicted vs. the actual cases:

The mean absolute error of 7.68 days (the average difference between actual cases and predicted Dengue cases) shows there is room for improvement but the model does accurately predict the huge spike of over 150 cases around week 95. As mentioned at the beginning of this article, information like this can be of tremendous value to a region’s decision-makers.

Going forward I will be experimenting with a few ways to improve this model :