资讯动态

从UserBehavior数据到推荐系统:召回、排序与离线评估实战

发布时间:2026/10/4 7:30:11 来源:尧图企业网站定制
1. 处理 UserBehavior 之前先把业务问题拆清楚1.1 一个公开数据集为什么值得认真对待今年我一直在做电商场景的推荐系统最开始手头没有生产环境的用户日志权限就靠淘宝公开的 UserBehavior 数据集User Behavior Data from Taobao for Recommendation去摸底。这套数据大概有 1 亿条用户行为记录覆盖了用户在淘宝上的点击、收藏、加购、购买四种动作时间跨度是 2017 年 11 月 25 日到 12 月 3 日。虽然数据是几年前产生的但它包含了推荐系统落地时最核心的东西用户-商品交互序列、行为类型差异、时间信息以及商品和类目的映射关系。很多人拿到这份数据后第一件事就是跑df.describe()然后画几个柱状图最后得出“点击最多、购买最少”这种结论就结束了。其实这样非常浪费。推荐系统的问题不能简单等同于“用分类模型预测用户买不买”它要回答的是在什么场景下、用什么触发方式、给用户展示什么商品、以什么顺序排才能既满足用户即时需求又让商品获得合理曝光。1.2 四条关键信息线的记录结构这套数据集每条记录有五个字段字段含义示例值user_id脱敏用户编号10001082item_id商品编号1372850category_id类目编号4756105behavior_type行为类型pv / cart / fav / buytimestamps秒级时间戳1511544070其中 behavior_type 的四种取值很容易被当成多分类标签实际它们是行为漏斗的四层状态。pv 是曝光后的点击fav 是收藏表达潜在兴趣cart 是加购物车购买意向更强buy 是最终成交。设计推荐策略时每一层都有自己的用法pv 可以训练召回模型cart 和 fav 可以构造“高意向”样本buy 则用来评估真正的转化效果。时间字段同样需要仔细处理。原始数据给的是秒级 UNIX 时间戳直接转换成datetime后你会发现 12 月 3 日当天的数据量明显比前几天少这是因为数据集本身只采集到当天某个时刻不是当天完整数据。很多人跑时间序列分析时把 12 月 3 日当成完整日来统计得出来的“周末转化率暴跌”结论其实是数据截断导致的乌龙。2. 数据清洗里最容易出错的地方逐个说清楚2.1 要不要做用户过滤和商品过滤原始数据并不是一个干净的用户行为明细表里面对同一个用户、同一个商品、同一种行为存在重复记录。有的重复是因为用户真的是短时间内连续点了两次有的则是日志上报时的重复写入。我处理时用的原则是pv按「user_id item_id 时间戳」去重因为用户在同一秒内重复点击同一个商品无论如何都不应该算两次有效行为fav、cart、buy则按「user_id item_id」保留最早或最晚时间具体看你要解决什么问题——做购买预测时保留最早时间更合理做行为序列建模时则要保留全部记录。用户过滤和商品过滤也是一个重要决定决定了整体偏差。2.2 时间窗口切分该怎么切才合理离线实验最忌讳随机切分。如果随机把 100 万条记录分成训练集和测试集同一个用户的行为会同时出现在两边模型相当于偷看了“未来的答案”。推荐系统的离线评估必须按时间切分。我当时设定的切分规则是前 7 天11/25 到 12/01作为训练集后 2 天12/02 到 12/03作为测试集。这样切完之后还要做一个动作测试集里只保留在训练集中出现过的用户把新用户剔除掉。因为冷启动是另一个独立问题如果评估时把新用户也卷进来模型分数会很难看而且你分不清是“召回能力差”还是“冷启动没解决”。基于所有用户行为我构建了用户维度和商品维度的画像。用户画像包括活跃天数、总点击量、总购买量、点击到购买的平均间隔等商品画像包括日曝光量、转化率、收藏加购占比等。这些特征后面都会喂给排序模型。3. 探索性分析决定特征怎么建不是只看热闹3.1 行为漏斗的转化率到底该怎么算电商圈里常说的“点击到购买转化率”有两种算法分母用总点击用户数或者用点击商品的总次数。按用户维度算得出的是一段时间内真实人群的转化水平按行为次数维度算得出的更接近流量效率。两者差异非常大。我按用户维度算了一下点击用户的购买转化率整体在 1.8% 到 2.3% 之间收藏后再购买的用户转化率能翻到 9%-12%加购后再购买的用户转化率更是能到 18%-25%。这个结论直接影响了特征设计——对某个商品有点击但没有加购行为和加购后未购买完全不能同等对待。加购和收藏行为本身就是在表达“兴趣验证”它的权重应该明显高于点击。单看日维度总转化率会掩盖一个规律前几天的转化率平稳但 12 月 2 日会出现小波峰。原因是周末用户有更多时间逛决策链路变长。如果在做推荐模型时把“是否是周末”作为特征加进去效果会有微弱但稳定的提升。3.2 活跃度分层二八法则在行为数据里的体现把用户按行为次数分成五层最顶层 10% 的活跃用户贡献了接近 45% 的点击和 38% 的购买。这和电商业务里“头部用户贡献大部分 GMV”的现实是一致的。这些强用户行为的稀疏性问题在于大多数人只产生少量行为无法单独训练高质量的用户向量。所以做协同过滤时不能对所有用户统一训练。我的做法是先把用户按行为量分成三层高活用户行为数大于 50、中活用户10-50、低活用户少于 10。高活用户用完整序列建模低活用户则更多依赖商品热度和类目偏好做召回。这个分层在后面的评估里很重要因为整体指标往往被高活用户主导低活用户才是推荐系统需要持续优化的部分。4. 召回层的选择协同过滤、向量召回还是规则召回4.1 为什么 item-based CF 在这个场景里比 user-based CF 更稳用户行为数据天然适合做协同过滤但在这个数据集上我强烈建议优先尝试 item-based CF物品协同过滤而不是 user-based CF。原因很直接item-based CF 计算的是商品之间的相似度。商品的数量相对用户来说少得多商品相似矩阵的存储和更新都更可控。而且商品相似度相对稳定一个商品的属性、类目、品牌短时间内不会频繁变化可以离线计算好放进缓存线上使用时直接取相似商品列表。user-based CF 需要实时计算用户之间的相似度用户数量一旦上亿这个计算量非常恐怖而且用户兴趣变化快相似用户列表需要频繁更新维护成本太高。不过 item-based CF 有一个天然的弱点它只能推荐与用户历史交互商品相似的商品推荐的惊喜度很低。比如用户之前点击了一个红色连衣裙item-based CF 大概率推荐一堆类似红色连衣裙用户可能已经对这个类目不感兴趣了。4.2 用行为序列构造商品向量补上协同过滤的盲区为了弥补上面的问题我用行为序列训练了一版商品 embedding。具体做法是把每个用户的行为按时间排序得到一个商品 ID 序列。考虑到用户序列中可能会有大量无关点击我先过滤掉单次会话内超过 30 个连续点击的商品说明用户在快速浏览没走心然后把序列切成固定长度为 20 的滑动窗口。用 Word2Vec 的 Skip-gram 模式训练商品向量向量维度设为 64。训练完之后商品向量的余弦相似度能表达“用户在行为上更倾向同时关注哪些商品”。这跟 item-based CF 的“商品共现”本质上是同一件事但 embedding 方法能捕捉更深层的非线性关系还能算出不同类目商品之间的语义关联。比如点击过某款手机的用户在行为序列里往往也出现过手机壳、蓝牙耳机这是单纯靠 item 共现很难捕捉到的跨类目关联。4.3 召回阶段的组合策略向量召回为主热门兜底线上召回阶段需要既保证效果又控制延迟。我用了两层召回第一层是向量召回。把用户最近 20 个有过正向行为的商品 embedding 取平均作为用户向量然后与商品向量做内积取 Top 200。这层召回的结果在类目多样性和跨类目能力上表现不错。第二层是规则召回。包括该用户最近点击过的商品的相似商品用 item-based CF 计算、热门商品按最近 24 小时点击量排序和类目热门商品。这个兜底解决冷启动问题——新用户没有足够行为算出稳定的向量直接推热门商品是最稳妥的。但是向量召回有一个需要注意的地方训练 embedding 时如果直接把pv、fav、cart、buy全部当成同一个行为去训练模型会被点击数据主导因为点击量是购买量的几十倍。买过的东西和点过的东西在用户心里的分量是完全不同的。我最终采用的方案是训练时对不同行为设置不同权重——buy权重 10cart权重 5fav权重 3pv权重 1。这样训练出来的商品向量更贴近用户的真实偏好。5. 排序层从 CTR 预估到考虑业务目标5.1 样本怎么构造正负样本比例怎么定召回层输出候选商品集后排序层需要预测用户对每个商品的点击或购买概率。这里的正负样本构造很容易翻车。我当时的做法是正样本取用户实际点击过的商品预测点击率时或实际购买过的商品预测购买转化率时。负样本则是从召回结果中随机抽取用户没有交互过的商品。负样本和正样本的比例控制在 5:1 到 10:1 之间。如果负样本太少模型会倾向于把什么都预测成正样本线上效果崩得很厉害如果负样本太多训练时间变长而且模型会过度强调负样本导致召回率变低。5.2 排序模型特征体系的几个板块排序模型使用的特征可以分成四块这是一个从实践中总结出来的通用框架用户侧特征用户活跃度分层、用户历史点击类目分布、用户最近一次行为距当前的时间间隔商品侧特征商品在训练期的点击数、收藏数、加购数、转化率、商品类目热门程度行为序列特征用户最近点击的 N 个商品 ID 的 embedding 均值、用户最近点击的类目序列交叉特征当前商品与用户最近点击商品的相似度、当前商品所属类目在用户历史行为中的占比训练时可以用 LightGBM 或 XGBoost。GBDT 类模型对特征工程的要求相对较低对缺失值有天然容忍度而且能够自动捕捉部分特征交叉。不过它也有明显缺点——用户和商品 ID 不能直接作为离散特征喂进去必须先做 embedding 或 target encoding。5.3 掌握好“求稳”和“求新”之间的平衡排序阶段如果只用点击率作为目标模型会倾向于推荐用户大概率会点击的商品。但点击并不代表购买也不代表用户真的满意。一个更合理的思路是训练多目标模型一个塔预测 CTR一个塔预测 CVR转化率最后用pCTR * pCVR作为综合排序分数。这个乘积公式看起来简单但在实践中比单独优化任一指标都更能平衡业务目标。要注意CVR 模型的正样本非常稀疏只有 2% 左右直接训练很容易过拟合。我试过用 ESA Entire Space Multi-task Model全空间多任务模型出自阿里的思路把 CTR 和 CVR 放到同一个模型里联合建模用全量曝光样本空间而不是只拿点击后的样本训练 CVR。这个做法能把 CVR 模型的训练样本量扩大几十倍效果提升明显。6. 离线评估别让指标骗了你6.1 一个容易踩的坑不做时间切分我前面反复提到时间切分因为它实在是太关键了。我见过不少人拿这份数据做随机划分然后跑 AUC 得到 0.85 甚至更高觉得模型效果很好。实际上这种随机划分下的高 AUC 有很严重的泄漏问题——同一个用户的行为同时出现在训练集和测试集模型学到的用户偏好实际上已经“看到了”测试集里的内容。按时间切分后再进行同样的训练和测试AUC 往往会掉到 0.68-0.72。这个数字才是真实水平。6.2 多维度看指标不要只看 AUCAUC 是排序能力的一个整体度量但它对头部推荐效果的反映不够敏锐。在实际业务中用户只关注前 20 个推荐商品所以我还重点看了 Recall20、Precision20、NDCG20 这几个指标。NDCG 能反映推荐列表中相关商品的位置是否靠前——同样是召回 10 个商品第一个就是用户要买的和第十个才是用户要买的体验完全不同。另外我强烈建议评估时按用户活跃度分层看指标。高活用户行为丰富模型容易学准各种指标都很好看低活用户行为稀疏模型基本靠热门商品兜底指标会难看很多。如果把所有用户混在一起看高活用户会掩盖低活用户的问题让你误以为系统整体表现不错。6.3 指标好不代表业务好引入覆盖率与多样性离线指标提升并不能直接等同于用户体验提升。还需要关注两个维度覆盖率模型推荐出去的商品占全网可推荐商品的比例。如果覆盖率太低说明模型永远在推那几百个热门商品长尾商品完全没有曝光机会。类目多样性推荐列表中不同类目的数量。如果一位用户最近看了手机系统就疯狂推手机配件用户很快就会产生审美疲劳。我在实验中发现单纯用 CTR 做排序目标覆盖率只有 12%-15%引入了多样性约束之后覆盖率提升到 28%CTR 只有略微下降。这个取舍在很多场景下是值得的。7. 从离线实验到线上策略的思考7.1 性能与可扩展性离线实验跑通一个模型只是开始线上环境要考虑 QPS和延迟。淘宝这个级别的系统推荐服务需要在几十毫秒内返回结果所以线上向量检索一般用 faiss 这类工具把商品向量放到内存里做近似最近邻搜索。Item-based CF 的相似商品表也是提前算好放缓存。如果实验阶段的代码还是用 Python 循环算相似度切换成 faiss 之后性能会有数量级的提升。在 100 万商品量级下FAISS 用 IVF 索引可以做到单次查询毫秒级返回而暴力遍历需要几百毫秒。这些细节决定了你在离线实验里验证过的策略能不能真正落地。7.2 拥抱线上反馈形成迭代闭环离线评估只是第一道关卡上线后的 A/B 测试才是最终裁判。推荐系统的迭代节奏应该是离线实验筛选出靠谱的候选然后小流量上线对比效果好了再全量。每一次全量后新的行为日志又会回流形成新的训练数据整个系统就进入一个持续优化的循环。还有一点经验上线新模型时不要把流量全部切过去建议先切 10%-20% 的流量观察 3-5 天。因为离线指标和线上指标不是完全对应的尤其是 CTR 这种实时反馈指标受位置偏差、用户预期变化等多方面影响。等线上的置信区间足够明确再全量可以避免很多意外。8. 这类数据还可以怎么做从行为数据到用户长期价值8.1 用户生命周期价值预测以上所有工作都集中在“提升本次推荐的点击和转化”但从更长远的视角看我们还可以用这套行为数据预测用户生命周期价值LTV。把用户在前 7 天的行为作为特征预测用户在接下来 30 天的购买金额这样就能在早期识别高价值用户为他们提供差异化的服务和权益。8.2 触发式推荐与营销触达行为数据里有非常丰富的时间信号。比如用户连续三次点击但一直没有下单就可以触发一个“限时提醒”场景用户对某类目的点击频率突然升高说明可能进入了某个消费周期。这些场景的建模本质上也是从同一份行为序列里提取出来的只是目标函数从“预测下一次点击”变成了“判断是否值得触达”。回到开头那句话UserBehavior 数据集虽然年份较早但它的结构非常接近真实生产环境的行为日志。如果你能把这份数据从清洗、探索、召回、排序到评估完整跑一遍再换到自己的业务数据时就不会对行为日志不知所措了。我自己的体会是数据分析这件事拿真实公开数据练手会比看十篇论文都有用。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑