AW Dev Rethought

🕵️ Debugging is like being the detective in a crime movie where you are also the murderer - Filipe Fortes

⚡️ Saturday ML Spark – 🏪 Feature Store Concepts for Production ML


Description:

As machine learning projects evolve from experimentation to production, managing data becomes one of the biggest challenges. While building a model is important, ensuring that the same features are consistently available during both training and inference is equally critical.

Imagine training a fraud detection model using one version of a customer's transaction history, but serving predictions using a slightly different calculation in production. Even a small inconsistency can significantly impact model accuracy.

This problem is known as training-serving skew, and one of the best solutions is a Feature Store.

In this project, we'll build a simple Feature Store simulation using Python and understand why it has become a fundamental component of modern ML platforms.


What Is a Feature Store?

A Feature Store is a centralised system for creating, storing, managing, and serving machine learning features.

Instead of implementing feature engineering separately for every model or application, teams define features once and reuse them consistently across the entire ML lifecycle.

For example, rather than calculating a customer's average transaction value in multiple services, the Feature Store computes it once and makes it available wherever it's needed.


Why Do We Need a Feature Store?

Without a Feature Store, different teams may implement the same feature differently.

For example:

Training

Average Purchase = Total Amount / Number of Orders

Production

Average Purchase = Total Amount / Successful Orders

Although both formulas appear similar, they produce different values, resulting in inconsistent model behavior.

A Feature Store ensures that both training and production use the exact same feature definitions.


Creating Reusable Feature Engineering

The first step is defining feature engineering logic in one reusable function.

def generate_features(df):

    features = df.copy()

    features["avg_transaction_value"] = (
        features["total_spent"] /
        features["transactions"]
    )

    return features

This function becomes the single source of truth for feature generation.

Any model that requires these features can reuse the same implementation.


Offline Feature Store

The Offline Feature Store is primarily used during model development and training.

It stores historical feature values for large datasets.

Typical use cases include:

  • model training
  • feature exploration
  • historical analysis
  • batch inference

Because latency is not critical, offline stores usually rely on data warehouses or data lakes.


Online Feature Store

Once a model is deployed, predictions must be generated in milliseconds.

Instead of reading from massive datasets, production systems retrieve precomputed features from an Online Feature Store.

This enables:

  • low-latency predictions
  • real-time recommendations
  • fraud detection
  • personalised user experiences

The online store serves the same features that were used during training, ensuring consistency.


Keeping Features Up to Date

Customer behaviour changes continuously.

As new transactions arrive, feature values must be refreshed.

For example:

  • purchase count increases
  • average spending changes
  • recent activity updates
  • customer status changes

A Feature Store automatically updates these values so production models always receive the latest information.


How a Feature Store Works

A typical workflow looks like this:

Raw Data
    │
    ▼
Feature Engineering
    │
    ▼
Offline Feature Store
    │
    ├────────────► Model Training
    │
    ▼
Online Feature Store
    │
    ▼
Real-Time Predictions

This architecture ensures that every model uses identical feature definitions regardless of where predictions are made.


Benefits of a Feature Store

A Feature Store provides several advantages:

  • centralised feature management
  • reusable feature definitions
  • consistent training and inference
  • reduced duplicate engineering effort
  • faster model deployment
  • improved collaboration between teams
  • lower maintenance costs

As organisations build more ML models, these benefits become increasingly valuable.


Popular Feature Store Platforms

Many production ML systems use dedicated Feature Store solutions, including:

  • Feast
  • Tecton
  • Databricks Feature Store
  • Vertex AI Feature Store
  • Amazon SageMaker Feature Store
  • Hopsworks

These platforms provide scalable infrastructure for feature storage, versioning, monitoring, and real-time serving.


Where Feature Stores Are Used

Feature Stores support a wide range of AI applications, including:

  • recommendation systems
  • fraud detection
  • credit risk assessment
  • customer churn prediction
  • demand forecasting
  • personalized marketing
  • real-time pricing
  • intelligent search systems

Any production ML system that relies on engineered features can benefit from a Feature Store.


Key Takeaways


  1. A Feature Store centralises feature engineering for machine learning systems.
  2. Offline Feature Stores are used for training, while Online Feature Stores serve real-time predictions.
  3. Using the same feature definitions prevents training-serving skew.
  4. Feature Stores improve scalability, consistency, and collaboration across ML teams.
  5. They are a foundational component of modern MLOps and production AI platforms.

Conclusion

Building an accurate machine learning model is only part of deploying AI successfully. Equally important is ensuring that the features used during training are identical to those served in production. Feature Stores solve this challenge by providing a centralised, reusable, and reliable feature management system.

With this topic, we've completed the ML Systems Advanced series in Saturday ML Spark. From Concept Drift and Feature Drift Detection to Canary Deployments, Model Versioning, and Feature Stores, we've explored the essential concepts that power reliable, scalable, and production-ready machine learning systems.


Code Snippet:

# =========================================================
# 📦 Install Required Libraries
# =========================================================

# Run this in terminal if not installed:
# pip install pandas numpy


# =========================================================
# 📦 Import Required Libraries
# =========================================================

import pandas as pd
import numpy as np
from datetime import datetime


# =========================================================
# 🏗️ Create Sample Customer Dataset
# =========================================================

customer_data = pd.DataFrame({
    "customer_id": [101, 102, 103, 104, 105],
    "transactions": [12, 4, 20, 7, 15],
    "total_spent": [8500, 2200, 15600, 4300, 9800],
    "days_since_last_purchase": [5, 28, 2, 14, 8]
})

print("=" * 70)
print("RAW CUSTOMER DATA")
print("=" * 70)

print(customer_data)


# =========================================================
# 🧮 Feature Engineering Function
# =========================================================

def generate_features(df):

    features = df.copy()
    features["avg_transaction_value"] = features["total_spent"] / features["transactions"]
    features["purchase_frequency"] = features["transactions"] / 30
    features["high_value_customer"] = features["total_spent"] >= 9000
    features["active_customer"] = features["days_since_last_purchase"] <= 10
    return features


# =========================================================
# 🏪 Build Offline Feature Store
# =========================================================

offline_store = generate_features(customer_data)

print("\n" + "=" * 70)
print("OFFLINE FEATURE STORE")
print("=" * 70)

print(offline_store)


# =========================================================
# 💾 Save Offline Feature Store
# =========================================================

offline_store.to_csv("offline_feature_store.csv", index=False)
print("\nOffline Feature Store saved.")


# =========================================================
# ⚡ Create Online Feature Store
# =========================================================

online_store = {}

for _, row in offline_store.iterrows():
    online_store[
        row["customer_id"]
    ] = {
        "avg_transaction_value": row["avg_transaction_value"],
        "purchase_frequency": row["purchase_frequency"],
        "high_value_customer": row["high_value_customer"],
        "active_customer": row["active_customer"],
        "last_updated": datetime.now()
    }
print("\nOnline Feature Store Created.")


# =========================================================
# 🔍 Retrieve Features for Inference
# =========================================================

customer_id = 103

features = online_store[
    customer_id
]

print("\n" + "=" * 70)
print(f"ONLINE FEATURES FOR CUSTOMER {customer_id}")
print("=" * 70)

for key, value in features.items():
    print(f"{key}: {value}")


# =========================================================
# 🤖 Simulate Model Prediction
# =========================================================

print("\n" + "=" * 70)
print("MODEL INFERENCE")
print("=" * 70)

score = 0
if features["active_customer"]:
    score += 1
if features["high_value_customer"]:
    score += 1
if features["purchase_frequency"] >= 0.4:
    score += 1


if score >= 3:
    prediction = "Very High Purchase Probability"
elif score == 2:
    prediction = "High Purchase Probability"
elif score == 1:
    prediction = "Medium Purchase Probability"
else:
    prediction = "Low Purchase Probability"


print(f"Prediction: {prediction}")


# =========================================================
# 🔄 Simulate Incoming Customer Activity
# =========================================================

print("\n" + "=" * 70)
print("NEW CUSTOMER ACTIVITY")
print("=" * 70)

customer_data.loc[
    customer_data["customer_id"] == 102,
    "transactions"
] += 1

customer_data.loc[
    customer_data["customer_id"] == 102,
    "total_spent"
] += 950

customer_data.loc[
    customer_data["customer_id"] == 102,
    "days_since_last_purchase"
] = 1

print(customer_data)


# =========================================================
# 🔁 Refresh Offline Feature Store
# =========================================================

offline_store = generate_features(customer_data)

print("\nOffline Feature Store Refreshed.")


# =========================================================
# 🔄 Synchronize Online Feature Store
# =========================================================

for _, row in offline_store.iterrows():

    online_store[
        row["customer_id"]
    ] = {
        "avg_transaction_value": row["avg_transaction_value"],
        "purchase_frequency": row["purchase_frequency"],
        "high_value_customer": row["high_value_customer"],
        "active_customer": row["active_customer"],
        "last_updated": datetime.now()
    }

print("Online Feature Store Updated Successfully.")


# =========================================================
# 🔍 Verify Updated Features
# =========================================================

customer_id = 102

updated_features = online_store[customer_id]

print("\n" + "=" * 70)
print(f"UPDATED FEATURES FOR CUSTOMER {customer_id}")
print("=" * 70)

for key, value in updated_features.items():
    print(f"{key}: {value}")


# =========================================================
# 📊 Feature Store Statistics
# =========================================================

print("\n" + "=" * 70)
print("FEATURE STORE SUMMARY")
print("=" * 70)

print(f"Customers Stored : {len(online_store)}")
print(f"Active Customers : {offline_store['active_customer'].sum()}")
print(f"High Value Customers : {offline_store['high_value_customer'].sum()}")
print(f"Average Transaction Value : {offline_store['avg_transaction_value'].mean():.2f}")


# =========================================================
# 💾 Save Updated Feature Store
# =========================================================

offline_store.to_csv("updated_feature_store.csv", index=False)

print("\nUpdated Feature Store saved.")


# =========================================================
# 📂 Load Saved Feature Store
# =========================================================

loaded_store = pd.read_csv("updated_feature_store.csv")

print("\n" + "=" * 70)
print("LOADED FEATURE STORE")
print("=" * 70)

print(loaded_store)


# =========================================================
# 🏛️ Production Feature Store Workflow
# =========================================================

print("\n" + "=" * 70)
print("FEATURE STORE WORKFLOW")
print("=" * 70)


# =========================================================
# 🌍 Production Feature Store Platforms
# =========================================================

platforms = [
    "Feast",
    "Tecton",
    "Databricks Feature Store",
    "Vertex AI Feature Store",
    "Amazon SageMaker Feature Store",
    "Hopsworks"
]

print("=" * 70)
print("POPULAR FEATURE STORE PLATFORMS")
print("=" * 70)

for platform in platforms:
    print(f"• {platform}")


# =========================================================
# ✅ Final Note
# =========================================================

print("\nFeature Store simulation completed successfully!")
print("Consistent feature engineering helps eliminate training-serving skew in production ML systems.")

Link copied!

Comments

Add Your Comment

Comment Added!