一、粗排环节的核心作用与精准度瓶颈
1.1 粗排到底做什么
我们刷短视频时,后台首先要从全平台几十万甚至上百万的新视频或候选视频里,快速挑出几百条显示在feed流里,这个“先筛一批”的环节就是粗排。它的核心是“快”——得在几百毫秒内完成,不然手机会卡顿,用户体验会差;同时还要“准”——挑出来的得是用户大概率会喜欢的,不然划两下就没兴趣了。
1.2 粗排精准度为什么难提升
粗排的矛盾点很明显:候选太多,时间不够,没法用太复杂的模型。比如用户偶尔刷了一条宠物视频,粗排不能因为这一次就把宠物视频大量推给他,但又不能忽略他真的有潜在兴趣;还有用户的“误操作”,比如手指滑到的点赞,这种无效信号也会干扰粗排的判断,导致精准度上不去。
二、提升粗排精准度的具体技巧
2.1 技巧一:基于上下文关联特征优化候选过滤
原来很多粗排只用用户的“核心历史行为”(比如最近点赞的品类),但忽略了当前场景的上下文——比如时间、设备、所在环境这些,而这些信息能帮我们过滤掉明显不匹配的视频,减少无效候选。举个例子,凌晨1点用户大概率在刷助眠或慢生活视频,这时候推美食视频就很不合理,加了时间上下文的过滤,就能减少这类误匹配。
技术栈:Python
# 粗排过滤函数:结合用户历史、当前时间、设备上下文(核心是加了场景特征)
def coarse_filter(candidate_videos, user_history_cates, current_time, device_type):
# 定义不同时段的用户偏好对应品类(生活化规则,可根据业务调整)
time_preference = {
(0, 6): ["助眠", "慢生活", "科普"], # 凌晨到6点,偏安静、短内容
(12, 18): ["美食", "剧情", "测评"], # 午间到傍晚,偏实用、娱乐
(18, 24): ["娱乐", "游戏", "脱口秀"] # 晚间,偏轻松、长内容
}
# 匹配当前时段的目标品类
target_cates = []
for (start, end), cates in time_preference.items():
if start <= current_time <= end:
target_cates = cates
break
# 过滤规则:3选1就保留——要么属于当前时段目标品类,要么和用户历史品类匹配,要么是超高热度的新内容
filtered_candidates = []
for video in candidate_videos:
video_cate = video.get("category", "")
video_tags = video.get("tags", [])
hot_score = video.get("hot_score", 0)
# 核心判断逻辑:减少绝对化规则,加入灵活匹配
if (video_cate in target_cates) or (set(video_tags) & set(user_history_cates)) or (hot_score > 85):
filtered_candidates.append(video)
return filtered_candidates
这个示例的核心是把“死规则”变成“灵活匹配”,比如不再因为用户历史只有美食就全推美食,而是结合时段的偏好,既保留用户核心兴趣,又适配当前场景,提升候选的匹配度。
2.2 技巧二:用轻量级排序模型替代硬规则
以前粗排常用一堆if-else的硬规则,比如“点赞过美食就推美食,没有就推热点”,但这种规则太僵化,没法处理用户的复杂偏好(比如用户喜欢美食但最近也看了几次旅游)。换成轻量的机器学习模型(比如逻辑回归,计算量极小,适合粗排),就能学到更灵活的权重,比如“看了5次美食,2次旅游,那美食权重占70%,旅游占20%”,不用人工写复杂规则。
技术栈:Python
from sklearn.linear_model import LogisticRegression
import numpy as np
# 预训练轻量粗排模型(实际项目中是用历史数据训练好后上线,不用每次训练)
def build_coarse_sort_model():
# 模拟训练数据:每个候选视频对应5个特征(比如和用户历史相似度、时段匹配度、热度、视频时长、发布时间差)
# 1=适合推荐,0=不适合,数据模拟符合实际分布
feature_dim = 5
sample_count = 2000
X = np.random.rand(sample_count, feature_dim) # 随机生成特征
y = np.random.randint(0, 2, sample_count) # 随机标签,实际项目用真实用户点击/停留数据
# 轻量逻辑回归,max_iter=100足够收敛,推理速度极快(单样本推理<1ms)
model = LogisticRegression(max_iter=100, random_state=42)
model.fit(X, y)
return model
# 粗排打分函数:用模型给候选排序,取前200个(符合首页显示数量)
def sort_candidates_with_model(model, candidate_features, top_n=200):
# 模型输出概率:代表这个候选适合用户的程度
scores = model.predict_proba(candidate_features)[:, 1]
# 把分数和候选对应,按分数降序排列
sorted_candidates = sorted(zip(scores, candidate_features), key=lambda x: -x[0])
# 取top N的候选,返回给后续精排环节
return [feat for score, feat in sorted_candidates[:top_n]]
这个技巧的优势是模型灵活,能处理复杂偏好,而且速度快,不会影响粗排的延迟要求,适合大部分短视频平台的粗排场景。
2.3 技巧三:补充长尾行为的弱信号
粗排容易忽略用户的“弱行为”,比如视频停留了2秒就划走、看完一半退出、长按了1秒视频,这些弱信号虽然单个没权重,但累积起来能反映用户的真实偏好——比如用户很少点赞美食,但每次看到美食视频都会停留5秒,说明他其实对美食有潜在兴趣,只是没点赞。把这些弱信号加入粗排的特征,能覆盖更多用户的真实需求,避免漏推合适的视频。比如在之前的模型特征里加入“视频停留时长占比”,权重占10%,就能提升这类长尾行为的影响。
三、技巧的应用场景与技术优缺
3.1 适配的业务场景
这些技巧都适合短视频平台的首页feed流推荐、搜索结果页的相关推荐、个人中心的“猜你喜欢”模块,只要是需要从海量候选里快速筛选出小部分内容的场景,都能用到。尤其是新用户冷启动阶段,补充弱信号和上下文特征,能更快建立用户偏好的画像。
3.2 各技巧的优缺点对比
上下文关联特征的优点是实现简单、速度快,不需要复杂的模型,缺点是规则固定,没法处理用户的个性化异常;轻量级模型的优点是灵活,能学到复杂的偏好,缺点是需要少量的标注数据来训练,而且特征工程要做的规范;补充长尾弱信号的优点是覆盖更多真实需求,缺点是信号噪声多(比如用户误停留),需要做过滤处理,增加一点计算量。
四、实操注意事项
4.1 计算资源的权衡
粗排的延迟要求极高,一般要控制在300ms以内,所以模型不能太复杂,特征数量最好控制在10个以内,代码逻辑要尽量简化——比如不要用嵌套太多的循环,尽量用向量化运算(像示例里的模型推理),避免占用太多计算资源,影响整体推荐速度。
4.2 信号噪声的过滤
弱信号很容易有噪声,比如用户手指误触的停留、不小心长按的视频,要加入过滤规则:比如停留时长小于1秒的不算有效信号,点赞后1秒内划走的不计入核心行为,这些细节能避免噪声干扰粗排的判断,提升精准度。
五、总结
粗排是短视频推荐系统的第一道关卡,精准度直接影响用户后续的停留和点击,提升的核心是在“低延迟”和“精准匹配”之间找到平衡。上下文关联特征优化、轻量级模型替代硬规则、补充长尾弱信号这三个技巧,不需要太复杂的技术,容易落地,适合大部分开发者快速优化自己的推荐系统,提升用户的使用体验。
Comments