DEV Community

Cover image for How to Turn Your Python Machine Learning Code Into a Web App
Code_Jedi
Code_Jedi

Posted on • Updated on

How to Turn Your Python Machine Learning Code Into a Web App

What if I told you that there's an easy way to turn your Python Machine Learning code into an interactive Web App?


Installing Pandas, Sklearn, Numpy and Flask

For the ML code in this tutorial, you'll need to install:

  1. Pandas ==> pip3 install pandas
  2. Sklearn ==> pip3 install sklearn
  3. Numpy ==> pip3 install numpy

After installing the above libraries, in order to turn your Python ML code into a Web App, you must install the flask library through pip3 install flask.


Before I start going over how our Machine Learning Web App is going to work, for anyone who just wants the code, here's the github repo.


How it's going to work

Here's how our Web App is going to work:

  1. It will display an HTML page containing a form
  2. The user will input values into the form which will then be used to make a prediction.
  3. A Python file will process the input and display a prediction.

Sample Machine Learning code

For this tutorial and for simplicity's sake, I'll be using the following classification model.
ml.py

import pandas as pd
from sklearn.linear_model import LinearRegression
import pickle
import pandas
from sklearn.neighbors import KNeighborsClassifier


df = pandas.read_csv('IRIS.csv')
model = KNeighborsClassifier(n_neighbors=3)

features = list(zip(df["sepal_length"], df["sepal_width"]))

model.fit(features,df["species"])
pickle.dump(model, open('model.pkl','wb'))
Enter fullscreen mode Exit fullscreen mode

I've named this file ml.py for simplicity, but you can name it whatever you want.
You can download the dataset i'm using here

What this code does is it trains a classification model on our iris dataset and saves the model in a .pkl file using Pickle. Pickle files are basically binary files and the Python Pickle module is used for serializing and de-serializing Python object structures(list, dict, etc.) into byte streams (0s and 1s). This file will then be used by our Web App every time someone tries to predict an iris species through it.

After executing ml.py using python3 ml.py, you will see that a model.pkl file has been created in your directory.


Creating an HTML interface for the Web App

In order for our Web App to work, we're going to need to have a user interface. Create a templates folder in your directory. After that's done, create an index.html file inside the templates directory and add the following HTML code.

<!DOCTYPE html>
<html >

<head>
  <meta charset="UTF-8">
  <title>Iris Predictor</title>

</head>

<body>
 <div>
    <h1>Iris Predictor</h1>

    <form action="{{ url_for('predict')}}"method="post">
        <input type="text" name="length" placeholder="sepal length" required="required" />
        <input type="text" name="width" placeholder="sepal width" required="required" />

        <button type="submit" class="btn">Predict</button>
    </form>

   <br>
   <br>
   <b>{{ prediction_text }}</b>

 </div>


</body>
</html>
Enter fullscreen mode Exit fullscreen mode

You're probably wondering what those double curly brackets are for. The ones in {{ url_for('predict')}} indicate where the inputted form values will be sent to, and the ones inside the <b> tag indicate where our Flask code is going to display it's predictions.


Making the Flask code

We're going to have to make another file, which I will call app.py for this tutorial, that will use our model to create an ML Web App.
app.py

import numpy as np
from flask import Flask, request, jsonify, render_template
import pickle

app = Flask(__name__)
model = pickle.load(open('model.pkl', 'rb'))# loads ML model

@app.route('/')
def home():
    return render_template('index.html')# renders index.html

@app.route('/predict',methods=['POST'])# gets the values that were sent to '/predict' by 'index.html'
def predict():
    int_features = [float(x) for x in request.form.values()]# defines the form values in an array
    final_features = [np.array(int_features)]# turns the form values into a Numpy array
    prediction = model.predict(final_features)# makes a prediction using the values in the created Numpy array

    output = prediction[0]# gets the prediction as a string

    return render_template('index.html', prediction_text='Iris species: {}'.format(output))# displays the prediction inside the '<b>{{ prediction_text }}</b>' that we've seen in 'index.html'

if __name__ == "__main__":
    app.run(debug=True)# Runs the Web App

Enter fullscreen mode Exit fullscreen mode

Here's what this code does in a nutshell

  1. It loads the classification model we've saved earlier in model.pkl.
  2. It renders the HTML we've defined in the templates/index.html file.
  3. It takes in the entered form parameters and uses them to make a prediction.

Running the Web App

Now that you have all the code, it's time you see if it works.
Supposing your Flask code is in app.py run python3 app.py in your directory.
Here's what you should see:
App Info

Open a tab on localhost:5000 and you'll see your index.html webpage. Enter number values into the two input elements, click submit and you'll see that your Machine Learning code has made a prediction and displayed it on a webpage!

The Web App in action



Conclusion

I hope that this article was helpful. Just note that there's more that needs to be done if you want to turn such a Web App into a public SaaS like security and style, but this code is everything you need to make a Machine Learning Web App. What I've shown here obviously isn't limited to classification models and can be implemented into other machine learning models such as linear regression.

'Till next time👋

Top comments (2)

Collapse
 
chusteven profile image
Steven Chu • Edited

This is fun :) I've really been wanting to host this algorithm online just for giggles: github.com/facebookresearch/DrQA

EDIT: Looks like there is a link to an existing implementation of a web UI-based version already! github.com/zaghaghi/drqa-webui

Collapse
 
gordontytler profile image
gordontytler

Thanks for this excellent article. I can't think how you could make it any simpler.

I used this as an example to create a web service for my scikeras.wrappers.KerasClassifier. I had a couple of problems with it though. When the Java client was running a single thread it was using progressively more memory over time - upto several GB. When running with multiple threads it only worked for 2 minutes then stopped responding. Is this normal for flask under a heavy load or something in my code?

import numpy as np
import pandas as pd
from scikeras.wrappers import KerasClassifier
from tensorflow import keras
from flask import Flask, request, jsonify, render_template
import logging

app = Flask(__name__)

prices = pd.read_csv("../betting/price_pandas.csv")
# code to convert prices into X, Y omitted
X_test, y_test =  X[33000:], y[33000:]

path = "./football-classification-numpy_best_model_n_neurons"

clf_model = keras.models.load_model(path)
clf = KerasClassifier(clf_model)
clf.initialize(X_test, y_test)

@app.route('/')
def home():
    return render_template('index.html')

@app.route('/predict',methods=['POST'])
def predict():
    # the request body is a string of comma separated prices
    data = request.get_data(as_text=True) 
    data_list = [float(x) for x in data.split(",")]
    data_np = np.array(data_list).reshape(1, -1)
    y_proba = clf.predict_proba(data_np)
    app.logger.info(y_proba)
    output = y_proba

    return render_template('index.html', prediction_text=output)

if __name__ == "__main__":
    app.run(debug=True)# Runs the Web App

Enter fullscreen mode Exit fullscreen mode