Grade Predictor Deployment with Flask and Heroku

袁晗 | Luo, Yuan Han
8 min readFeb 17, 2021
JAKER5000 https://www.teenvogue.com/story/why-teachers-getting-rid-grades

Methodology:

  1. Introduction
  2. Data
  3. EDA
  4. Data Engineering/cleaning
  5. Model Building
  6. Test
  7. Deployment
  8. Conclusion
  1. Introduction

The focus of this project is the last chapter of a data science project: Model deployment. So the rest of the steps will be very brief, but I will still go over them nevertheless. If you are only interested in model deployment, feel free to skip to section 7.

This time our goal is to predict a high school student’s final grade via its social economic standing and some school related features. Although the data came from a small sample size, the process of training a model to predict the students performance should be universally applicable to the education sector. Lastly, since the final grade is a quantitative value between 0 to 20, this is a regression problem.

2. Data

The data set came from Paulo Cortez, University of Minho and hosted on University of California Irvine machine learning repository website: https://archive.ics.uci.edu/ml/datasets/Student+Performance. It has 649 instances and 33 features including the dependent feature G3 (final grade). Now let’s crack the dataset open and see what we have.

3. EDA

The target feature “G3” has a bimodal distribution. I will address this later on in a feature engineering section.

Some categorical features show a strong correlation such as ‘studytime’, ‘failures’, and ‘higher’.

Quantitative features, such as ‘G1’ and ‘G2’, have the strongest correlations.

4. Data Engineering/cleaning

There are 4 steps in this section: cleaning, outliers handling, binning, and binary transformation.

Average G3 score of ‘yes’ or ‘no’ famsup via df.groupby([‘famsup’])[‘G3’].mean().to_frame()

First, weak correlated features, such as ‘famsup’ or alike, will be dropped.

df = df[df[‘G3’] > 0]

Second, we are going to use one of the many techniques to handle outliers: cap the data off where G3 score is greater than 0. Not only this will turn the skewness and kurtosis to the acceptable range, it also gives better results with test data that has not been used to train our models.

df[‘guardian’] = df[‘guardian’].replace({‘father’: “with_parents”, ‘mother’: “with_parents”, ‘other’: “without_parents”})

Third, since the mean G3 score between father and mother is relatively close I will bin them together as a new category: ‘with_parents’.

df[‘guardian’] = df[‘guardian’].replace({‘with_parents’: 1, ‘without_parents’: 0})

The last step is to transform the string values into integer values. This results in a slightly better RMSE score. I only showed the feature engineering of ‘guardian’, but most other features that did not get deleted goes through the same process as ‘guardian’.

These are the basic 4 steps I took to feature engineering. Although I would like to talk more about bimodal distribution and why I didn’t use one hot-encoding instead, each of these subjects are out of the scope and deserves an article of its own. I will try to find time and make separate projects focusing on them individually.

5. Model Building

Model building is fairly straight forward and since I didn’t do anything extra fancy I won’t go too deep into it.

Model building is relatively standard in my projects. The only thing I didn’t show from my previous articles is hyper parameter tuning.

Also, always keep in mind this is a regression problem so models, such as linear regression, will be used instead of models like decision tree. If you are not sure what models to use, sklearn website has a very good documentation to explain each models.

6. Testing

The only thing I will say in testing is that certain metrics are used for regression problems, others, such as confusion metrics or F1 score, are used for classification. If you ever wondered why some previous works has F1 or confusion metrics while others have graphs, such as the current project, this is the reason.

7. Deployment

OK (deep breath), now finally we are on deployment. First I have to give a shout out to 2 sources that I found to be very useful: https://www.youtube.com/watch?v=mrExsjcvF4o&t=378s by Krish Naik and https://www.youtube.com/watch?v=nUOh_lDMHOU&t=1231s by Ken Lee. If you have not yet subscribed to them, do yourself a favor and subscribe now. They are straight to the point, big picture oriented, and focusing on the actual codes. I know that sounds like a no brainer but you have no idea how many hours I have wasted only to ask my self at the end what did I just read or watched. Now that’s out of the way lets get to the code.

Before we start, you will need to install the anaconda package for all this to work. There are total of 4 parts to deployment: pickle model, create app file, create procfile, create requirement file.

First thing you have to do is use the pickle library, which is included in the anaconda package, to pickle the model that gives the best performance.

The only new things here from typical data science works are importing pickle library, the dump method (create .pkl file), and the load method to make sure that file you just created works.

Ok, the reason why we have to create a separate file with extension of pkl is beyond me. Feel free to google it and let me know once you find out. What I do know is that when we need to import our model to make a prediction from the input received from the API end point of the user, we cannot load our model from the python (.py) file where we have all our codes. Instead, we have to import the model from the .pkl file with no python codes. And in case you wonder what this .pkl file with no codes looks like, I took a snip.

Second thing you have to do is create an app.py file. This step is your typical web app dev process so you can skip to requirement and procfile section if you are already familiar with it. If not, I will briefly go over the codes so you can fork a copy and customize it to your fitting or you can go to the flask website and take a deep dive.

Obviously we first import the Flask class so we can have the app variable to inherent its properties where we will later use it to render webpages for us. Next, we load the model with .pkl extension that we created with the dump mehod earlier. Now we can write the routes: home page and predict page. Whatever html template you are using, just make sure that you add action= “{{url_for(‘predict’)}}” method=“post” to the form tab that requests information from your user so that “/predict” will be added to the route after you trigger the button within the form.

Last thing to explain is the request method from flask. The purpose of request.form.values() is to collect the input from the user to make prediction. But before sending it to our model, don’t forget to turn it into a 2 dimensional array because we trained our model to take 2 dimensional array as input. Like I mentioned before, this is a quick and oversimplified version of the explanation to get your codes running. I recommend going over Krish and Ken’s videos and read some documentation from flask to get a firm grasp. Now let’s talk about requirement and Procfile.

The purpose of requirements and Procfile is to tell Heroku what is needed and what file to read.

Just as JSON file in web app dev tells what libraries have been used and require to run the app, the requirement.txt tells Heroku what libraries are needed to deploy your model. Make sure you add all the libraries you used in your project and the concurrent version.

The Procfile tells Heroku to read the app file first to run the app.

The last step is to push your files on to github and create a Heroku account. I assume you already know how to push files onto github so I will jump to how to deploy from Heroku.

First you will have to create a Heroku account like everything in the universe nowadays.

After you done that, go to the deploy section where I highlighted above and hit the connect to github deployment method.

Now you should be able to find your github account and your repository name and click search and connect once you find your project.

After it’s connected, scroll down to the bottom (Manual deploy) and hit deploy branch.

If everything worked properly (cross my fingers), you should see this screen above. Now this my friend, means your machine learning model has been deployed.

8. Conclusion

Before we wrap up, there are few things you should know. Although the Heroku account is free, it only allows you to deploy one app at a time. Second, I am lucky enough that the dataset works with minor data engineering to fit a relatively good model so I don’t have to manipulate user input. However, datasets with heavier alterations will require you to transform user input in a much bigger scale. The key is to transform user input into the panda data frame (or whichever data frame you are used to)first and then data engineer it the same way you did to the training data. Lastly, this project elicit a single row of input, it is probably wise to also be familiar with collecting a whole file of inputs, since different industries and roles has different needs. I might make a project base on that later. With that said, thank you again for reading this and I hope you learned something.

--

--