H&M Multi-Modal Customer Encoder (contrastive, 48 epochs) + K=20 segment centroids

A 256-D customer-embedding encoder trained with pure contrastive learning (NT-Xent) on the public H&M Personalized Fashion Recommendations dataset (1.35M customers, 31.8M transactions, 2018-09 β†’ 2020-09), plus the K-Means centroids of the final 20-segment customer segmentation. Code, full pipeline, and experiment history: https://github.com/priyadip/deep-seg-paradox

Headline result

Recommending each customer the bestsellers of their own segment instead of global bestsellers improves next-purchase prediction on a fully held-out test week by +21.6% MAP@12 (0.00710 β†’ 0.00864; 68,984 purchasers; 15/20 segments positive). Model and K were selected exclusively on a separate validation week.

Key finding (why this checkpoint)

All experiments

Across a three-regime ablation (DeepCluster-style pseudo-label refreshing; frozen pseudo-labels; pure contrastive), cluster-aware training objectives monotonically degraded downstream predictive utility even as internal cluster-validity metrics (silhouette) improved β€” internal and extrinsic segmentation quality were anti-correlated. Pure contrastive training was best throughout, peaking at 48 epochs (+17.9% validation uplift) and declining afterward (confirmed to 96 epochs). This checkpoint is that peak.

Files

File Contents
encoder_contrastive_48ep.pth encoder weights (6.9MB; state_dict)
kmeans_centroids_k20.npy 20 Γ— 256 segment centroids fitted on the encoder's embeddings
model.py self-contained architecture + loading + nearest-centroid segment assignment

Architecture

Three input views per customer β†’ fused 256-D embedding:

  • Demographic (7): age (median-imputed) + one-hot club_member_status, fashion_news_frequency β†’ MLP(128)
  • Style (384): mean all-MiniLM-L6-v2 embedding of purchased articles' detail_desc β†’ MLP(512)
  • Behavioral (24Γ—2): log1p monthly purchase count & spend over 24 months β†’ 2-layer LSTM(256)
  • Fusion: concat β†’ MLP β†’ LayerNorm β†’ 256-D embedding (+ projection head used only in training; cluster head unused by this final model)

Usage

import torch, numpy as np
from model import load_encoder, assign_segments

model = load_encoder("encoder_contrastive_48ep.pth")
with torch.no_grad():
    emb, _, _ = model(demo, style, behav)   # [N,7], [N,384], [N,24,2] float32
segments = assign_segments(emb.numpy())     # [N] ints in 0..19

Input construction must follow the exact recipe above (see the GitHub repo's preprocessing.py). Customers with no purchase history: zero-fill style and behav β€” the model still produces an embedding (demographic-driven cold start).

Training

  • Objective: NT-Xent (temp 0.1) over two augmented views (Gaussian noise Οƒ=0.02 + 5% random feature/time-step masking); no clustering loss.
  • AdamW lr 1e-3, wd 1e-5, batch 1024, cosine warm restarts (12-epoch cycles), 48 epochs.
  • Data: transactions before 2020-09-09 only (validation week 09-09..15 used for all selection; test week 09-16..22 evaluated once).
  • Hardware: 1Γ— NVIDIA L40S, 3.3h for this run (20 GPU-hours for the full study).

Evaluation protocol

Per candidate segmentation: build top-12 bestsellers per segment from a 14-day popularity window, recommend to members, score MAP@12 against actual held-out-week purchases, and compare with a single global top-12 list. Uplift isolates what knowing the segment adds.

Intended use & limitations

For research on segmentation evaluation, representation learning on retail data, and as a practical segment-assignment model for H&M-schema data. Not a competition-grade recommender (the popularity recommender is deliberately minimal). Trained on one retailer, 2018–2020; retrain for other domains. Single training seed; nearby checkpoints differ by small MAP margins. Dataset Β© H&M Group via Kaggle competition rules β€” not redistributed.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support