As a data scientist, you likely have experience building machine learning models. However, it’s the deployment of these models that transforms them into practical solutions. If you’re looking to deepen your knowledge about deploying machine learning models, this guide is designed for you.
The process of building and deploying machine learning models can be distilled into several key steps: developing the model, creating an API to serve predictions, containerizing the API, and deploying it in the cloud.
In this guide, we’ll cover the following:
- Building a machine learning model using Scikit-learn
- Creating a REST API to serve predictions with FastAPI
- Containerizing the API using Docker
We’ll build a simple regression model using the California housing dataset to predict house prices. By the end of this guide, you will have a containerized application that can deliver predictions based on user input.
Setting Up the Project Environment
Before beginning, ensure you have the following installed:
- A recent version of Python (preferably Python 3.11 or later)
- Docker for containerization (download the appropriate version for your OS)
⚙️ It’s beneficial to have a foundational understanding of machine learning model development and API usage as you follow along.
Project Structure
Here’s the recommended directory structure for your project:
project-dir/
│
├── app/
│ ├── __init__.py # Empty file
│ └── main.py # FastAPI code for the prediction API
│
├── model/
│ └── linear_regression_model.pkl # Saved trained model
│
├── model_training.py # Script to train and save the model
├── requirements.txt # Project dependencies
└── Dockerfile # Docker configuration
We’ll need a few Python libraries for this project. Let’s install them next.
In your project environment, create and activate a virtual environment:
$ python3 -m venv v1
$ source v1/bin/activate
The required packages for our project include Pandas and Scikit-learn for model building, along with FastAPI and Uvicorn for the API. Install these using pip:
$ pip3 install pandas scikit-learn fastapi uvicorn
You can find all the code for this tutorial on GitHub.
Building a Machine Learning Model
Next, we’ll train a linear regression model using Scikit-learn’s California Housing dataset, which will predict house prices based on selected features. Create a file named model_training.py
:
# model_training.py
import pandas as pd
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
import pickle
import os
# Load the dataset
data = fetch_california_housing(as_frame=True)
df = data['data']
target = data['target']
# Select features
selected_features = ['MedInc', 'AveRooms', 'AveOccup']
X = df[selected_features]
y = target
# Train-test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Train the model
model = LinearRegression()
model.fit(X_train, y_train)
# Create a 'model' directory to save the model
os.makedirs('model', exist_ok=True)
# Save the trained model
with open('model/linear_regression_model.pkl', 'wb') as f:
pickle.dump(model, f)
print("Model trained and saved successfully.")
The script loads the California housing dataset, selects three features (MedInc, AveRooms, AveOccup), trains a linear regression model, and saves it as linear_regression_model.pkl
in the model directory.
To train the model and save it, run:
$ python3 model_training.py
You should see the message confirming successful training and saving of the model.
Creating the FastAPI Application
Now, we will set up the API to serve predictions using FastAPI. In the app/
directory, create two files: __init__.py
(keep it empty) and main.py
:
In main.py
, write the following code:
# app/main.py
from fastapi import FastAPI
from pydantic import BaseModel
import pickle
import os
# Define the input data schema
class InputData(BaseModel):
MedInc: float
AveRooms: float
AveOccup: float
# Initialize FastAPI app
app = FastAPI(title="House Price Prediction API")
# Load the model at startup
model_path = os.path.join("model", "linear_regression_model.pkl")
with open(model_path, 'rb') as f:
model = pickle.load(f)
@app.post("/predict")
def predict(data: InputData):
input_features = [[data.MedInc, data.AveRooms, data.AveOccup]]
prediction = model.predict(input_features)
return {"predicted_house_price": prediction[0]}
This FastAPI application exposes a /predict
endpoint, allowing it to accept input data and return predicted house prices using the trained model.
Containerizing the Application with Docker
Next, we’ll containerize our FastAPI application. In the project root directory, create a Dockerfile
and a requirements.txt
file.
Creating the Dockerfile
Here’s what your Dockerfile should contain:
# Use Python 3.11 as the base image
FROM python:3.11-slim
# Set the working directory in the container
WORKDIR /code
# Copy the requirements file
COPY ./requirements.txt /code/requirements.txt
# Install the Python dependencies
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
# Copy the app folder into the container
COPY ./app /code/app
# Copy the model directory into the container
COPY ./model /code/model
# Expose port 80 for accessing the FastAPI app
EXPOSE 80
# Command to run the FastAPI app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
This configuration creates a lightweight container for your FastAPI application using Python 3.11 as the base, setting the working directory to /code
, installing dependencies, and exposing port 80 for the FastAPI application.
Creating the requirements.txt File
Add the following dependencies to your requirements.txt
file:
fastapi
uvicorn
scikit-learn
pandas
Building the Docker Image
With your Dockerfile, requirements.txt
, and FastAPI application in place, you can build the Docker image and run the container.
Dockerizing the API
Execute the following command to build the Docker image:
$ docker build -t house-price-prediction-api .
Then, run the Docker container:
$ docker run -d -p 80:80 house-price-prediction-api
Your API should now be operational and accessible at http://127.0.0.1:80
.
To test the /predict
endpoint using Postman or curl, send a POST request with the following example:
curl -X 'POST' \
'http://127.0.0.1:80/predict' \
-H 'Content-Type: application/json' \
-d '{
"MedInc": 3.5,
"AveRooms": 5.0,
"AveOccup": 2.0
}'
You should receive a response containing the predicted house price, such as:
{
"predicted_house_price": 2.3248705765077062
}
Tagging and Pushing the Docker Image to Docker Hub
After building the image, running the container, and testing it, you can push it to Docker Hub for easier sharing and deployment to cloud platforms.
First, log in to Docker Hub:
$ docker login
Enter your credentials when prompted.
Next, tag the Docker image:
$ docker tag house-price-prediction-api your_username/house-price-prediction-api:v1
Be sure to replace your_username
with your actual Docker Hub username.
Note: It’s also wise to version your model files. By adding iteration numbers to your model, you can rebuild and push updated images as needed.
Now, push the image to Docker Hub:
$ docker push your_username/house-price-prediction-api:v1
Other developers can pull and run your image with:
$ docker pull your_username/house-price-prediction-api:v1
$ docker run -d -p 80:80 your_username/house-price-prediction-api:v1
Anyone with access to your Docker Hub repository can now easily pull the image and run the container.
Wrap-Up and Next Steps
In summary, this tutorial has guided you through the following steps:
- Training a machine learning model using Scikit-learn
- Building a FastAPI application to serve predictions
- Containerizing the application with Docker
- Pushing the Docker image to Docker Hub for distribution
The next logical step is deploying this containerized application to the cloud using platforms like AWS ECS, Google Cloud Platform, or Azure. If you’re interested, let us know if you’d like a tutorial on deploying machine learning models to the cloud.
Let me know if you need any further modifications or additional content!