Skip to main content

Personalization Signals for "For You" Recommendations

Purpose

This document outlines how we personalize the "For You" recommendations for each user. We use a weighted signal system that learns from user behavior to surface the most relevant courses and consultations.

How It Works

Instead of calculating personalization on every request, we:

  1. Pre-compute a user interest profile (embedding) from their activity
  2. Store this profile and update it when behavior changes
  3. Match the user profile against product profiles using vector similarity
  4. Serve personalized recommendations instantly

This approach is efficient - we only recalculate when the user's preferences actually change.

Signal Categories

Strong Intent Signals (Highest Impact)

These indicate direct purchase or learning intent:

SignalWeightDescription
Wishlist Items5.0Products the user explicitly saved for later
Cart Items4.0Products added to cart (even if abandoned)
Enrolled Products3.0Categories the user has already invested in

Explicit Preferences (User-Declared)

What users tell us about themselves:

SignalWeightSource
Primary Interest Category3.0Student profile setup
Other Interests2.0Secondary interests in profile
Learning Objectives2.0Goals stated in profile

Behavioral Signals (Implicit)

What we learn from user actions:

SignalWeightNotes
Recent Views2.0Products viewed in last 7-30 days (decays over time)
Search Queries1.5Keywords and categories from search history
High Ratings1.5Products rated 4-5 stars by the user
Engagement Time1.0Categories where user spends the most time

Negative Signals (Exclusions)

What we avoid recommending:

SignalEffectRationale
Already EnrolledExcludedNever recommend what they already have
Low Ratings (1-2 stars)DeprioritizedUser showed dissatisfaction with similar content

When Recommendations Update

We recalculate a user's profile when their preferences change:

EventUpdate TimingWhy
User enrolls in course/consultationImmediateStrong signal - they paid for it
User adds to wishlistWithin 1 minuteShows clear interest
User removes from wishlistWithin 1 minutePreferences changed
User adds to cartWithin 5 minutesPurchase intent (might checkout)
User gives 4-5 star reviewImmediatePositive affinity
User gives 1-2 star reviewImmediateNegative signal to incorporate
User updates profile interestsImmediateExplicit preference change

Cold Start (New Users)

For users without activity history:

  1. Use their Primary Interest Category from profile setup
  2. If no profile yet → show Trending/Popular content
  3. Build personalized recommendations after first interactions

Data Sources

DataWhere It LivesWhat We Use
Wishlistwishlist tableProduct IDs, timestamps
Cartcart_items tableProduct IDs
Enrollmentsenrollment tableCourse/consultation IDs, categories
Viewsimpression tableEntity IDs, view counts, recency
Reviewsreview tableRatings, product associations
Profilestudent tableInterest category, objectives, skills
SearchElasticsearch logsQuery terms, filters used

Key Decisions

  • Event-driven updates only: We don't recalculate on a schedule. If a user hasn't interacted, their preferences haven't changed.
  • Weighted averaging: Stronger signals (wishlist, cart) influence recommendations more than weak signals (views).
  • Recency matters: Recent views weighted higher than old ones (decay function).
  • Negative signals excluded: We never recommend already-purchased items.

Success Metrics

  • Click-through rate on "For You" section
  • Conversion rate from recommendations
  • Wishlist additions from recommendations
  • User engagement with personalized vs non-personalized content

Technical Implementation

See: docs/flows/ for integration details (if created)

Key files:

  • server/src/recommendation/services/user-embedding.service.ts - Signal collection and embedding calculation
  • server/src/recommendation/listeners/user-embedding.listener.ts - Event handlers for updates
  • server/src/recommendation/processors/user-embedding.processor.ts - Background job processing

Last Updated

2025-01-27