|
3 weeks ago | |
---|---|---|
.. | ||
solution | 3 weeks ago | |
README.md | 3 weeks ago | |
assignment.md | 3 weeks ago | |
notebook.ipynb | 3 weeks ago |
README.md
Build a Web App to use a ML Model
In this lesson, you will train a machine learning model using a fascinating dataset: UFO sightings over the past century, sourced from NUFORC's database.
You will learn:
- How to save a trained model using 'pickle'
- How to integrate that model into a Flask web application
We'll continue using notebooks to clean data and train our model, but we'll take it a step further by exploring how to use the model in a real-world scenario: a web app.
To achieve this, you'll need to build a web app using Flask.
Pre-lecture quiz
Building an app
There are multiple ways to create web apps that utilize machine learning models. The architecture of your web app may influence how the model is trained. Imagine you're working in a company where the data science team has trained a model, and they want you to integrate it into an app.
Considerations
Here are some important questions to consider:
- Is it a web app or a mobile app? If you're building a mobile app or need to use the model in an IoT context, you could use TensorFlow Lite to integrate the model into an Android or iOS app.
- Where will the model be hosted? Will it reside in the cloud or locally?
- Offline support. Does the app need to function offline?
- What technology was used to train the model? The technology used may dictate the tools required for integration.
- Using TensorFlow. If the model was trained using TensorFlow, you can convert it for use in a web app with TensorFlow.js.
- Using PyTorch. If the model was built using PyTorch, you can export it in ONNX (Open Neural Network Exchange) format for use in JavaScript web apps with Onnx Runtime. This approach will be covered in a future lesson for a Scikit-learn-trained model.
- Using Lobe.ai or Azure Custom Vision. If you used an ML SaaS platform like Lobe.ai or Azure Custom Vision, these tools provide options to export the model for various platforms, including creating a custom API for cloud-based queries.
You could also build a complete Flask web app capable of training the model directly in a web browser. This can be achieved using TensorFlow.js in a JavaScript environment.
For this lesson, since we've been working with Python-based notebooks, we'll focus on exporting a trained model from a notebook into a format that can be used in a Python-built web app.
Tool
To complete this task, you'll need two tools: Flask and Pickle, both of which run on Python.
✅ What is Flask? Flask is a lightweight web framework for Python that provides essential features for building web applications, including a templating engine for creating web pages. Check out this Learn module to practice working with Flask.
✅ What is Pickle? Pickle 🥒 is a Python module used to serialize and deserialize Python object structures. When you 'pickle' a model, you flatten its structure for use in a web app. Be cautious: Pickle is not inherently secure, so exercise caution when prompted to 'un-pickle' a file. Pickled files typically have the .pkl
extension.
Exercise - clean your data
In this lesson, you'll work with data from 80,000 UFO sightings collected by NUFORC (The National UFO Reporting Center). The dataset includes intriguing descriptions of UFO sightings, such as:
- Long example description. "A man emerges from a beam of light that shines on a grassy field at night and he runs towards the Texas Instruments parking lot."
- Short example description. "The lights chased us."
The ufos.csv spreadsheet contains columns for the city
, state
, and country
where the sighting occurred, the object's shape
, and its latitude
and longitude
.
In the blank notebook provided in this lesson:
-
Import
pandas
,matplotlib
, andnumpy
as you did in previous lessons, and load the UFO dataset. Here's a sample of the data:import pandas as pd import numpy as np ufos = pd.read_csv('./data/ufos.csv') ufos.head()
-
Convert the UFO data into a smaller dataframe with updated column names. Check the unique values in the
Country
field.ufos = pd.DataFrame({'Seconds': ufos['duration (seconds)'], 'Country': ufos['country'],'Latitude': ufos['latitude'],'Longitude': ufos['longitude']}) ufos.Country.unique()
-
Reduce the dataset by removing rows with null values and filtering sightings that lasted between 1-60 seconds:
ufos.dropna(inplace=True) ufos = ufos[(ufos['Seconds'] >= 1) & (ufos['Seconds'] <= 60)] ufos.info()
-
Use Scikit-learn's
LabelEncoder
library to convert text values in theCountry
column into numeric values:✅ LabelEncoder encodes data alphabetically.
from sklearn.preprocessing import LabelEncoder ufos['Country'] = LabelEncoder().fit_transform(ufos['Country']) ufos.head()
Your cleaned data should look like this:
Seconds Country Latitude Longitude 2 20.0 3 53.200000 -2.916667 3 20.0 4 28.978333 -96.645833 14 30.0 4 35.823889 -80.253611 23 60.0 4 45.582778 -122.352222 24 3.0 3 51.783333 -0.783333
Exercise - build your model
Now, divide the data into training and testing sets to prepare for model training.
-
Select three features for your X vector, and use the
Country
column as your y vector. The goal is to inputSeconds
,Latitude
, andLongitude
to predict a country ID.from sklearn.model_selection import train_test_split Selected_features = ['Seconds','Latitude','Longitude'] X = ufos[Selected_features] y = ufos['Country'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
-
Train your model using logistic regression:
from sklearn.metrics import accuracy_score, classification_report from sklearn.linear_model import LogisticRegression model = LogisticRegression() model.fit(X_train, y_train) predictions = model.predict(X_test) print(classification_report(y_test, predictions)) print('Predicted labels: ', predictions) print('Accuracy: ', accuracy_score(y_test, predictions))
The accuracy is quite good (around 95%), which is expected since Country
correlates strongly with Latitude
and Longitude
.
While the model isn't groundbreaking—predicting a Country
from its Latitude
and Longitude
is straightforward—it serves as a valuable exercise in cleaning data, training a model, exporting it, and using it in a web app.
Exercise - 'pickle' your model
Next, save your trained model using Pickle. After pickling the model, load it and test it with a sample data array containing values for seconds, latitude, and longitude:
import pickle
model_filename = 'ufo-model.pkl'
pickle.dump(model, open(model_filename,'wb'))
model = pickle.load(open('ufo-model.pkl','rb'))
print(model.predict([[50,44,-12]]))
The model predicts '3', which corresponds to the UK. Fascinating! 👽
Exercise - build a Flask app
Now, create a Flask app to call your model and display results in a user-friendly format.
-
Start by creating a folder named web-app next to the notebook.ipynb file where your ufo-model.pkl file is located.
-
Inside the web-app folder, create three subfolders: static (with a css folder inside) and templates. Your directory structure should look like this:
web-app/ static/ css/ templates/ notebook.ipynb ufo-model.pkl
✅ Refer to the solution folder for a completed app example.
-
Create a requirements.txt file in the web-app folder. This file lists the app's dependencies, similar to package.json in JavaScript apps. Add the following lines to requirements.txt:
scikit-learn pandas numpy flask
-
Navigate to the web-app folder and run the following command:
cd web-app
-
Install the libraries listed in requirements.txt by typing
pip install
in your terminal:pip install -r requirements.txt
-
Create three additional files to complete the app:
- app.py in the root directory.
- index.html in the templates folder.
- styles.css in the static/css folder.
-
Add some basic styles to the styles.css file:
body { width: 100%; height: 100%; font-family: 'Helvetica'; background: black; color: #fff; text-align: center; letter-spacing: 1.4px; font-size: 30px; } input { min-width: 150px; } .grid { width: 300px; border: 1px solid #2d2d2d; display: grid; justify-content: center; margin: 20px auto; } .box { color: #fff; background: #2d2d2d; padding: 12px; display: inline-block; }
-
Build the index.html file:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>🛸 UFO Appearance Prediction! 👽</title> <link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}"> </head> <body> <div class="grid"> <div class="box"> <p>According to the number of seconds, latitude and longitude, which country is likely to have reported seeing a UFO?</p> <form action="{{ url_for('predict')}}" method="post"> <input type="number" name="seconds" placeholder="Seconds" required="required" min="0" max="60" /> <input type="text" name="latitude" placeholder="Latitude" required="required" /> <input type="text" name="longitude" placeholder="Longitude" required="required" /> <button type="submit" class="btn">Predict country where the UFO is seen</button> </form> <p>{{ prediction_text }}</p> </div> </div> </body> </html>
Notice the templating syntax in this file. Variables provided by the app, such as the prediction text, are enclosed in
{{}}
. The form posts data to the/predict
route. -
Finally, create the Python file that handles the model and displays predictions:
import numpy as np from flask import Flask, request, render_template import pickle app = Flask(__name__) model = pickle.load(open("./ufo-model.pkl", "rb")) @app.route("/") def home(): return render_template("index.html") @app.route("/predict", methods=["POST"]) def predict(): int_features = [int(x) for x in request.form.values()] final_features = [np.array(int_features)] prediction = model.predict(final_features) output = prediction[0] countries = ["Australia", "Canada", "Germany", "UK", "US"] return render_template( "index.html", prediction_text="Likely country: {}".format(countries[output]) ) if __name__ == "__main__": app.run(debug=True)
💡 Tip: Adding
debug=True
while running the Flask app allows you to see changes immediately without restarting the server. However, avoid enabling this mode in production.
Run python app.py
or python3 app.py
to start your local web server. You can then fill out the form to discover where UFOs have been sighted!
Before testing the app, review the structure of app.py
:
- Dependencies are loaded, and the app is initialized.
- The model is imported.
- The home route renders the
index.html
file.
On the /predict
route, the following occurs when the form is submitted:
- Form variables are collected and converted into a numpy array. The array is sent to the model, which returns a prediction.
- Predicted country codes are converted into readable text and sent back to
index.html
for display.
Using a model with Flask and Pickle is relatively simple. The key challenge is understanding the data format required by the model for predictions, which depends on how the model was trained. In this case, three data points are needed for predictions.
In a professional setting, clear communication between the team training the model and the team integrating it into an app is crucial. In this lesson, you're both teams!
🚀 Challenge
Instead of training the model in a notebook and importing it into the Flask app, try training the model directly within the Flask app on a route called train
. What are the advantages and disadvantages of this approach?
Post-lecture quiz
Review & Self Study
There are various ways to build a web app that utilizes machine learning models. Make a list of methods for using JavaScript or Python to create such an app. Consider the architecture: should the model reside in the app or in the cloud? If hosted in the cloud, how would you access it? Sketch an architectural diagram for an applied ML web solution.
Assignment
Disclaimer:
This document has been translated using the AI translation service Co-op Translator. While we aim for accuracy, please note that automated translations may include errors or inaccuracies. The original document in its native language should be regarded as the authoritative source. For critical information, professional human translation is advised. We are not responsible for any misunderstandings or misinterpretations resulting from the use of this translation.