Posted in Internship, Machine Learning, Programming, Web Dev

Creating an ML Model and Serving it as a RESTful API: Part 2

This post is the continuation of the Model and API creation, so be sure to check out part 1 of this series first!

Part 2 of the series will be focused on creating a very simple web app that asks for Iris’s petal and sepal width and length. It will then make a call to the Iris Classification Model API to classify the type of Iris flower based on the given user data. The web app will be created in PHP and HTML, where it will be hosted in a local server.

Coding the Web App 🖥️

The web app contains four input fields to accept user data. Once the user clicks submit, it will call the API and return the predicted classification in JSON format.

To do that, we create a file called iris-app.php and enter the following PHP and HTML codes inside:

<?php
 $form = “
 <!DOCTYPE html>
 <html>
 <body>
 <h1>Iris Classification</h1>
 <form action=’iris-app.php’ method=’GET’>
 <p>Enter Sepal Length</p>
 <input type=’text’ name=’slength’/>
 <br/>
 <p>Enter Sepal Width</p>
 <input type=’text’ name=’swidth’/>
 <br/>
 <p>Enter Petal Length</p>
 <input type=’text’ name=’plength’/>
 <br/>
 <p>Enter Petal Width</p>
 <input type=’text’ name=’pwidth’/>
 <br/>
 <input type=’submit’ name=’Submit’/>
 <input type=’hidden’ name=’submitted’ value=’true’/>
 </form>
</body>
 </html>”;
echo $form;

Note the extra input tag below Submit. It will be used to notify the program that the form has been submitted.

It should look like this:

When the user clicks submit, it will redirect back to the same file as this is where we will be doing the API request. We then have to enclose the form in an if-else statement so that the request will only happen if the user clicks submit. If not, then the form will just keep showing itself.

The code will then be:

<?php
 if(isset($_GET[‘submitted’])){
 //API Request Goes Here
 }
 else{
   $form = “
   <!DOCTYPE html>
   <html>
    <body>
      <h1>Iris Classification</h1>
      <form action=’home.php’ method=’GET’>
        <p>Enter Sepal Length</p>
        <input type=’text’ name=’slength’/>
        <br/>
        <p>Enter Sepal Width</p>
        <input type=’text’ name=’swidth’/>
        <br/>
        <p>Enter Petal Length</p>
        <input type=’text’ name=’plength’/>
        <br/>
        <p>Enter Petal Width</p>
        <input type=’text’ name=’pwidth’/>
        <br/>
        <input type=’submit’ name=’Submit’/>
        <input type=’hidden’ name=’submitted’ value=’true’/>
      </form>
    </body>
  </html>”;
  echo $form;
}

The cURL library can be used to make HTTP requests in PHP. We use curl_init() to initialize a cURL session first, then only make the API request using curl_setopt() where it takes three parameters:

  • cURL_handler — returned when you initialized cURL using `curl_init()`
  • Option — the constant value for the setting to be changed. For this program, we use `CURLOPT_URL` as we want to pass a URL as the value in the third parameter
  • Value — the value to be used for the setting. In this case, we make a call to the API along with the user’s input as the query.

Once this is set, we send out the request using `curl_exec()` and finally close the cURL session using `curl_close`.

Full code is written below:

$swidth = $_GET[‘swidth’];
$slength = $_GET[‘slength’];
$pwidth = $_GET[‘pwidth’];
$plength = $_GET[‘plength’];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, “https://iris-classification-model.herokuapp.com/classify?swidth=".$swidth."&slength=".$slength."&pwidth=".$pwidth."&plength=".$plength);
$result = curl_exec($ch);
curl_close($ch);

And we’re done! If we run the program with these values:

We get the Iris classification as:

Hurrah! Now we have our Model API and interface 🎉!

Posted in Internship, Programming, Python

Creating an ML Model and Serving it as a RESTful API: Part 1

I started my internship at a local company that focuses on Data Science and Machine Learning and as part of my training, I was tasked to create a simple Iris Classification model that identifies the type of Iris category (Versicolor, Virginica and Setosa) based on the given petal and sepal width and length. Being someone who has minimal Machine Learning background, I needed a lot of research and reading in order to arrive at the required output, but it was all worth it.

In this post, I will be sharing the steps I did to create an Iris Classification model using Python and serve it through Flask RESTful API. I have also created a simple PHP interface that connects to the API to demonstrate its usage.

Model Creation 🤖

In Machine Learning, a model is trained using a set of data to recognize certain patterns. Python’s open-source Machine Learning library, Sci-Kit Learn, provides model training for supervised and unsupervised learning. It is simple to use and it has a lot of tutorials to get started with.

First, install Sci-Kit library using pip:

pip install -U scikit-learn

Once the installation is finished, create a file called `model.py` where Sci-Kit Learn’s already made Iris dataset can be used:

from sklearn import datasets
iris = datasets.load_iris()

*Note: You can use your own dataset but it needs to be preprocessed and formatted for Sci-Kit Learn to understand and train the model as efficiently as possible.

Next, the datasets are separated into data and target. Data consists of petal and sepal width and length in centimetres, while the target, or the label, is the class to predict. For the Iris classification, the target consists of Versicolor, Virginica and Setosa.

iris_data = iris.data
iris_target = iris.target

Before training the model, the data and target are split again so that the other half is used for the actual model training while the other is used for verifying the model (in other terms, testing the model’s accuracy).

This can be achieved using train_test_split:

from sklearn.model_selection import train_test_split
iris_data_train, iris_data_test, iris_target_train, iris_target_test = train_test_split(iris_data, iris_target, test_size = .5)

The test_size parameter specifies the size of the testing datasets.

Now, we can start building the model. There are many classification algorithms that can be used for this model, but I settled on K-Nearest Neighbors as the accuracy score is much higher.

from sklearn import neighbors
classifier = neighbors.KNeighborsClassifier()

From this, we can start training the model:

classifier.fit(iris_data_train, iris_target_train)

And there we have it! We have a trained Iris classification model. We can print the accuracy level of the model using accuracy_score:

from sklearn.metrics import accuracy_score
predict_iris = classifier.predict(iris_data_test)
print(accuracy_score(iris_target_test, predict_iris))
From the above, the model has an accuracy score of 97%! Great!

Creating Flask API ⚙️


Before we create the Flask API, the model needs to be serialized using a Python library called Pickle. By “pickling” a python code, it is converted into a byte stream for it to be easily sent over the network or saved on disk. “Unpickling” is the opposite, where it converts the python file into its original state.

Pickle can be installed using pip:

pip install pickle-mixin

Our Iris classification model can be “pickled” or serialized using the following code:

import pickle
pickle.dump(classifier, open(“iris_model”, “wb”))

This creates the iris_model file. If you try to open it, it will show indecipherable characters.

Now that we have our model pickled, we can now start with the Flask API!

Like the rest of the Python libraries, we install flask as well:

pip install flask

We then create our main app file called `app.py`. Inside, we import the libraries required for our Flask API:

from flask import Flask, jsonify
from flask_restful import reqparse, abort, Api, Resource
app = Flask(__name__)
api = Api(app)

Our Iris Classification model is then loaded and “unpickled”:

import pickle
loaded_model = pickle.load(open(“iris_model”, ‘rb’))

When we create the front-end interface later, we need a way to send over the user input to the Iris classification Flask API. In order to do that, we create parameters to the URL and we pass the user input there. The inputs we need are the petal and sepal width and length, and from this information, the model predicts what type of Iris flower we are referring to.

We create the parameters using the following code:

parser = reqparse.RequestParser()
parser.add_argument(‘slength’)
parser.add_argument(‘swidth’)
parser.add_argument(‘plength’)
parser.add_argument(‘pwidth’)

Once the queries are set, we need to call the model to predict the Iris type based on the given inputs. We then create a class called `requestIris` that takes the URL parameter values then insert it to the model for prediction. The predictions will come into integer format, so 0 is setosa, 1 is versicolor, and 2 is virginica. Also, note that the data returned should be in JSON format.

The full code is stated below:

class requestIris(Resource):
def get(self):
args = parser.parse_args()
slength= args[‘slength’]
swidth = args[“swidth”]
plength = args[“plength”]
pwidth = args[“pwidth”]
prediction = (loaded_model.predict([[slength, swidth, plength, pwidth]])).tolist()
if(prediction[0] == 0):
type=”setosa”
elif(prediction[0] == 1):
type=”versicolor”
else:
type=”virginica”
serve_model = {“Iris Type”:type}
print(serve_model)
return jsonify(serve_model)

We then add the resource to our API, and create a route for the resource:

api.add_resource(requestIris, ‘/classify’)

Last but not least, we add the code to run our Flask application:

if __name__ == ‘__main__’:
app.run()

Hurray! We have our Iris Classification API now!

The API can be run locally or published to Heroku. I published mine here:

https://iris-classification-model.herokuapp.com/

In the next post, I will be writing about the PHP frontend interface to demonstrate the API’s application. Stay tuned!

Posted in Family, Music, Programming, School Life

Thank You 2020!

Year 2020 had been the most unexpected year I ever had. A lot of things may have happened, but I wouldn’t say it’s the worst year for me. Sure, there’s the pandemic that caused almost a lot of planned activities to go unplanned and heartaches that resulted in wet pillow and puffy eyes, but there are always things to be grateful for.

Goodbye, 2020!

Developer Journey 💻

Firstly, I have achieved my goal to win Google Code-In programming competition. Although my prize trip to Google Headquarters in San Francisco, California was cancelled (and boy, it caused more tears than I ever shed), I get to have satisfactory alternative prizes. What’s more, it helped me gain confidence to join more hackathons and coding competitions, and I realized that I can actually do it.

Speaking of hackathons, 2020 also enabled me to focus more and join online hackathons that are held from the other parts of the world. I get to meet people with the same interests as I and helped me learn. I also get to win a 1-year hosting and domain name for my website portfolio from a hackathon that is sponsored by Qoom.

Last but not the least, I started learning PHP and Laravel Framework after being blessed with a part-time work as a freelance web developer! It’s challenging at first (considering I have college to focus to as well), but I got through it alright, and get to enjoy my first salary by buying donuts 😋.

Student Stuff 📝

College life changed pretty much for 2020. For one, we get to conduct lessons through online means because of the pandemic. Being a person who was homeschooled for the whole duration of my elementary and high school years, I’m used to studying at home, so there’s no problem with that. The biggest challenge with online classes is perhaps the group assignments, as they are “harder” to execute without face to face discussions.

As for the lessons, we get to study OOP concept using Java (the language I always try to learn but keeps procrastinating), and PHP lessons aren’t bad, especially my part-time work helped me understand the language more and put them into hands-on practice (though combining school and part-time do require more effort, time management, and sacrifice from too much gaming 😂).

One last thing to add, I got my results for my last semester this January 7, and I can happily say I got my third Dean’s list award 💖

Musical Hobby 🎹

Being in quarantine made it easier for me to play my piano, and at the same time, to NOT play it (my dad works at home so I can only play during his breaks). I’m happy that I get to play the songs I’ve been wanting to play, which includes the Voltes V Theme Song and Silhouette of a Breeze from Emma: A Victorian Romance anime.

Though youth choir at my local Church was postponed (thus, I cannot sing there for now), I was given a Karaoke Microphone for Christmas. Time to SIIIING!

Family Life 👪

Of course, I get to spend more time with my family because of the pandemic. They were the ones who helped me grab opportunities and comfort me during 2020’s heartaches. Even though outings are minimal, we get to have a nice picnic near the seaside every once in a while. Late night movies are also frequent, and I also get to learn new recipes to cook for my family!

Final Thoughts

Once again, 2020 is a lot, even if it’s mostly spent inside my house. As I welcome 2021 and continue improving in different aspects of my life, I won’t regret being a part of 2020’s adventures 😉