Turning Machine Learning Models into Products with Flask

Build an application for your model using REST APIs

Adrián González Carpintero
Towards Data Science

--

Photo by Carles Rabada on Unsplash

Introduction

In 1971, with just 21 years old, Steve Wozniak was already an incredible computer programmer and electronics engineer. He really enjoyed to spend his time creating weird devices and searching for improvements in his area. It was in 1971 when he met a 15 year old guy who would soon realize the enormous potential of what Wozniak was doing. This guy thought that the weird devices Wozniak created could become useful for many people. They worked together the following years, and 6 years later, they started to commercialize one of the first and most successful personal computers of its time: the Apple II.

The guy that convinced Wozniak to convert his devices into products was Steve Jobs. It is curious, because everybody knows who Steve Jobs is, but not many people have heard about Wozniak.

This post is not about the story behind Apple, but it is about turning technology into products.

When you spend a lot of time with notebooks and competitions, it seems that the Machine Learning picture is pretty simple: you create models that throw a metric. This metric explains how good your model is, so you have to improve the metric. Sometimes you have a threshold. Eventually you achieve this threshold. And once you achieve it, it means that the model is good enough so, job is done!

It turns that in a real environment this process is just the tip of the iceberg. We have to remember that at the end of the day, what we want to do is to create products that are useful for the people.

In this post I will develop a web application for a Machine Learning model. I will use Flask, a microframework where you can build a REST API in a simple way with Python code.

We will work with Adult Census Income Dataset. We will try to predict if a person earns more than 50k a year or not, thus we have a binary classification problem. As explanatory variables, we will use personal characteristics as age, sex, marital status and working hours per week.

We will use HTML for building the web application. I know many people reading this are not familiar with it, so if you are one of them, don’t worry! I am not an expert either so the code here is not a big deal. It is also worth mentioning that in this post I will focus on developing a REST API, so web development will take a secondary place.

this post is structured as follows: First we will define in an easy way the concepts we have to know before building a REST API. Then, I will explain the code step by step. You can find all the code used for this project in this repository.

That being said, let’s get to the point!

Key concepts behind REST API

To make things clear, I think first we have to answer some typical questions about REST APIs in order to understand what a REST API really is. These are short questions and answers that shouldn’t be a big deal to understand even if you are not familiar with the concept of REST API, so let’s go for it!

  • What is an API?

You can think of an API (Application Programming Interface) as software that connects programs, allowing them to communicate (send data).

  • What is REST?

REST can be defined as a set of specific rules that you follow when creating an API. It stands for REpresentational State Transfer, and is a stateless architecture that generally runs over HTTP.

  • What is the difference between REST and RESTful?

While REST refers to the architecture, RESTful refers to a web service that implements the REST architecture.

  • How does a RESTful API works?

What a RESTful API essentially does is send requests to obtain resources.

  • What is exactly a request?

When you make a request in HTTP you are asking the server for something. For doing a request you use HTTP methods. The most important methods are the following:

GET to fetch data.

PUT to alter (upload) data.

POST to create data.

DELETE to remove data.

As an example, when you go to http://www.google.com, you send the following:

GET / HTTP/1.1 
Host: www.google.com

This is a GET request where:

  1. GET is the verb
  2. / is the path
  3. HTTP/1.1 is the protocol
  • What is exactly a resource?

A resource is essentially data. For example, if you ask for your model predictions, the predictions, that can be some sort of data like a JSON file, will be the resource.

I think that with this key concepts in mind we are now ready to build a REST API with Flask, so let’s get down to business!

REST API implementation with Flask

Before going with the code, I think is necessary to first set the plan:

Essentially, we want to create an application that takes as inputs the different characteristics of and individual, and outputs the probability that the individual has to earn more than 50k a year given those characteristics.

Therefore, in the main page we will need to specify the inputs:

Image by Author

and once we submit them, the application will send us to a page where we can see the output:

Image by Author

The main files in the repository are the Python scripts. In model.py we will build our model while in server.py we will build the REST API.

I explain both scripts below.

Building the model

The first step is to create a model that makes predictions. For doing that, we first process the data:

Once we have the processed data, we can fit a model. I have chosen a logistic regression (it works pretty well).

📒NOTE: if you want to develop more complex models for this problem, you can take a look at this Kaggle notebook.

Once we have our model fitted, we have to create a function that does the following:

It takes as inputs single values for each of the explanatory variables, i.e., characteristics of an individual.

It outputs the probability the individual has to earn more than 50k given their characteristics (inputs).

As you may have noticed, our web application has the same inputs and the same output, thus this function is key for this project.

Building the REST API

In the script server.py we will develop the REST API.

We first import some libraries and create instances of the Flask class and the Api class.

Then we will create 2 classes. Both of them inherit the Resource class and both of them are composed of a function called get. If you remember, at the beginning we said that what a RESTful API basically does is use requests to obtain resources. As you might guess, the functions called get are requests that uses the GET method, and both of them will return resources.

The first one is pretty easy: it basically returns the HTML code used to make the application page where we set the inputs.

The second one gets the inputs defined by us in the web application and passes them to the predict_probability function that returns a probability. Finally, the get function returns the HTML code used to make the application page where the probability is showed.

Then we have to add the classes as resources. For doing that, we use the add_resource method, specifying the name of the class and the URL where they will go.

At the end of the script, we run the app.

📒NOTE: If you don’t know what the if(__name__=='__main__') does, here is an explanation: Python assigns the name __main__ to a script when it is executed. If the script is imported from another script, the script keeps its given name (not __main__). Therefore, using the if(__name__=='__main__') statement we make sure that the app is only run when we are executing the server.py script. Thus, if we are on another script and we import something from the server.py script, the app doesn't run. This is a common practice for avoiding undesired executions of code.

Besides the Python scripts, the repository also has other files that are worth mentioning:

  • adult.csv

This is the raw data. You can also access it in Kaggle.

  • requirements.txt

In is file you can see the packages I use in my environment for running the code. It is not mandatory to have the exactly same versions.

  • templates folder

Here I store the HTML code for building the web application. index.html has the code for building the main page (where we set the inputs) and output.html has the code for building the output page (where we see the probability).

📒NOTE: I have a limited knowledge of HTML, so I am sure that the code can be improved in many ways!

  • static folder

Here I store CSS code.

📒NOTE: If you haven’t heard of CSS, it is used to define styles for your web applications, so it helps the HTML code to make the web application look nicer.

Test the application

Once we know all the above, we can run our application. For doing that, open a terminal in the path of the root folder where you have the server.py script. Write python service.py to run service.py.

Once you run it you should see a line like this in the output:

* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

http://127.0.0.1:5000/ is the direction of your application.

127.0.0.1 is the IP of the localhost and 5000 is the port. Port 5000 is the default but you can specify any other using the app.run() method in server.py.

If you click on the URL, you should see the web application in your browser. Now you can play with it and check that everything works!

Conclusion

In this post, we have turned a Machine Learning model into a final product, so everyone can interact with it and extract value. As future work I suggest improving the application adding new functions like an option to store data in a Database (with SQLAlchemy), or a login system for users (with Flask-JWT).

I hope you have learned a lot! Thanks for reading!

References

REST APIs with Flask and Python, Jose Salvatierra

--

--