Programming a simple Neural Network using TensorFlow and R

Using R Language interface for TensorFlow, it is possible to program Deep Neural Networks using tfestimators library. I provide one simple example for the same.

The problem is to estimate the value of the Sensex Index based on the following parameters:

  1. Historical prices of the Nifty
  2. Historical prices of Gold
  3. The date on which the above 2 prices were recorded
  4. The day of the date
  5. The month of the above date
  6. The year of the above date
  7. The day of the week of the date
  8. The Julian day of the date

Before we start programming the predictor, let us look at the libraries that we require.

if("lubridate" %in% rownames(installed.packages()) == FALSE) {install.packages("lubridate")}
library(lubridate)

if("tensorflow" %in% rownames(installed.packages()) == FALSE) {install.packages("tensorflow"); library(tensorflow); install_tensorflow()}
library(tensorflow)

if("tfestimators" %in% rownames(installed.packages()) == FALSE) {install.packages("tfestimators")}
library(tfestimators)

Next, let us load the data and have a look at the data.

df <- read.csv(file="PriceIndex.csv", header=TRUE, sep=",")
df$ObsDate <- as.Date(df$ObsDate, "%Y-%m-%d")
df$ObsMonth <- month(df$ObsDate)
df$YearNum <- year(df$ObsDate)
df$WeekDay <- as.POSIXlt(df$ObsDate)$wday
df$ObsDay <- day(df$ObsDate)
df$ObsJulianDay <- as.numeric(format(df$ObsDate, "%j"))

The first few records in the data.

head

The last few records in the data.

tail

Now, we start building the model.

First, we need to set up the input function. The input function defines the independent variables and the dependent variables. In our case, the independent variable is the value of the Sensex. The dependent variables are values of Nifty, Gold, Date, Year, Month, Weekday and Julian Day.

sensexVal_input_fn <- function(data, num_epochs = 1) {
  input_fn(data,
           features = c("ObsJulianDay", "ObsMonth", "ObsDay", "WeekDay", "YearNum", "Gold", "Nifty"),
           response = "Sensex",
           batch_size = 32,
           num_epochs = num_epochs)
}

Next, we need to set up the feature columns. Feature Columns can be Categorical or Numeric. We use only Numeric columns in this example.

sensexVal_cols <- feature_columns(
  column_numeric("ObsJulianDay"),
  column_numeric("ObsMonth"),
  column_numeric("ObsDay"),
  column_numeric("WeekDay"),
  column_numeric("YearNum"),
  column_numeric("Gold"),
  column_numeric("Nifty")
)

Next, we need to set up the model. We set up a Deep Neural Network Regressor. model_dir parameter specifies where the model will be stored on the disk. The stored model can be retrieved at a later point of time to make predictions using the same.

We can set up the hidden layers of the Neural Network using the hidden_units parameter. In this example, I have set up 3 layers of hidden layers, each containing 7 neurons.

modelsensexVal <- dnn_regressor(hidden_units = c(7,7,7), feature_columns = sensexVal_cols, model_dir='./Value')

The complete syntax for the dnn_regressor function is as follows.

dnn_regressor(hidden_units, feature_columns, model_dir = NULL,
label_dimension = 1L, weight_column = NULL, optimizer = "Adagrad",
activation_fn = "relu", dropout = NULL, input_layer_partitioner = NULL,
config = NULL)

Next, we set up the data for training and testing. We use 90% of the available data for training and 10% of the available data for testing.

dfModel <- subset(df, ObsDate <= as.Date(cutOfDate, "%Y-%m-%d"))
indicessensexVal <- sample(1:nrow(dfModel), size = 0.90 * nrow(dfModel))
trainsensexVal <- df[indicessensexVal, ]
testsensexVal  % train(sensexVal_input_fn(trainsensexVal, num_epochs = 100))

> # train the model
> modelsensexVal %>% train(sensexVal_input_fn(trainsensexVal, num_epochs = 10))
[\] Training -- loss: 987729.00, step: 542
>

Once the model has been trained, we can evaluate it.

modelsensexVal %>% evaluate(sensexVal_input_fn(testsensexVal))

> # Evaluate the model
> modelsensexVal %>% evaluate(sensexVal_input_fn(testsensexVal))
[/] Evaluating -- loss: 34283.56, step: 8# A tibble: 1 x 3
average_loss global_step loss

1 86105. 54699. 2421707.
>

Once the model has been created, it is persisted on the disk in the directory defined by the parameter model_dir.

We can write the following code to load the model if already available or generate the model if it is not created yet.

# Assume the Sensex Model exists
generateSensexModel <- 0

# Check if the Sensex Model exists
if(file.exists("sensexValModelDir.rds")) {
  load(file="sensexValModelDir.rds")
  modelsensexVal <- dnn_regressor(hidden_units = c(7,7,7), feature_columns = sensexVal_cols,
                                     model_dir = saved_SensexValmodel_dir)
  if(is.null(modelsensexVal)) {
    generateSensexModel <- 1
  }
} else {
  generateSensexModel <- 1
}

if(generateSensexModel == 1) {
  modelsensexVal <- dnn_regressor(hidden_units = c(7,7,7), feature_columns = sensexVal_cols, model_dir='./Value')

  cutOfDate <- "2018-04-10"
  dfModel <- subset(df, ObsDate <= as.Date(cutOfDate, "%Y-%m-%d"))
  indicessensexVal <- sample(1:nrow(dfModel), size = 0.80 * nrow(dfModel))
  trainsensexVal % evaluate(sensexVal_input_fn(testsensexVal))

  # Save the model
  saved_SensexValmodel_dir <- model_dir(modelsensexVal)
  save(saved_SensexValmodel_dir, file="sensexValModelDir.rds")
}

Now that the model has been created, it can be used to predict the value of the independent variable.

# Form the Prediction Parameters
ObsJulianDay <- c(as.numeric(format(TodayDate, "%j")))
ObsMonth <- c(month(TodayDate))
ObsDay <- c(day(TodayDate))
WeekDay <- c(as.POSIXlt(TodayDate)$wday)
YearNum <- c(year(TodayDate))
Nifty <- c(YesterdayRecord$Nifty)
Gold <- c(YesterdayRecord$Gold)
obs <- data.frame(ObsJulianDay, ObsMonth, ObsDay, WeekDay, YearNum, Gold, Nifty)

# Predict Value
predictionValue % predict(sensexVal_input_fn(obs)))
predictionValue <- as.numeric(paste( unlist(predictionValue), collapse=''))
predictionValue

We can check how our model performed with the Test Data.

For this, we can create the prediction against each of the test data points.

predictionValue <- (modelsensexVal %>% predict(sensexVal_input_fn(testsensexVal)))
preds <- unlist(predictionValue['predictions'])

Now, we can plot a graph to check the performance.

qplot(x=testsensexVal$SENSEX, y=preds)

Rplot

Advertisements