How to Turn Your Python Machine Learning Code Into a Web App
Tags: webdev, tutorial, python, machinelearning
Published: 2022-02-27 11:46:48

**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](https://github.com/matveynikon/ML_WebApp)**.

*****************
##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**
```Python
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'))
```
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](https://github.com/matveynikon/ML_WebApp/blob/main/IRIS.csv)_

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](https://www.merriam-webster.com/dictionary/serialize) 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.
```HTML
<!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>
```
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**
```Python
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

```
**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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fhlk59wrlmaovxkjm2qv.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8xzntme0zszq6poncelw.gif)

****************
****************
#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👋**