How to deploy Machine Learning Models on Django
Tags: machinelearning, django, webdev, deployment
Published: 2024-02-14 21:42:00

If you have encountered machine learning models, you must have wondered how to share your fun project with a larger audience. Since most of these models are trained in Jupyter Notebook, Django is one of Pythons’ frameworks that comes in handy when we want to deploy them on the web. In this article, we are going to follow a series of simple steps and set up our model in a Django application.

# Prerequisites.

* Django 3.2.3

* scikit-learn 1.0.2

* pandas 1.3.5

## Django project.

First, we have to set up a Django application. Run the command below in the terminal to create our Django project in the directory you want your project in.
```
django-admin startproject practice
```
The above command creates a new folder in the root directory. The structure of the new folder should look like the block below
```
practice/  
    manage.py  
    practice/  
        __init__.py  
        settings.py  
        urls.py  
        wsgi.py  
        asgi.py
```
While inside the practice directory ,you can start your development server by running the command below in the terminal
```
$ python manage.py runserver
```
Your development server, at this point, should look similar to the picture below.

![](https://miro.medium.com/v2/resize:fit:700/1*xvISmb-Od17m0bKwpPrQfw.png)



Let’s create the Django app by running the command below in the terminal
```
$ python manage.py startapp practiceApp
```
A new folder should appear in our root directory. The contents inside this new folder should match the block below
```
practiceApp/  
 migrations/  
        __init__.py  
    __init__.py  
    admin.py  
    apps.py  
    models.py  
    tests.py  
    views.py
```
We are going to add a  `urls.py`file in the  _practiceApp_  directory. The file structure in the two created directories is not the same.

In the  `settings.py`  file inside the practice directory, add your  `practiceApp`  app in the  `INSTALLED_APPS`  segment.

**_practice/settings.py_**

![](https://miro.medium.com/v2/resize:fit:700/1*ZDtixJ5Rmzzwdgg9Vh-YbQ.png)



It is one of the ways we use to link our Django project and app.

Next,let's create a templates directory in our projects’ root folder. Once that is done, we will then create a  `index.html`  file inside it. We will use this file to define a simple front-end for our application.

## The model

Still, in our root folder, let’s create a model folder. Let’s create a  `model.ipynb`  file inside this folder. This file will differ from our  `.py` files since it’s in jupyter notebook format.Jupyter notebook is used to analyze data/code .Load the iris dataset by adding the code below.
```
from sklearn.datasets import load_iris  
import pandas as pd  
  
data = load_iris()  
X_data = pd.DataFrame(data.data, columns = data.feature_names)  
y_data = pd.Series(data = data.target, name = 'Targets')  
X_data.head()
```
As you can see from the block above, we can load and get the first five rows of the dataset as shown below:

![](https://miro.medium.com/v2/resize:fit:544/1*uqIBP5oOqGr5WlsPv1nLdA.png)



Next, we use the  `train_test_split`  method to divide the data into training and testing data. Once that is done, we import the  `RandomForestClassifier`  model to train our data. Here, we use our training data,  `X_train`  and  `Y_train`, and fit it into our model. Fitting models highly increases the chances of better results/predictions. All this is shown in the code block below
```
from sklearn.model_selection import train_test_split  
  
X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size = 0.2)  
from sklearn.ensemble import RandomForestClassifier  
model = RandomForestClassifier()  
model.fit(X_train, y_train)
```
After that, we measure our models’ accuracy score, and if we are satisfied with the result, we proceed to the next task. In this case, our model got a 96% accuracy score, as shown.
```
y_pred = model.predict(X_test)  
from sklearn.metrics import accuracy_score  
accuracy_score(y_test, y_pred)
```
Once you run the above cell, the output displays a 0.9666666666666667 accuracy score, telling us that our model is 96% more likely to give us better predictions.

Lastly, we need to save our model as a  `joblib`  file to import it into our project views file later and use it to make simple predictions.To do this, we create a new empty directory at our project root. We can give it the name  `modelSaved`. We then return to our  `main.ipynb`  file and run the code block below in the last code cell.
```
from joblib import dump  
dump(model, './savedModel/model.joblib')
```
Remember to change the relative path to match that of your  `savedModel`  directory. When you look at your  `savedModel`  directory, there is a new model.joblib file. Our model is now saved and ready to be integrated into our application.

Another mandatory step to connect our app and project directories is to link our URLs. We do this by including the  _practiceApp URLs_  in our project  _URLs_, in this case, the  _practice URL_. Below is how we can make this happen.

**_practice/urls.py_**
```
from django.urls import path, include  
  
urlpatterns = [  
  path('', include('practiceApp.urls')),  
]
```
In our  _practiceApp URLs_, we add URL patterns that show our app views. It is where we call the functions defined in our view file. It is shown in the code block below
```
**_practiceApp/urls.py_**

from django.urls import path  
from . import views  
  
urlpatterns = [  
    path('', views.predictor, name = 'predictor'),  
]
```
Let’s see what the predictor function looks like in our  `views.py`file.


**_practiceApp/views.py_**
```
from django.shortcuts import render  
  
from joblib import load  
model = load('./savedModel/model.joblib')  
  
def predictor(request):  
    if request.method == 'POST':  
        sepal_length = request.POST['sepal_length']  
        sepal_width = request.POST['sepal_width']  
        petal_length = request.POST['petal_length']  
        petal_width = request.POST['petal_width']  
        y_pred = model.predict([[sepal_length, sepal_width, petal_length, petal_width]])  
        if y_pred[0] == 0:  
            y_pred = 'Setosa'  
        elif y_pred[0] == 1:  
            y_pred = 'Verscicolor'  
        else:  
            y_pred = 'Virginica'  
        return render(request, 'index.html', {'result' : y_pred})  
    return render(request, 'index.html')

```
In our view file, we started by loading our already saved model. We then defined a predictor function that makes use of the POST method. In our prediction method, we wrote a short loop for our y_pred, which is also the user input to determine the prediction. All the output is based on the trained model prediction. Then, finally, our result, which will be later referenced in our index.html file, is given as the value of y_pred, in short, the user input.  
```
from joblib import load  
model = load('./savedModel/model.joblib')
```
In our view file, we started off by loading our already saved model. We then defined a predictor function that makes use of the POST method. In our prediction method, we wrote a short loop for our  _y_pred_, also the user input, to determine exactly what the prediction would be. All the output is based on the trained model prediction. Then finally, our result ,that will be later referenced in our  `index.html`  file , is given as the value of  _y_pred_  , in short, the user input.

## Front-end

In our  `index.html` file, paste the following HTML code

**_templates/index.html_**
```
<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <meta http-equiv="X-UA-Compatible" content="IE=edge">  
    <meta name="viewport" content="width=device-width, initial-scale=1.0">  
    <title> Django </title>  
</head>  
<body>  
    <h1>Iris Application</h1>  
    <hr>  
    {% if result %}  
        <h1>Flower is {{result}}</h1>  
    {% endif %}  
  
    <form action="" method="POST">  
        {% csrf_token %}  
        Sepal Length : <input type="number" name="sepal_length" required><br>  
        Sepal Width : <input type="number" name="sepal_width" required><br>  
        Petal Length : <input type="number" name="petal_length" required><br>  
        Petal Width : <input type="number" name="petal_width" required><br>  
        <input type="submit">  
    </form>  
</body>  
</html>
```
The above html code creates a simple form that is going to enable a user test our model. Once you run your development server, you should be able to get different output based on your form input.

## Conclusion

So far, you have successfully deployed a machine-learning model in your Django application. Building the front-end aspects of your model makes it easier for it to reach a bigger and wider audience.