Chapter 8: Model Deployment
Activity 13: Deploy an R Model Using Plumber
Create a model.r script that will load the required libraries, data, fit a regression model and necessary function to predict on unseen data.
Load the mlbench library that has the data for this activity:
library(mlbench)
Load BostonHousing data into a DataFrame df:
data(BostonHousing) df<-BostonHousing
Create train dataset using the first 400 rows of df and test with the remaining:
train <- df[1:400,] test <- df[401:dim(df)[1],]
Fit a logistic regression model using the lm function with dependent variable as medv (median value) and 10 independent variables, such as, crim, zn, indus, chas, nox, rm, age, dis, rad, and tax.
model <- lm(medv~crim+zn+indus+chas+ nox+rm+age+dis+rad+tax,data=train)
Define a model endpoint as predict_data; this will be used as the API endpoint for Plumber:
#' @get /predict_data function(crim,zn,indus,chas,nox,rm,age,dis,rad,tax){
Within the function, convert the parameters to numeric and factor (since the API call will pass them as string only):
crim <- as.numeric(crim) zn <- as.numeric(zn) indus <- as.numeric(indus) chas <- as.factor(chas) nox <- as.numeric(nox) rm <- as.numeric(rm) age <- as.numeric(age) dis <- as.numeric(dis) rad <- as.numeric(rad) tax <- as.numeric(tax)
Wrap the 10 independent features for the model as a DataFrame named sample, with the same name for the columns:
sample <- data.frame(crim = crim, zn = zn, indus = indus, chas = chas, nox = nox, rm = rm, age = age, dis = dis, rad = rad, tax = tax )
Pass the sample DataFrame to the predict function with the model (created in the 4th step) and return predictions:
y_pred<-predict(model,newdata=sample) list(Answer=y_pred) }
The entire model.r file will look like this:
library(mlbench) data(BostonHousing) df<-BostonHousing train <- df[1:400,] test <- df[401:dim(df)[1],] model <- lm(medv~crim+zn+indus+chas+nox+rm+age+dis+rad+tax,data=train) #' @get /predict_data function(crim,zn,indus,chas,nox,rm,age,dis,rad,tax){ crim <- as.numeric(crim) zn <- as.numeric(zn) indus <- as.numeric(indus) chas <- as.factor(chas) nox <- as.numeric(nox) rm <- as.numeric(rm) age <- as.numeric(age) dis <- as.numeric(dis) rad <- as.numeric(rad) tax <- as.numeric(tax) sample <- data.frame(crim = crim, zn = zn, indus = indus, chas = chas, nox = nox, rm = rm, age = age, dis = dis, rad = rad, tax = tax ) y_pred<-predict(model,newdata=sample) list(Answer=y_pred) }
Load the plumber library.
library(plumber)
Create a plumber object using the plumb function and pass the model.r file (created in part 1).
r <- plumb(model.r)
Run the plumber object by passing the hostname as localhost or 127.0.0.1 and a port, say 8080.
http://127.0.0.1:8080/
Test the deployed model using the browser or Postman and invoke the API.
API invoke:
http://127.0.0.1:8080/predict_
ata?crim=0.01&zn=18&indus=2.3&chas=0&nox=0.5&rm=6&
age=65&dis=4&rad=1&tax=242
{"Answer":[22.5813]}