Machine Learning Model with FLASK REST API

Written by ashish-ghimire | Published 2020/01/09
Tech Story Tags: flask-api | machine-learning | random-forest | python | programming | api | backend | machine-learning-tutorials

TLDR Using FLASK REST API we will see how you can make your first REST API for Machine Learning Model. We will start by creating machine learning model. We will save the model and test it using Postman. Then we will use the model to create API using Flask and create API. The first thing we will need is to import the necessary libraries. In this project we will be using Boston Housing data set and it can be downloaded from.apologeticsklearn.datasets.com.via the TL;DR App

In this tutorial we will see how you can make your first REST API for Machine Learning Model using FLASK. We will start by creating machine learning model. Then we will see step-by-step procedure to create API using Flask and test it using Postman. 

Part 1: Creating Machine Learning Model

The first thing we will need is to import the necessary libraries. After importing necessary libraries we will need to import data. In this project we will be using Boston Housing data set and it can be downloaded from
sklearn.datasets
.
# importing necessary libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import metrics
 
 
# importing dataset from sklearn
from sklearn.datasets import load_boston
boston_data = load_boston()

# initializing dataset
data_ = pd.DataFrame(boston_data.data)

### Top five rows of dataset
data_.head()
Currently our data set does not have any feature name. So we will need to import feature name for the data set.
# Adding features names to the dataframe
data_.columns = boston_data.feature_names
data_.head()
Pre-processing the data
The variable we want to predict is price. So we will now create target variable for our Machine Learning Model.
# Target feature of Boston Housing data
data_['PRICE'] = boston_data.target
Now, we will check if any of our features are null and categorical or not. This is because null values would result in biased estimation machine learning models requires numerical values rather than categorical.
# checking null values
data_.isnull().sum()
No null values are found so features are left as it is. Now let's check if there are any categorical values.
# checking if values are categorical or not
data_.info()
We can see that all features are numerical. So now we will now create our model. 
Creating model
At first we will need to separate feature and target variable. Then split data set into training and testing set. And finally create a model.
# creating feature and target variable 
X = data_.drop(['PRICE'], axis=1)
y = data_['PRICE']
 
# splitting into training and testing set
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.2, random_state=1)
print("X training shape : ", X_train.shape )
print("X test shape : ", X_test.shape )
print("y training shape :“ , y_train.shape )
print("y test shape :”, y_test.shape )
 
# creating model
from sklearn.ensemble import RandomForestRegressor
classifier = RandomForestRegressor()
classifier.fit(X_train, y_train)
Now let's evaluate the performance of model for training and testing set.
# Model evaluation for training data
prediction = classifier.predict(X_train)
print("r^2 : ", metrics.r2_score(y_train, prediction))
print("Mean Absolute Error: ", metrics.mean_absolute_error(y_train, prediction))
print("Mean Squared Error: ", metrics.mean_squared_error(y_train, prediction))
print("Root Mean Squared Error : ", np.sqrt(metrics.mean_squared_error(y_train, prediction)))


# Model evaluation for testing data
prediction_test = classifier.predict(X_test)
print("r^2 : ", metrics.r2_score(y_test, prediction_test))
print("Mean Absolute Error : ", metrics.mean_absolute_error(y_test, prediction_test))
print("Mean Squared Error : ", metrics.mean_squared_error(y_test, prediction_test))
print("Root Mean Absolute Error : ", np.sqrt(metrics.mean_squared_error(y_test, prediction_test)))

Part 2: Saving and using machine learning model

We will use
pickle
for saving model. Serialization and DeSerialization mechanism helps to save the machine learning object model into byte stream and vice versa. The model will be saved under
model
folder. The working structure of the project is shown in Part 3.
# saving the model
import pickle
with open('model/model.pkl','wb') as file:
    pickle.dump(classifier, file)



# saving the columns
model_columns = list(X.columns)
with open('model/model_columns.pkl','wb') as file:
    pickle.dump(model_columns, file)

Part 3: Creating API for machine learning using Flask

After successfully creating machine learning model. We will need to create a web-sever in Flask. Flask is lightweight web application which is easy to use and scale up to complex application. This tutorial covers the basic implementation of Flask application i.e. making a web server and simple REST API.
Here is how the whole project is organized:
To use Flask, first create a folder name webapp and install flask inside it using following command in terminal. Make sure flask is inside webapp folder.
>> pip install Flask
A minimal web-application can be produced using Flask. The following code will create a simple web-app that redirects to stated URL to produce given results.
from flask import Flask
 
app = Flask(__name__)
 
@app.route('/', methods=['GET', 'POST'])
def main():
    return "Boston House Price Prediction”
 
 
if __name__ == "__main__":
   app.run()
Running the app
To start flask server on local machine, navigate to webapp folder and run the command in terminal.
>> export FLASK_APP=app.py
>> export FLASK_ENV=development
>> flask run
This will execute the application. Now navigate to web browser (localhost:5000) to see the result. The final result is shows below:
Let's put all the code together to check if we missed anything or not. All files are separated into
.py 
files. So the complete
app.py
file should look like:
from flask import render_template, request, jsonify
import flask
import numpy as np
import traceback
import pickle
import pandas as pd
 
 
# App definition
app = Flask(__name__,template_folder='templates')
 
# importing models
with open('webapp/model/model.pkl', 'rb') as f:
   classifier = pickle.load (f)
 
with open('webapp/model/model_columns.pkl', 'rb') as f:
   model_columns = pickle.load (f)
 
 
@app.route('/')
def welcome():
   return "Boston Housing Price Prediction"
 
@app.route('/predict', methods=['POST','GET'])
def predict():
  
   if flask.request.method == 'GET':
       return "Prediction page"
 
   if flask.request.method == 'POST':
       try:
           json_ = request.json
           print(json_)
           query_ = pd.get_dummies(pd.DataFrame(json_))
           query = query_.reindex(columns = model_columns, fill_value= 0)
           prediction = list(classifier.predict(query))
 
           return jsonify({
               "prediction":str(prediction)
           })
 
       except:
           return jsonify({
               "trace": traceback.format_exc()
               })
      
 
if __name__ == "__main__":
   app.run()

Part 4: Testing API in Postman

To test our API we will need API client and we will be using Postman. Once you have download Postman it should look like this.
Now we will type our URL (localhost:5000/predict) and type required features our model in .json format inside Body. And change request type to POST. Our final result should look like this.

Summary

By this point, you have developed Machine Learning and used Flask to create API, which can be used to predict the price of houses in Boston.

Extending this work

This article focuses on creating REST API for Machine Learning model and testing on Postman. Further it can be extended to make web-application and deploy in Heroku cloud platform.

Published by HackerNoon on 2020/01/09