Intermediate

Feature Engineering for Feature Stores

Design features that work well with feature stores: entity modeling, transformation patterns, aggregation strategies, and pipeline design.

Entity Design

Entities are the primary keys for feature lookups. Good entity design is critical for feature reuse and efficient serving.

Python - Common Entity Patterns
from feast import Entity

# Single-key entities
user = Entity(name="user_id", description="Application user")
merchant = Entity(name="merchant_id", description="Merchant/business")
product = Entity(name="product_id", description="Product SKU")

# Composite entities (for interaction features)
user_merchant = Entity(
    name="user_merchant",
    join_keys=["user_id", "merchant_id"],
    description="User-merchant pair for interaction features"
)

Feature Categories

CategoryExamplesComputation
Identityage, gender, account_typeDirect lookup, rarely changes
Aggregationtx_count_7d, avg_spend_30dWindowed aggregation over events
Interactionuser_category_spend, click_rateCross-entity aggregation
Derivedspend_ratio, is_high_valueComputation from other features
Embeddinguser_embedding, text_embeddingML model output

Windowed Aggregation Patterns

SQL - Multi-Window Feature Computation
-- Compute features across multiple time windows
SELECT
    user_id,
    -- 1-hour window
    COUNT(CASE WHEN ts > NOW() - INTERVAL '1 hour' THEN 1 END) AS tx_count_1h,
    SUM(CASE WHEN ts > NOW() - INTERVAL '1 hour' THEN amount END) AS spend_1h,

    -- 1-day window
    COUNT(CASE WHEN ts > NOW() - INTERVAL '1 day' THEN 1 END) AS tx_count_1d,
    SUM(CASE WHEN ts > NOW() - INTERVAL '1 day' THEN amount END) AS spend_1d,

    -- 7-day window
    COUNT(CASE WHEN ts > NOW() - INTERVAL '7 days' THEN 1 END) AS tx_count_7d,
    AVG(CASE WHEN ts > NOW() - INTERVAL '7 days' THEN amount END) AS avg_spend_7d,

    -- 30-day window
    COUNT(CASE WHEN ts > NOW() - INTERVAL '30 days' THEN 1 END) AS tx_count_30d,

    -- Ratios (1d/7d spending velocity)
    COALESCE(
        SUM(CASE WHEN ts > NOW() - INTERVAL '1 day' THEN amount END) /
        NULLIF(SUM(CASE WHEN ts > NOW() - INTERVAL '7 days' THEN amount END), 0),
        0
    ) AS spend_velocity_1d_7d,

    MAX(ts) AS event_timestamp
FROM transactions
GROUP BY user_id;

Feature Pipeline Design

Python - Batch Feature Pipeline with Feast
import pandas as pd
from feast import FeatureStore

def run_feature_pipeline():
    """Daily batch feature computation pipeline."""

    # 1. Compute features from raw data
    features_df = spark.sql("""
        SELECT user_id, ... FROM transactions
        GROUP BY user_id
    """).toPandas()

    # 2. Add timestamp
    features_df['event_timestamp'] = pd.Timestamp.now()

    # 3. Write to offline store (Parquet/data warehouse)
    features_df.to_parquet(
        "s3://feature-store/user_features/latest.parquet",
        index=False
    )

    # 4. Materialize to online store
    store = FeatureStore(repo_path="feature_repo/")
    store.materialize_incremental(end_date=pd.Timestamp.now())

    print(f"Materialized {len(features_df)} feature rows")

Feature Transformation Tips

  • Keep transformations simple: Complex transformations are hard to debug and maintain. Break them into multiple feature views.
  • Use multiple time windows: Features like tx_count_1h, tx_count_1d, tx_count_7d capture different behavioral signals.
  • Compute ratios: Ratios like spend_1d / spend_7d capture velocity and trends.
  • Avoid target leakage: Never include the label or future information in features.
  • Handle nulls explicitly: Define default values for features when no data exists (new users, cold start).

Ready to Go Deeper?

Live instructor-led courses from our partners. Affiliate disclosure.