This project is about deploying the trained machine learning pipeline using FastAPI and Docker. The ml pipeline which will be deployed is taken from my repository Credit-Risk-Analysis-for-european-peer-to-peer-lending-firm-Bandora.
The ml pipeline includes a RandomForestClassifier for classifying the loan borrowers as defaulted / not-defaulted.
The API code must be in 'main.py' file within a directory 'app' according to FastAPI guidelines.
Import the required packages
# Imports for server
import pickle
import pandas as pd
from fastapi import FastAPI
from pydantic import BaseModel
# App name
app = FastAPI(title="Loan Default Classifier for lending firm Bandora")
To represent a sample of loan details along with the data type of each atttribute, a class needs to be defined using the BaseModel
from the pydantic library.
# defining base class for Loan to represent a data point for predictions
class Loan(BaseModel):
LanguageCode : object
HomeOwnershipType : object
Restructured : object
IncomeTotal : float
LiabilitiesTotal : float
LoanDuration : float
AppliedAmount : float
Amount : float
Interest : float
EMI : float
PreviousRepaymentsBeforeLoan : float
MonthlyPaymentDay : float
PrincipalPaymentsMade : float
InterestAndPenaltyPaymentsMade : float
PrincipalBalance : float
InterestAndPenaltyBalance : float
Bids : float
Rating : object
The trained machine learning pipeline needs to be loaded into memory, so it can be used for predictions in future.
One way is to load the machine learning pipeline during the startup of our Server
. To do this, the function needs to be decorated with @app.on_event("startup")
. This decorator ensures that the function loading the ml pipeline is triggered right when the Server starts.
The ml pipeline is stored in `app/ML_artifact' directory.
@app.on_event("startup")
def load_ml_pipeline():
# loading the machine learning pipeline from pickle .sav format
global RFC_pipeline
RFC_pipeline = pickle.load(open('app/ML_artifact/RFC_pipeline.sav', 'rb'))
Finally, an endpoint on our server handles the prediction requests and return the value predicted by our deployed ml pipeline.
The endpoint is server/predict with a POST operation.
Finally, a JSON response is returned containing the prediction
# Defining the function for handling the prediction requests, it will be run by ```/predict``` endpoint of server
# and expects an instance inference request of Loan class to make prediction
@app.post("/predict")
def predict(inference_request : Loan):
# creating a pandas dataframe to be fed to RandomForestClassifier pipeline for prediction
input_dictionary = {
"LanguageCode" : inference_request.LanguageCode,
"HomeOwnershipType": inference_request.HomeOwnershipType,
"Restructured" : inference_request.Restructured,
"IncomeTotal" : inference_request.IncomeTotal,
"LiabilitiesTotal" : inference_request.LiabilitiesTotal,
"LoanDuration" : inference_request.LoanDuration,
"AppliedAmount" : inference_request.AppliedAmount,
"Amount": inference_request.Amount,
"Interest":inference_request.Interest,
"EMI": inference_request.EMI,
"PreviousRepaymentsBeforeLoan" : inference_request.PreviousRepaymentsBeforeLoan,
"MonthlyPaymentDay" :inference_request.MonthlyPaymentDay,
"PrincipalPaymentsMade" : inference_request.PrincipalPaymentsMade,
"InterestAndPenaltyPaymentsMade" : inference_request.InterestAndPenaltyPaymentsMade,
"PrincipalBalance" : inference_request.PrincipalBalance,
"InterestAndPenaltyBalance" : inference_request.InterestAndPenaltyBalance,
"Bids" : inference_request.Bids,
"Rating" : inference_request.Rating
}
inference_request_Data = pd.DataFrame(input_dictionary,index=[0])
prediction = RFC_pipeline.predict(inference_request_Data)
# Returning prediction
if prediction == 0:
return {"Prediction": "Not Defaulted"}
else:
return {"Prediction": "Defaulted"}
As our API has been built, the Uvicorn Server can be use the API to serve the prediction requests. But for now, this server will be dockerized. And final predictions will be served by the Docker container.
The Docker container will be run on localhost.