多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

淘宝用户行为数据集全解析:从数据清洗到推荐系统实战

淘宝用户行为数据集全解析:从数据清洗到推荐系统实战 先说一个很实在的结论User Behavior Data from Taobao for Recommendation这个数据集是我见过最适合入门“用户行为数据分析 推荐系统”实战的公开数据没有之一。它不是那种整理得干干净净拿来练SQL的玩具表而是带着真实电商场景的“毛边”——有噪音、有时间戳、有行为序列、有稀疏的购买行为。你把它跑通一遍基本上就把推荐系统里数据侧的活摸了个遍。这篇文章不聊虚的我把整个分析过程、推荐落地思路、还有踩过的坑都捋一遍。不管你是刚学Python数据分析还是准备做推荐系统相关的项目这篇文章都建议看完。1. 数据集到底在还原什么业务先把这个数据集讲透。User Behavior Data from Taobao for Recommendation是阿里云天池公开的一个经典数据集记录的是淘宝App内用户一段时间的真实行为日志。它和一般“用户表 订单表”的静态数据不同本质是一份行为流数据一个用户一行行地记录他在什么时间点对哪个商品做了哪种操作。1.1 字段级拆解每列都不是白给的常见版本的数据集主要包含以下字段字段名含义典型值/格式业务解读user_id用户唯一标识数值ID脱敏用户维度聚合的依据item_id商品唯一标识数值ID脱敏商品维度聚合的依据behavior_type行为类型pv / cart / fav / buy用户对商品意图强度的直接信号item_category商品类目ID数值ID脱敏类目偏好分析粗粒度推荐time行为发生时间yyyy-mm-dd HH有的版本拆分日期/小时行为序列与时效性分析的关键很多初学者只盯着 behavior_type 和 time 看实际上item_category是个宝。商品ID的泛化能力强用户今天看了某件羽绒服明天可能看另一件但如果他对“羽绒服”这个类目持续点击说明他有真实的类目需求。做不了个性化商品推荐的环节类目推荐永远是保底方案。还有一点容易忽略这个数据集里 timestamp 通常需要转换成可读时间。我拿到的版本里 time 字段是字符串比如 2017-11-25 08需要拆成日期和小时两列后面做时间序列分析才顺手。1.2 四种行为背后的用户心理数据集里的行为类型一共有四种按用户意图强度从低到高排列pv点击/浏览。代表用户注意到了这个商品但注意力和兴趣都最弱。fav收藏。代表用户有潜在意向可能想等降价、想对比后再决定。cart加购。代表用户购买意向已经非常明确基本是“准备买”的信号。buy购买。行为链的终点真正贡献GMV的动作。这四种行为不只是四个类别它们构成了一条清晰的转化路径。你去看真实数据会发现pv 的体量远大于其他三种这说明用户在“逛”buy 占比极小说明真正下单是稀缺行为。做推荐系统时不能把四种行为同等对待要给不同行为赋不同权重buy 权重最高pv 权重最低。我习惯把行为权重设置成这样供参考buy5cart4fav3pv1。这个权重不是拍脑袋它符合“行为意图越强、越接近成交价值越高”的业务逻辑在后续计算用户-商品偏好得分时很好用。1.3 规模与场景数据集整体量级在千万到亿级之间具体看版本。我第一次跑的时候用Pandas直接全量读入内存直接爆掉。后来学乖了要么用 chunk 分批读要么先做字段裁剪要么直接换 PySpark 或者 Polars。这种“数据量刚好卡在单机处理边缘”的设定其实很妙——让你感受到真实生产环境的内存压力又不至于真的需要上分布式集群才能跑。业务背景也值得说一句这批数据的时间窗口横跨双十一促销前后阶段所以你能看到明显的促销效应对用户行为节奏的扰动。例如某些日期pv暴涨、加购和购买的比例出现波动。分析时如果不了解这个背景很容易把异常波动当bug。2. 动手前的第一道坎数据清洗与预处理很多人拿到数据就急着跑统计结果后面发现结论全是脏数据给的幻觉。用户行为数据的清洗是整个流程里最不性感但最重要的一步。2.1 脏数据的典型形态我处理这个数据集时遇到过这么几类典型问题空值有的行 user_id 或 item_id 为空。这种直接过滤掉因为无法定位分析主体。重复记录同一用户在完全相同的秒级时间戳下单条行为重复出现需要做去重避免后续计数虚高。非法行为值behavior_type 偶尔出现四种取值之外的脏值可能是采集异常或字段串位。统一剔除。行为时间越界个别记录的时间戳早于或晚于数据集声明的时间窗口比如出现 2018 年的数据混入。需要按合理业务日期范围过滤。清洗逻辑我用一个简单的Python代码片段表达一下后面分析都是基于清洗后的数据import pandas as pd df pd.read_csv(user_behavior_data.csv) # 去除关键字段空值 df df.dropna(subset[user_id, item_id, behavior_type]) # 去重保留第一条 df df.drop_duplicates() # 过滤非法行为类型 valid_behaviors [pv, fav, cart, buy] df df[df[behavior_type].isin(valid_behaviors)] # 时间字段转换与范围过滤 df[time] pd.to_datetime(df[time], format%Y-%m-%d %H) df df[(df[time] 2017-11-18) (df[time] 2017-12-18)]这段代码的核心在于每一个过滤条件背后都有业务依据不是随手写的。比如时间范围过滤因为数据集对应的就是这段周期分析窗口外边的数据会污染转化率计算。2.2 时间字段的隐藏坑这里特别提醒一下时区问题。有的公开数据集给的时间戳是UTC时间而业务时间用的东八区两者相差8小时。如果不加8小时直接按日期聚合你会看到每天凌晨的活跃低谷被算错到前一天晚上。我实际处理时看过原始时间分布发现天然接近东八区所以直接解析即可。但你自己拿到数据时一定要先画一条24小时分布曲线做检查确认凌晨低谷出现在 4-6 点而不是 20-22 点否则就有时区偏置。另外跨天行为也值得注意。用户晚上 23:50 加购凌晨 00:10 下单如果只按自然日切分这两个关联行为会被拆到不同日期导致“当日加购到购买的转化率”被低估。我的处理办法是在做用户行为序列分析时按“滚动24小时窗口”而不是“自然日窗口”来组织会话。3. 用户行为数据分析的三大视角数据洗干净之后就可以正式进入分析了。我把整个分析拆成三个最核心的视角漏斗转化视角、时间节奏视角、用户分层视角。这三个视角分别回答了三个经典业务问题用户从看到商品到下单流失在哪一步用户在什么时候最活跃、最适合投放哪些用户最值得运营、哪些最容易流失3.1 转化漏斗每一步都在掉人最经典的分析是“pv → cart → buy”或者“pv → fav → cart → buy”的漏斗。做法很简单按行为类型统计独立用户数或行为次数然后算每一步的转化率。以我跑出来的典型结果为例数值为示意pv → fav 转化率约 6% ~ 8%fav → cart 转化率约 20% ~ 30%cart → buy 转化率约 20% ~ 30%从 pv 到最终购买整体转化率往往只有 2% ~ 3% 左右。这个数据本身就是一个重要结论电商里绝大多数流量都是无效流量。“逛”的人远远多于“买”的人。所以推荐系统的目标不一定是让所有人立即买而是先把用户从 pv 一步步推向 cart 和 fav。分析漏斗时有一个很容易犯的错误——直接按行为次数算转化。比如“pv次数10万buy次数2000转化率2%”但一个用户可能点了100次才买1次次数口径会把转化率严重稀释。更合理的做法是按独立用户算漏斗看过商品的用户有多少人其中加购的有多少人里面购买的有多少人。这样才反映用户层面的真实转化而不是行为层面的。3.2 时间节奏用户什么时候最活跃按小时聚合行为量画出24小时折线图。典型结果通常是凌晨 2 点到 6 点低谷符合普通人休息的规律。中午 11 点到 14 点一个高峰通勤和午休时间刷手机。晚上 20 点到 23 点全天最高峰下班后躺在床上逛淘宝。这个发现直接指导内容推荐和营销投放的策略晚上8点到11点是大促、新品、Push投放的黄金窗口。我实际分析时发现晚间时段不仅pv量高买买买的比例也更高说明用户晚间购物决策更果断。节假日或大促日期的行为节奏会明显突变。比如双十一当天凌晨0点到2点会出现一个成交量尖峰这是用户集中结算的结果。分析时如果要在报告中体现可以单独拉出促销日和普通日做对比能看到完全不同的曲线形态。3.3 用户分层识别高价值用户基于行为数据给用户打标签我一般分四层高活跃高价值用户行为次数多、且包含多笔购买。这是核心用户推荐策略上可以大胆提供个性化推荐。高活跃低价值用户点击很多但不买即“逛客”。这类用户需要用优惠信息或精准商品来刺激转化。低活跃高价值用户行为少但一买就买贵的/多件。这类用户不需要频繁打扰适度推荐即可。低活跃低价值用户访问频率低也没购买。属于待唤醒用户可以用热门推荐或者新人券试一试。这个分层还能进一步通过 RFM 思路优化比如按“最近一次行为距今天数Recency、行为频率Frequency、购买金额Monetary有订单金额的话”三维打分。但淘宝这个数据集没有具体金额字段所以我一般用行为次数替代 Monetary用“购买次数权重”近似价值。分层之后有一个立竿见影的用途不同层级的用户使用不同的推荐策略。高价值用户给长尾个性化推荐因为他的偏好已经很明确推太大众的商品反而降低体验低价值用户给热门榜单、头部爆品因为他对你了解还不够深需要用高热度商品把他留住。4. 从分析到推荐把行为数据变成推荐结果分析做得再漂亮最终还是要落到推荐上。这节讲实操怎么基于用户行为数据构建一个简单的推荐系统。4.1 推荐设计前的三个原则动手写代码之前我先立三个原则做推荐的人值得始终记住行为数据有时效性用户三个月前的行为对当前推荐的参考价值很低。给更近的行为更高权重。稀疏购买、稠密点击buy 数据非常稀疏大部分用户可能只有0到2次购买这时候完全依赖购买记录做推荐等于无米之炊。必须把 pv/fav/cart 也纳入偏好计算。热门物品是兜底不管推荐算法多花哨冷启动阶段热门推荐永远是最稳妥的方案。4.2 ItemCF 协同过滤最务实的入门方案我推荐的第一个落地算法是ItemCF基于物品的协同过滤。它的核心思想一句话如果一个用户喜欢物品A那么和物品A相似度高的物品B也值得推荐给这个用户。这里的“相似”不是看商品本身的属性而是看用户行为上的“共现关系”——买过A的人是不是也买过B。实现步骤拆开来看构建“用户-商品”行为得分矩阵把四种行为按权重映射为得分。构建“商品-商品”共现矩阵统计两个商品在同一用户行为记录中共同出现的次数。计算商品间相似度常用余弦相似度或Jaccard相似度。对于用户历史行为中的每个商品找到与其最相似的商品加权汇总生成推荐候选集。过滤用户已经交互过的商品输出 TopN 推荐。给你一段核心的Python实现用的是“购买行为”作为共现信号便于理解你也可以换成加权得分from collections import defaultdict import pandas as pd import numpy as np def build_item_cf(df, behaviorbuy): # 筛选行为 data df[df[behavior_type] behavior] # 构建 用户-商品集合 user_items defaultdict(set) for uid, iid in data[[user_id, item_id]].values: user_items[uid].add(iid) # 计算共现矩阵 cooccur defaultdict(lambda: defaultdict(int)) for uid, items in user_items.items(): items list(items) for i in range(len(items)): for j in range(i 1, len(items)): a, b items[i], items[j] cooccur[a][b] 1 cooccur[b][a] 1 # 计算相似度并推荐 def recommend_single(user_id, topn10): interacted user_items[user_id] scores defaultdict(float) for item in interacted: for other, cnt in cooccur[item].items(): if other not in interacted: scores[other] cnt # 取topn return sorted(scores.items(), keylambda x: x[1], reverseTrue)[:topn] return recommend_single这段代码用共现次数直接作为相似度权重好处是简单、直观、快。实际使用时推荐做归一化用余弦相似度替代纯计数不然热门商品容易霸榜。4.3 推荐结果评估离线指标不是全部推荐做出来之后怎么评估常用的是离线指标准确率Precision、召回率Recall、覆盖率Coverage、多样性。我建议这样切分数据把用户行为按时间排序用前80%的行为做训练后20%的购买行为做验证。然后看推荐列表里有多少命中验证集中的购买商品。我自己跑下来ItemCF在这个数据集上的离线命中率大概在 5% ~ 15% 之间看你取多少条推荐、用什么行为作为训练信号。这个数字看去不高但已经比随机推荐高出几个数量级这也说明推荐系统的本质是从海量候选里“概率性命中兴趣”不是百分百猜中。有一点必须提醒离线指标好不代表线上效果一定好。用户可能今天没买但明天买了你推荐的东西离线窗口根本捕捉不到。在做项目汇报或者写博客时把离线指标当成参考即可真正要验证推荐质量还得靠在线A/B测试。4.4 冷启动问题的兜底策略新用户没有行为数据ItemCF直接失效。这种情况我用两层兜底热门推荐全站pv量最高的前50个商品直接推给新用户简单粗暴但效果好。类目推荐如果新用户在某个类目有零星点击立刻升维推荐该类目下最热商品。这是 item_category 字段发挥作用的地方。冷启动问题解决的关键不是单一算法而是降维到可以统计的粒度。用户没有商品级行为但有类目级行为即使类目级也没有就用全站热门。每一层都比随机效果好。5. 踩坑实录与效率优化最后这部分是真正值钱的地方都是我实操里踩出来的。5.1 小心“时序穿越”我第一次做评估的时候直接随机切数据把后20%当验证集。结果发现离线命中率虚高像偷看了答案。原因就是随机切分导致训练集里混入了验证集时间之后的行为相当于用未来信息预测过去这在真实推荐场景里不可能发生。后来我改为严格按时间切分先按用户聚合最早行为时间取所有行为时间的中位数或80%分位点作为切分点之前是训练之后是验证。这样保证训练集里的任何行为在时间上都发生在验证集之前才符合真实推荐系统“只能根据过去预测未来”的约束。5.2 千万级数据的内存优化用Pandas直接读全量数据我一度看到内存占用飙到几个G电脑风扇开始咆哮。后来总结出三个亲测有效的优化点指定列读取只读需要的列usecols[user_id, item_id, behavior_type, item_category, time]免得把无关大字段也load进来。类型压缩把user_id和item_id转成 int32behavior_type转成 category 类型。category 类型对低基数字段压缩效果极其显著。分块处理用 chunksize 分批读取每批处理完释放内存再做分布式聚合。如果你机器的内存真的顶不住直接换 Polars 或者 DuckDB。Polars 的惰性查询和并行计算在处理这种千万级表时性能提升不是一点点代码风格和Pandas也接近上手成本低。5.3 数据质量问题的隐蔽坑有几个问题不遇见你绝对想不到行为时间戳的秒级重复同一用户在同一秒对同一商品出现两条pv大概率是采集端重复埋点。不处理的话你算的用户活跃度会偏高。商品ID在不同时间窗口的重复某些商品在活动期和下架期反复出现直接统计商品热度会被“长期在架商品”霸榜。我看到这种情况时会把分析窗口拆细分别看周热度避免长周期商品掩盖短期爆品。行为序列中的异常跳变比如用户一整天没行为突然凌晨4点连续点了几百个商品然后迅速消失。这种通常是爬虫或脚本行为。我在分析时按“单用户单小时行为数”做一个分布把超过99.9%分位的用户行为标记为异常并剔除。5.4 分析效率的终极大招先抽样再全量如果时间紧张我建议先做一次 10% 用户的随机抽样跑通整个分析流程和推荐代码确认逻辑无误后再上全量数据。抽样数据会让你调试速度快一个数量级而且因为用户行为数据结构一致抽样验证过的逻辑基本可以直接套全量。抽样时要注意用用户维度抽样不要用“行级抽样”。行级抽样会把同一个用户的行为序列切得七零八落导致用户行为链条断裂后续算行为序列和共现矩阵都会出问题。最后分享一个我个人的体会。User Behavior Data from Taobao for Recommendation 这一套跑下来最大的收获不是学会了某个算法而是建立了“从业务数据到推荐方案”的完整闭环思维拿到数据先想业务、洗数据时找异常、分析时看漏斗、建模时权重先行、评估时注意时序。这套思维放到任何推荐场景都通用不管是商品推荐、内容推荐还是广告投放。如果你正准备拿这个数据集做项目还有一个扩展建议在ItemCF基础上叠加一个简单的 xDeepFM 或 DeepFM 排序模型把行为序列作为特征输入效果会明显上一个台阶。但前提是先把我前面讲的这些基本功走扎实排序模型只是锦上添花数据理解和特征工程才是地基。
返回列表