1746743497434_img

Introduction

Amazon SageMaker provides a comprehensive platform for building, training, and deploying machine learning models at scale. In this blog post, we’ll walk through a practical implementation of XGBoost, a powerful gradient boosting framework, to build a regression model using the classic Abalone dataset.

In this tutorial, we’ll walk through the process of building, training, and evaluating an XGBoost regression model using Amazon SageMaker. We’ll use the classic Abalone dataset to predict the age of abalone sea creatures based on physical measurements.

⚠️Important Note on AWS Costs: Please note that following these steps in AWS might incur charges to your account. Be mindful of the resources you create and always remember to clean up ALL associated resources.

Cell 1: Import Libraries and Set Up Environment

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import sagemaker
import boto3
from sagemaker import get_execution_role

# Set up the SageMaker environment
role = get_execution_role()
session = sagemaker.Session()
bucket = session.default_bucket()
prefix = 'sagemaker/xgboost-abalone'

In this first cell, we import the necessary Python libraries and set up our SageMaker environment. The get_execution_role() function retrieves the IAM role that SageMaker will use to access AWS resources. We also create a SageMaker session and specify the S3 bucket and prefix where our data and model artifacts will be stored.

Cell 2: Download and Prepare the Dataset

# Download and prepare the Abalone dataset
!wget --no-check-certificate https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/regression/abalone
!aws s3 cp abalone s3://{bucket}/{prefix}/data/

Here, we download the Abalone dataset in LibSVM format and upload it to our S3 bucket. This dataset contains physical measurements of abalone sea creatures, and the task is to predict their age (represented by the number of rings + 1.5).

Cell 3: Parse the LibSVM Format Data

# Parse the libsvm format data
def parse_libsvm(filename):
    data = []
    with open(filename, 'r') as f:
        for line in f:
            parts = line.strip().split()
            label = float(parts[0])
            features = {}
            for item in parts[1:]:
                idx, val = item.split(':')
                features[int(idx)] = float(val)
            data.append((label, features))
    return data

# Parse the data
all_data = parse_libsvm('abalone')

The Abalone dataset is in LibSVM format, which is a sparse format where each line represents a sample. The first value is the label (target variable), and the remaining values are feature index:value pairs. Our parse_libsvm function converts this format into a list of (label, features) tuples, where features is a dictionary mapping feature indices to values.

Cell 4: Split Data into Train and Test Sets

# Split into train and test sets
from sklearn.model_selection import train_test_split
np.random.seed(42)  # For reproducibility
indices = np.arange(len(all_data))
train_indices, test_indices = train_test_split(indices, test_size=0.2)

train_data = [all_data[i] for i in train_indices]
test_data = [all_data[i] for i in test_indices]

We split our data into training (80%) and testing (20%) sets using scikit-learn’s train_test_split function. Setting a random seed ensures reproducibility of our results.

Cell 5: Prepare Test Data for Evaluation

# Prepare test data for later use
test_labels = [item[0] for item in test_data]
test_features = []
for item in test_data:
    # Convert sparse features to dense format
    features = []
    for i in range(1, 9):  # Assuming 8 features in the Abalone dataset
        features.append(item[1].get(i, 0.0))
    test_features.append(features)

# Convert to numpy arrays
test_features = np.array(test_features)
test_labels = np.array(test_labels)

To evaluate our model later, we need to prepare our test data in a format suitable for prediction. We extract the labels (target values) and convert the sparse feature representation to a dense format, assuming the Abalone dataset has 8 features.

Cell 6: Configure and Train the XGBoost Model

# Train the XGBoost model
container = sagemaker.image_uris.retrieve("xgboost", boto3.Session().region_name, "1.0-1")

xgb = sagemaker.estimator.Estimator(
    container,
    role,
    instance_count=1,
    instance_type='ml.m5.xlarge',
    output_path=f's3://{bucket}/{prefix}/output',
    sagemaker_session=session
)

xgb.set_hyperparameters(
    max_depth=5,
    eta=0.2,
    gamma=4,
    min_child_weight=6,
    subsample=0.8,
    objective='reg:squarederror',
    num_round=100
)

train_input = sagemaker.inputs.TrainingInput(
    s3_data=f's3://{bucket}/{prefix}/data',
    content_type='libsvm'
)

Here, we configure our XGBoost model using SageMaker’s built-in XGBoost algorithm. We:

  1. Retrieve the appropriate container image for XGBoost
  2. Create an Estimator object that specifies the training infrastructure (instance type and count)
  3. Set hyperparameters for the XGBoost algorithm
  4. Define the training data input

The hyperparameters we’ve set include:

  • max_depth=5: Controls the maximum depth of each decision tree
  • eta=0.2: Learning rate, which controls how aggressively the model fits the residual errors
  • gamma=4: Minimum loss reduction required for a split
  • min_child_weight=6: Minimum sum of instance weights needed in a child node
  • subsample=0.8: Fraction of samples used for training each tree
  • objective='reg:squarederror': Loss function (squared error for regression)
  • num_round=100: Number of boosting rounds (equivalent to epochs in neural networks)

Cell 7: Start the Training Job

# Start training
xgb.fit({'train': train_input})

This cell launches the actual training job. SageMaker will:

  1. Provision the specified ML instance
  2. Download the training data from S3
  3. Train the XGBoost model with the specified hyperparameters
  4. Save the model artifacts back to S3

The model artifacts are stored at the location specified by output_path in the Estimator configuration. For our example, they would be at s3://{bucket}/sagemaker/xgboost-abalone/output/{training-job-name}/output/model.tar.gz.

Cell 8: Deploy the Model as an Endpoint

# Deploy the model as an endpoint
predictor = xgb.deploy(
    initial_instance_count=1,
    instance_type='ml.m5.large'
)

# Configure input format
from sagemaker.serializers import CSVSerializer
predictor.serializer = CSVSerializer()

After training, we deploy our model as a real-time endpoint for making predictions. SageMaker:

  1. Creates a model in the SageMaker model registry
  2. Configures an endpoint with the specified instance type and count
  3. Returns a predictor object that we can use to make predictions

We also configure the predictor to accept CSV-formatted input data.

Cell 9: Make Predictions on Test Data

# Make predictions using the deployed model
predictions = []
for features in test_features:
    # Format the features as a CSV string
    features_csv = ','.join(map(str, features))
    # Get prediction
    result = predictor.predict(features_csv).decode('utf-8')
    predictions.append(float(result))

predictions = np.array(predictions)

Now we use our deployed model to make predictions on the test data. For each sample in our test set:

  1. We convert the feature vector to a CSV string
  2. Send it to the endpoint for prediction
  3. Decode and store the result

Cell 10: Calculate Performance Metrics

# Calculate metrics
actual = test_labels
mse = mean_squared_error(actual, predictions)
rmse = np.sqrt(mse)
mae = mean_absolute_error(actual, predictions)
r2 = r2_score(actual, predictions)

print(f"Mean Squared Error: {mse:.4f}")
print(f"Root Mean Squared Error: {rmse:.4f}")
print(f"Mean Absolute Error: {mae:.4f}")
print(f"R² Score: {r2:.4f}")

image

To evaluate our model’s performance, we calculate several common regression metrics:

  1. Mean Squared Error (MSE): Average of squared differences between predicted and actual values
  2. Root Mean Squared Error (RMSE): Square root of MSE, which gives the error in the same units as the target variable
  3. Mean Absolute Error (MAE): Average of absolute differences between predicted and actual values
  4. R² Score: Proportion of variance in the dependent variable that is predictable from the independent variables

Lower values of MSE, RMSE, and MAE indicate better performance, while higher values of R² (closer to 1) indicate better performance.

Cell 11: Visualize Model Performance

# Visualize predictions vs. actual values
plt.figure(figsize=(10, 6))
plt.scatter(actual, predictions)
plt.xlabel('Actual Age')
plt.ylabel('Predicted Age')
plt.title('XGBoost Model Performance on Abalone Dataset')
plt.plot([min(actual), max(actual)], [min(actual), max(actual)], 'r--')
plt.show()

This cell creates a scatter plot of predicted values versus actual values. The red dashed line represents perfect predictions (where predicted = actual). Points close to this line indicate good predictions, while points far from the line indicate errors.

image

Cell 12: Analyze Residuals

# Visualize residuals
residuals = predictions - actual
plt.figure(figsize=(10, 6))
plt.scatter(predictions, residuals)
plt.axhline(y=0, color='r', linestyle='-')
plt.xlabel('Predicted Values')
plt.ylabel('Residuals')
plt.title('Residual Plot')
plt.show()

image

The residual plot helps us analyze the errors in our model. It shows the difference between predicted and actual values (residuals) plotted against the predicted values. Ideally, residuals should be randomly distributed around the zero line with no clear pattern, indicating that the model has captured all the patterns in the data.

Cell 13: Clean Up Resources

# Clean up resources when done
predictor.delete_endpoint()

Finally, we clean up the resources we created to avoid incurring unnecessary charges. The delete_endpoint() method removes the SageMaker endpoint we deployed.

Understanding Model Artifacts

During the training process, SageMaker generates model artifacts that are stored in the S3 location specified in the output_path parameter of the Estimator. For our XGBoost model, these artifacts include:

  1. The Model File: The serialized XGBoost model that contains the learned parameters and structure of the trees.

  2. Model Metadata: Information about the model configuration and hyperparameters.

  3. Preprocessing Scripts: Any code used for data transformation that needs to be applied during inference.

These artifacts are packaged in a model.tar.gz file and stored at:

s3://{bucket}/sagemaker/xgboost-abalone/output/{training-job-name}/output/model.tar.gz

You can access the training job name and model artifacts location programmatically:

# Get the training job name
training_job_name = xgb.latest_training_job.name

# Construct the S3 path to the model artifacts
model_artifacts = f"s3://{bucket}/{prefix}/output/{training_job_name}/output/model.tar.gz"

print(f"Model artifacts are stored at: {model_artifacts}")

These artifacts are used when you deploy the model to an endpoint, and they can also be downloaded for inspection or use in other environments.

Conclusion

In this tutorial, we’ve walked through the entire machine learning workflow using Amazon SageMaker and XGBoost:

  1. Setting up the SageMaker environment
  2. Preparing and uploading data
  3. Configuring and training an XGBoost model
  4. Deploying the model as a real-time endpoint
  5. Making predictions and evaluating model performance
  6. Visualizing results and analyzing errors
  7. Cleaning up resources

SageMaker simplifies the machine learning process by handling infrastructure management, allowing data scientists to focus on model development and evaluation. The ability to easily train, deploy, and evaluate models makes it a powerful tool for building machine learning solutions in the cloud.


<
Previous Post
🛠️ Feature Engineering with Amazon SageMaker Data Wrangler
>
Next Post
🧪 A/B Testing Machine Learning Models with Amazon SageMaker: A Practical Guide