The goal of building a machine learning application is to solve a problem, and an ML model can only do this when it is actively being used in production. As such, ML model deployment is just as important as ML model development.
Deployment is the process by which an ML model is moved from an offline environment and integrated into an existing production environment, such as a live application. It is a critical step that must be completed in order for a model to serve its intended purpose and solve the challenges it is designed for.
A common complaint among ML teams, however, is that deploying ML models in production is a complicated process. It is such a widespread issue that some experts estimate that as many as 90 percent of ML models never make it into production in the first place.
In this article, I will show you the basic way to deploy a machine learning model using a really popular python web framework, Django. We will build a model that recommends a music genre to someone depending on their age and gender. I am assuming you already know about ML model development and are looking for a way to deploy them.
The dataset.
Below is the dataset we will use to train our model, to easily follow along, save it as music.csv
Step 1: Fit the model and store it in a joblib file.
If you are quite familiar with machine learning, the code below is one of the simplest cases so should not be difficult to understand.
import joblib
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
data = pd.read_csv("music.csv")
X,y = data.drop(columns= ["genre"]), data.genre
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size= 0.3)
dtc = DecisionTreeClassifier()
dtc.fit(X_train, y_train)
joblib.dump(dtc, "premus.joblib")
What is happening?
First and foremost, we install packages pandas, which we use later to read our .csv dataset, DecisionTreeClassifier which is the algorithm we will use to fit the model, train_test_split will be used to split the data into training and testing sets.
Secondly, we load the data, from which we select the predictor variables and outcome variables, X and y respectively.
Next up, we then split the data into training and test sets to avoid over-fitting. We then initialize the model and train it (fitting with the training set).
Finally, store a binary file of our model that we will use later to make predictions, we use joblib to do this (dump).
Step 2: Set up Django
Django is a high-level Python framework for creating scalable and robust web applications. In python, this is the most widely used framework.
The most efficient method to integrate machine learning models in Django is to create a communication interface between the ML model and the web interface. It will acquire data for the model, which will then process it on its own. This interface will navigate you back to the web application's end once you've received the prediction from the model. We can do this through REST APIs or WebSocket.
Install Django
python -m pip install Django
Create the project
django-admin startproject premus
This will create a "premus" directory in your current directory. If it didn’t work, see Problems running django-admin. premus is just a name I chose for our app to mean music-prediction
The new startproject created should appear something like this
premus/
manage.py
premus/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
Add templates
We then work on templates, the HTML code through which the user will enter data and the prediction will be shown. So, we will require base.html page.
The base.html will contain an HTML form that will take all the necessary fields as input and upon submitting the form, the user will be redirected back with a recommendation displayed.
The new project structure should look something like this (the order of the files and folders may change)
premus/
manage.py
premus/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
templates/
form.html
Tell Django where to read the templates from
To do this, add "templates" to the DIRS in the object inside the TEMPLATES list in settings.py
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ["templates"], # right here
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Add code to base.html
Add the code below to base.html to collect the fields required. We will not be styling our HTML templates, for now, I just want us to create something functional, you can always do the styling later.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Music Recommender</title>
</head>
<body>
<header>
<nav></nav>
</header>
<section>
<h1>Select to options to get Recommendation</h1>
<form action="{% url 'prediction' %}" method="post">
{% csrf_token %}
<div>
<label>
Male
<input type="radio" name="gender" value="1" />
</label>
<label>
Female
<input type="radio" name="gender" value="0" />
</label>
</div>
<div>
<label>
Age
<input type="number" name="age" placeholder="eg. 19" />
</label>
</div>
<input type="submit" value="submit and get recommendation" />
</form>
<div class="output">
<h2>Prediction= {{prediction}}</h2>
</div>
<div class="output">
<h3>Age= {{settings.age}}</h3>
<h3>Gender= {{settings.gender}}</h3>
</section>
</body>
</html>
Integrating the music recommender model in a Django project
Copy your trained model dump (the joblib file) and paste it into the inner premus directory, at the end, the setup should look something like this (the order of files may be different due to sorting by alphabetical order).
premus/
manage.py
premus/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
premus.joblib
templates/
form.html
Create views.py and urls.py
Now we need to write some code in urls.py, this code lets the computer know which link to show what page
from django.contrib import admin
from django.urls import path
from . import views
app_name = "premus"
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name="index"),
path('/prediction', views.prediction, name="prediction")
]
The views.py will contain code on how to process the user-entered information.
from django.shortcuts import render
import joblib
from pathlib import Path
def index(request):
return render(request, "base.html", {"prediction": "None"})
def prediction(request):
BASE_DIR = Path(__file__).resolve().parent.parent
premus = joblib.load(BASE_DIR / "premus/premus.joblib")
gender, age = request.POST["gender"], request.POST["age"]
prediction = premus.predict([[age, gender]])
settings = {"gender": gender, "age": age}
return render(request, "base.html", {"prediction": prediction[0], "settings": settings})
Step 3: Start the server and test out
To start the Django development server, navigate to the root of your Django project(where there is manage.py) and run the following command using the terminal
python manage.py runserver
If you enter the URL provided (most likely http://127.0.0.1:8000/
) into the browser, the form the user will have to enter data and the results will look something like the below screenshot.
You can extend this to do some more efficient stuff on your other exciting ML project. If you learned something, follow and subscribe to my newsletter for more content like this. Follow me on Twitter