Sunday, January 28, 2018

Turn your R code into web API in seconds

Hello everyone! We will talk about turning your R code into web API in this blog. It is really simple. All you need to do is saving your code, using some functions from the library called "Plumber" and getting your value that is going to be sent to your website. Let's have a quick start and see how is it done.

Let's say you have such classifiers using House Prices data.

columns <- c("Street","RoofStyle","BsmtFinType2","Heating","GarageCond","OverallQual","OverallCond","LotFrontage","YearBuilt","TotRmsAbvGrd")
train.v1 <- train[,columns]


rf.model <- randomForest(outcomes~., data = train.v1, mtry = 3, importance = TRUE)
mod.gbm <- gbm(medv ~ . ,data = train.v1,distribution = "gaussian",n.trees = 10000,
               shrinkage = 0.01, interaction.depth = 4)

save(rf.model, file = "rf_for_house.RData")
save(mod.gbm, file = "gbm_for_house.RData")


Data used can be found at this web site.

As you can see 10 different features are used. So, from the web site user should send us 10 different values to feed our algorithm. The result will be the price of the house. Those values will be our parameters in the function that sends results to the website.

library(jsonlite)
library(randomForest)
library(gbm)
library(dplyr)
load("rf_for_house.RData")
load("data_for_house.RData")
load("gbm_for_house.RData")

#* @post /predict
#* @serializer unboxedJSON
predict.house <- function(Street, RoofStyle, BsmtFinType2, Heating, 
               GarageCond, OverallQual, OverallCond, LotFrontage, YearBuilt, TotRmsAbvGrd){
  data <- list(
   Street=Street, RoofStyle = RoofStyle, BsmtFinType2 = BsmtFinType2, Heating = Heating, 
     GarageCond = GarageCond, OverallQual = OverallQual,
    OverallCond = OverallCond, LotFrontage = LotFrontage, YearBuilt = YearBuilt,
    TotRmsAbvGrd = TotRmsAbvGrd
  )
  data <- as.data.frame(data)
  print(data)
  data <- preprocess2(data)
  
  prediction <- predict(rf.model, data)
  pred.gbm <- predict(mod.gbm,data, n.trees = 1000)
  
  prediction <- exp(prediction)
  pred.gbm <- exp(pred.gbm)
  
  ensembled <- (pred.gbm + prediction) / 2
  
  json <- jsonlite::toJSON(ensembled, auto_unbox = TRUE)
  }

This is the function that computes the price of the house. I will not go into details here but as you can see you can call any other function inside this function. The data that is sent is processed to make it in the same form as our training data. After processing it is ready for prediction. Random Forest and Gradient Boosting algorithms are used here and the result is the average of the results of both. In preprocessing, response value which is price was log transformed. To re-transform it to actual value the exponent value is taken. And the result is in JSON format since we are communicating with a web site. THE MOST IMPORTANT part here is that if you return the value using R's return function it won't work. Example code,

....

ensembled <- (pred.gbm + prediction) / 2
return (ensembled)

#OR
ensembled <- (pred.gbm + prediction) / 2
json <- jsonlite::toJSON(ensembled, auto_unbox = TRUE)
return (json)

In this case even if the value in the return function is json or numeric, it will be R OBJECT and javascript will not be able to read it's value. So just leave your end json type value. If you use Postman it will give no error. It handles this error somehow but in the javascript part you get the error. This is the lesson we learned 3 days before final presentation of our project.

After writing your function, we need to turn it into web API. Save your script which contains this function with the name "rf.model.R". And we are ready to go.

# !!! launch API
library(plumber)
r <- plumb(file = "rf.model.R")
r$run(port=8000)


This is where the library plumber comes. It turns your code into web API in 2 lines of code. And your API is waiting for you on the port 8000.

No comments:

Post a Comment

Gibbs Sampler

Gibbs Sampler In this blog we are going to discuss Gibbs Sampler with an applied example. But we will not dive into Gibbs Sampler direc...