Ranking Signals, Multi-Task Model, and Re-ranking
~50 min read
The three categories of ranking signals for social posts, the multi-task prediction model combining them, and the re-ranking adjustments applied before the final feed is returned.
The Three Signal Categories
Khang Pham's ML Primer organizes feed ranking signals into three groups:
1. Network signals (who posted and your relationship with them):
- User-author affinity: how often has this user liked/replied to/shared this author in the past 90 days?
Feature:
(likes_from_user_to_author_90d) / (total_impressions_from_author_90d) - Mutual connection strength: do you have mutual follows? Have you DM'd them?
- Follow recency: newly followed accounts may get a temporary boost (user is actively interested)
- Author credibility: account age, verification status, historical violation rate
2. Content signals (what was posted):
- Topic match: embed post text → cosine similarity with user's interest embedding
topic_score = cos_sim(post_topic_emb, user_interest_emb) - Content type affinity: does this user typically engage more with video vs. text?
- Post quality: grammar, readability, spam signals, link credibility (for link posts)
- Language: post in user's primary language?
3. Engagement signals (how others are reacting):
- Engagement velocity: likes/replies in the first 30 minutes — viral signal
- Global like rate: likes / impressions for this post across all users so far
- Global reply rate: high reply rate = discussion-generating content
- Negative signals: report rate, 'not interested' rate, block rate after seeing this post
Multi-Task Ranking Model
Architecture mirrors content recommendation: shared bottom + task-specific heads.
# Input: concatenation of all signal features input = concat([ user_features, # user embeddings, preferences author_features, # author stats, credibility post_features, # content embedding, type, quality user_author_features,# affinity metrics engagement_features, # current velocity, rates context_features, # time of day, device, session ]) # Shared bottom → task-specific heads h = dense_layers(input) p_like = sigmoid(W_like @ h) # positive p_reply = sigmoid(W_reply @ h) # positive (strong signal) p_repost = sigmoid(W_repost @ h) # positive (viral signal) p_not_interested = sigmoid(W_ni @ h) # negative p_report = sigmoid(W_report @ h) # strong negative score = (1.0*p_like + 2.0*p_reply + 1.5*p_repost - 1.0*p_not_interested - 10.0*p_report)
Note: the weights (1.0, 2.0, 1.5, -10.0) are policy decisions, not learned parameters. Policy teams adjust them based on A/B tests and trust-and-safety requirements.
Re-ranking Adjustments
After the ranking model produces scores, apply post-processing:
-
Time-decay:
feed_score = ranking_score × 1 / (1 + 0.1 × age_hours)Tune alpha per content type: breaking news decays fast, evergreen content slowly. -
Author diversity: if the top-10 posts are all from one author (even if they score highest), cap at 3 per author. This prevents single accounts from dominating regardless of score.
-
Deduplication: same story shared by 5 followed accounts → show once. Group by URL hash + text MinHash similarity → keep the version with highest score or earliest original post.
-
Content type mixing: avoid 15 consecutive videos if the user's historical preference is mixed. Interleave content types to match consumption patterns.
-
Seen post filter: remove any post the user already saw in the past 24h (tracked per user in Redis).
-
Ads injection: insert ad units at fixed positions (3, 8, 15) after organic ranking is complete.
💬 Deep Dive with AI
Key points
- •Three signal categories: network (who posted), content (what was posted), engagement (how others are reacting) — each captures a dimension of post quality the others miss
- •Multi-task ranking scores multiple engagement types (like, reply, share, report) separately, then combines with weights set by policy teams — not just ML metrics
- •Time-decay, author diversity, and deduplication are re-ranking constraints applied after the ranking model — they address quality problems that pure score optimization doesn't