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.