1. 用户画像到底在分析什么
1.1 从“淘宝用户行为分析”说起
“淘宝用户行为分析——用户画像”这个标题,乍一看像是电商数据分析的入门课题,但真正动过手的人都知道,它远不止跑几条SQL、画几张饼图那么简单。用户画像的本质,是把海量、零散、看似无规律的行为日志,压缩成一组可解释、可复用、能指导决策的标签体系。你拿到一份用户行为数据,里面有浏览、收藏、加购、购买这几类动作,还有时间戳、商品类目、用户ID,这些原始字段本身没有意义,只有把它们按用户维度聚合、按行为权重加权、按时间窗口切片,才能回答“这个用户是谁、他想要什么、他值多少钱”这三个核心问题。
我做用户画像项目有个习惯:先不急着写代码,而是拿一张白纸,把“我最终想回答的业务问题”列出来。比如运营想知道“哪些用户快流失了,该发什么券”,产品想知道“新用户第一次购买前平均浏览几个商品”,推荐算法团队想知道“哪些用户对价格敏感、哪些对品牌敏感”。这些问题决定了画像标签的粒度、更新频率和存储方式。如果一开始就闷头算RFM,最后很可能做出一堆没人看的报表。
这个项目适合谁参考?我认为有三类人:一是刚接触电商数据分析、想找一个完整案例练手的数据分析新手;二是需要搭建用户标签体系、但不知道从哪下手的运营或产品人员;三是想了解行为数据如何转化为业务策略的技术同学。不管你是哪一类,接下来的内容都会从数据理解、标签设计、实操计算到避坑经验,一层层拆开讲。
1.2 用户画像的四个核心维度
在淘宝这类综合电商场景下,用户画像通常围绕四个维度展开:属性维度、行为维度、价值维度和偏好维度。属性维度包括性别、年龄、地域这些相对静态的信息,但在行为数据里往往缺失,需要用行为反推;行为维度是浏览、收藏、加购、购买、评论、分享等动作的频次和时序;价值维度最经典的就是RFM模型,即最近一次购买时间、购买频率、购买金额;偏好维度则关注用户对类目、价格带、品牌的倾向。
这四个维度不是孤立的。举个例子,一个用户最近30天频繁浏览高端美妆、加购但不下单,他的行为维度显示高活跃,价值维度可能因为历史购买少而偏低,偏好维度则指向“高客单价美妆潜在客户”。如果你只算RFM,可能会把他归为低价值用户而放弃,但结合偏好维度,他其实是值得用大额券刺激的高潜用户。这就是为什么我说用户画像不能只做一套标签,而要做一套能交叉解释的标签体系。
注意:很多新手一上来就追求标签数量,觉得标签越多画像越准。实际上,标签之间如果高度相关,不仅增加计算成本,还会让后续策略互相打架。我一般建议先做20到30个核心标签,跑通业务闭环后再逐步扩展。
2. 数据理解与预处理的关键细节
2.1 行为数据的字段含义与陷阱
假设你拿到的是一份典型的淘宝用户行为日志,字段通常包括:用户ID、商品ID、类目ID、行为类型、时间戳。行为类型一般有四种:pv(浏览)、fav(收藏)、cart(加购)、buy(购买)。有些数据集还会包含地理信息或用户年龄性别,但真实场景下这些字段往往缺失严重,不能直接依赖。
这里有几个容易踩的坑。第一,时间戳的格式。很多公开数据集的时间戳是Unix秒级或毫秒级,直接转成日期时容易把时区搞错。我一般统一转成UTC+8的日期时间,再按天、小时、周几做衍生字段。第二,行为类型的权重。浏览、收藏、加购、购买对用户兴趣的表达强度完全不同,你不能简单地把它们都当成一次“互动”来计数。我的经验权重是:浏览1分、收藏3分、加购4分、购买5分,这个权重不是拍脑袋,而是基于“用户付出成本越高、兴趣越强”的逻辑。第三,重复行为的处理。同一个用户对同一个商品在短时间内多次浏览,可能只是刷新页面或误触,需要做去重或时间窗口合并。
还有一个隐蔽的陷阱:数据倾斜。淘宝的用户行为分布是典型的长尾分布,少数头部用户贡献了大部分行为记录。如果你直接对全量用户做聚合,计算资源会大量消耗在头部用户上,而长尾用户的画像反而被稀释。我的做法是先按用户ID做一次采样,对行为数超过某个阈值的用户单独处理,或者用分桶计算再合并。
2.2 数据清洗的实操步骤
清洗这一步,我通常按以下顺序操作,每一步都有明确的判断标准:
- 去除无效用户:行为记录少于3条的用户,画像可信度极低,直接过滤。这个阈值可以根据数据总量调整,但低于3条基本无法判断偏好。
- 去除无效商品:商品ID为空或类目ID缺失的记录,无法用于偏好分析,剔除。
- 时间范围截取:选择连续且完整的时间窗口,比如最近30天或90天。不要用有缺失的日期范围,否则RFM的“最近一次购买”会失真。
- 行为类型编码:把pv、fav、cart、buy映射为数值权重,方便后续加权计算。
- 去重与合并:同一用户对同一商品在同一小时内的多次相同行为,只保留一次。跨小时的行为保留,因为可能代表持续兴趣。
用Python的pandas做这些操作很直接,但数据量大时pandas会内存溢出。我一般用Dask或者直接上SQL做聚合,把清洗后的结果落地成宽表。下面是一个清洗逻辑的伪代码示例,你可以根据实际数据调整:
import pandas as pd # 读取原始日志 df = pd.read_csv('user_behavior.csv') # 时间戳转换 df['datetime'] = pd.to_datetime(df['timestamp'], unit='s') + pd.Timedelta(hours=8) df['date'] = df['datetime'].dt.date df['hour'] = df['datetime'].dt.hour # 行为权重映射 behavior_weight = {'pv': 1, 'fav': 3, 'cart': 4, 'buy': 5} df['weight'] = df['behavior_type'].map(behavior_weight) # 过滤低活跃用户 user_counts = df.groupby('user_id').size() valid_users = user_counts[user_counts >= 3].index df = df[df['user_id'].isin(valid_users)] # 去重:同一用户同一商品同一小时同一行为只保留一次 df = df.drop_duplicates(subset=['user_id', 'item_id', 'hour', 'behavior_type'])这段代码跑完,你得到的就是一份相对干净的、带权重的行为明细表。接下来所有画像计算都基于这张表。
提示:如果你的数据里包含“用户-商品”交互矩阵,注意稀疏性问题。淘宝场景下用户和商品的数量都是百万级以上,矩阵稀疏度通常超过99.9%,直接做协同过滤会非常慢。用户画像阶段不需要这么细,按类目聚合就够了。
3. 标签体系设计与计算逻辑
3.1 RFM模型的变体与参数选择
RFM是用户价值画像的基石,但直接套用经典RFM在淘宝场景下有几个问题。经典RFM的R是“最近一次购买时间”,但淘宝用户可能最近没有购买,却有频繁的加购和收藏,这些行为同样代表活跃度。所以我会把R扩展为“最近一次互动时间”,互动包括购买、加购、收藏、浏览,但购买的时间权重更高。具体做法是:取用户最近一次购买时间作为R_buy,最近一次任意行为时间作为R_any,两个都保留,后续分群时交叉使用。
F是购买频率,通常按最近90天的购买次数计算。这里有个细节:同一订单多件商品算一次还是多次?我的经验是按订单去重后计数,因为用户的一次购买决策对应一个订单,多件商品只是决策的延伸。如果你按商品件数算,会把批发型用户和普通用户混在一起。
M是购买金额,但很多公开数据集没有金额字段。如果没有金额,可以用“购买商品的平均价格带”或“购买类目的价值分”来替代。比如美妆类目的平均客单价高于日用百货,可以用类目均价作为金额的代理变量。这个替代方案在业务上完全可解释,而且比直接放弃M维度要好得多。
RFM的阈值划分,我一般不用固定数值,而是用分位数。比如R取最近一次互动距今天数,按20%、40%、60%、80%分位切成5档,分别赋1到5分。F和M同理。这样分出来的用户群在数量上相对均衡,不会出现某一类用户过多或过少的情况。分位数划分的另一个好处是,当数据分布随时间变化时,阈值会自动调整,不需要人工干预。
3.2 偏好标签的加权计算
偏好标签回答的是“用户喜欢什么”。在淘宝场景下,最核心的偏好是类目偏好和价格带偏好。类目偏好的计算逻辑是:对每个用户,按类目聚合行为权重,然后取权重最高的前三个类目作为偏好类目。但这里有个问题:如果用户浏览了很多类目但每个都只浏览一次,权重最高的类目可能只是随机噪声。所以我会加一个置信度过滤:只有当某个类目的行为权重占用户总权重的比例超过15%,且行为次数超过5次时,才认定为偏好类目。
价格带偏好的计算类似,但需要先把商品价格映射到价格带。价格带的划分没有统一标准,我一般按业务场景定:0-50元、50-100元、100-200元、200-500元、500元以上。然后按行为权重聚合,取占比最高的价格带。这里要注意,浏览价格带和购买价格带可能不一致。一个用户可能经常浏览高端商品但只购买低价商品,这代表“向往型消费”。我会把浏览价格带和购买价格带都保留,交叉分析时能发现这类用户。
除了类目和价格带,还可以做品牌偏好、时段偏好、促销敏感度等标签。时段偏好是看用户的行为集中在一天中的哪个时段,比如“夜猫型”用户集中在22点到凌晨2点,“上班摸鱼型”集中在10点到12点和15点到17点。促销敏感度则需要结合促销活动日期,看用户在促销期的行为权重是否显著高于非促销期。这些标签的计算逻辑都不复杂,关键是定义清楚“显著高于”的阈值。
3.3 用户分群的交叉策略
有了RFM和偏好标签,下一步是把用户分成可运营的群体。我常用的分群方法是先按RFM的R和F做九宫格,再在每个格子里按偏好标签细分。比如:
| R\F | 低频 | 中频 | 高频 |
|---|---|---|---|
| 近 | 新客/回流客 | 活跃客 | 核心客 |
| 中 | 沉睡客 | 普通客 | 忠诚客 |
| 远 | 流失客 | 预流失客 | 历史高价值客 |
这个九宫格的好处是,每个格子都有明确的运营动作。比如“近-低频”是刚有过互动但购买少的新客或回流客,适合发首单券或新人礼包;“远-高频”是曾经买过很多次但最近不来了的历史高价值客,适合发召回短信或大额券。在每个格子里,再按偏好类目细分,比如“近-低频-美妆偏好”和“近-低频-数码偏好”,运营文案和选品就能更精准。
注意:分群不是越细越好。我见过有人把用户分成几百个群,结果每个群只有几十个人,运营根本没法针对每个群做动作。我的经验是,核心运营群控制在10到15个,每个群至少占总用户的1%到2%,这样才有规模化运营的价值。其他长尾群可以合并为“其他”或只做自动化触达。
4. 实操过程与核心环节实现
4.1 从原始日志到用户标签宽表
整个实操流程可以拆成五步:数据加载、清洗、聚合、标签计算、落地存储。我以一份模拟的淘宝用户行为数据为例,走一遍完整流程。假设数据文件是CSV格式,包含user_id、item_id、category_id、behavior_type、timestamp五个字段,时间范围是最近90天。
第一步,加载数据并做基础清洗。用pandas读取后,先检查缺失值和重复值。如果user_id或item_id为空,直接删除;如果behavior_type不在pv、fav、cart、buy范围内,也删除。然后按前面说的规则过滤低活跃用户和无效商品。
第二步,构建用户-行为聚合表。按user_id分组,计算每个用户的总行为次数、购买次数、加购次数、收藏次数、浏览次数,以及最近一次行为时间、最近一次购买时间。这里用groupby加agg可以一次算完:
user_agg = df.groupby('user_id').agg( total_behavior=('behavior_type', 'count'), buy_count=('behavior_type', lambda x: (x == 'buy').sum()), cart_count=('behavior_type', lambda x: (x == 'cart').sum()), fav_count=('behavior_type', lambda x: (x == 'fav').sum()), pv_count=('behavior_type', lambda x: (x == 'pv').sum()), last_behavior_time=('datetime', 'max'), last_buy_time=('datetime', lambda x: x[df.loc[x.index, 'behavior_type'] == 'buy'].max() if (df.loc[x.index, 'behavior_type'] == 'buy').any() else pd.NaT) ).reset_index()第三步,计算RFM得分。用当前日期减去last_behavior_time得到R值,用buy_count得到F值,用购买类目的平均价格乘以购买次数得到M的代理值。然后对R、F、M分别做分位数切分,赋1到5分。这里要注意,R值越小越好,所以分位数切分后要反向赋分,最近互动的用户得5分。
第四步,计算偏好标签。按user_id和category_id分组,聚合行为权重,然后对每个用户取权重最高的前三个类目。同时按价格带聚合,取占比最高的价格带。这一步可以用groupby加apply实现,但数据量大时apply会很慢,建议用窗口函数或先聚合再排序取TopN。
第五步,把RFM得分、偏好标签、基础统计量合并成一张用户标签宽表,写入数据库或Parquet文件。这张宽表就是后续所有分析和运营动作的基础。
4.2 参数计算与阈值选择过程
在RFM计算中,分位数切分的具体参数需要根据数据分布来定。我一般先用describe()看R、F、M的分布,如果F的分布极度长尾,比如90%的用户购买次数在1到3次,那么按20%分位切分会导致大量用户挤在低分档。这时候我会改用自定义阈值:F=1为1分,F=2到3为2分,F=4到5为3分,F=6到10为4分,F>10为5分。这个阈值不是固定的,而是根据业务经验调整,核心原则是让每个分档都有足够的用户量,同时分档之间的行为差异明显。
偏好标签的置信度阈值也需要调。我一开始设的是行为权重占比超过10%且行为次数超过3次,结果发现很多用户被打了太多偏好标签,因为他们的行为分散在多个类目。后来把占比阈值提高到15%、次数阈值提高到5次,偏好标签的数量明显减少,但准确度提高了。这个调整过程需要反复看样本,我一般随机抽100个用户,人工检查他们的偏好标签是否合理,然后微调阈值。
价格带的划分同样需要看数据。如果数据集中大部分商品价格在50到200元之间,那么价格带可以细分为50-100、100-150、150-200;如果价格分布很广,就用更粗的划分。我的经验是,价格带的数量控制在5到7个,太少区分度不够,太多每个价格带的用户太少。
4.3 用户画像的存储与更新
用户画像不是算一次就完事,需要定期更新。淘宝场景下,行为数据是实时产生的,但画像更新不需要实时,通常按天或按周更新就够了。我一般用天级增量更新:每天计算最近90天的行为数据,覆盖更新用户标签宽表。这样既能反映最新行为,又不会因为实时计算带来过高的资源消耗。
存储方面,如果用户量在百万级以下,用MySQL或PostgreSQL就够了;如果上千万,建议用Hive或ClickHouse。标签宽表的字段设计要预留扩展空间,比如用JSON字段存储偏好类目列表,用数组字段存储价格带偏好。这样后续增加新标签时不需要改表结构。
提示:更新画像时要注意数据回刷。如果某天的数据源出现异常,比如日志丢失或重复,直接覆盖更新会导致画像失真。我的做法是保留最近7天的原始数据快照,更新前先做数据质量检查,确认无误后再覆盖。
5. 常见问题与排查技巧实录
5.1 数据质量问题的排查思路
用户画像项目里,数据质量问题占了排查工作的一半以上。我遇到最多的三类问题是:时间戳异常、行为类型缺失、用户ID重复。时间戳异常表现为某些记录的时间戳是未来时间或1970年,这通常是数据采集或传输错误,直接剔除。行为类型缺失表现为空值或未知类型,如果占比低于1%,直接删除;如果占比高,需要联系数据源排查。
用户ID重复有两种情况:一种是同一用户在不同设备上登录,产生多个ID;另一种是数据重复写入。前者需要用设备指纹或登录账号做ID映射,后者直接去重。ID映射在淘宝场景下很常见,但公开数据集通常没有设备信息,只能按用户ID去重。
还有一个隐蔽问题:行为类型的顺序。在真实场景下,用户的行为是有时序的,比如先浏览再加购再购买。如果数据里购买记录出现在浏览记录之前,说明数据有问题。我会按用户ID和时间戳排序,检查行为序列是否符合“pv -> fav/cart -> buy”的常见路径。如果大量记录不符合,说明数据采集或清洗环节出了问题。
5.2 画像标签不准的调试方法
标签不准通常有三种原因:阈值不合理、权重设计有偏、数据窗口太短。调试时我一般从样本入手,随机抽100个用户,人工看他们的行为记录和生成的标签,找出明显不合理的案例。比如一个用户明明经常买母婴用品,但偏好标签却是“数码”,这可能是权重设计问题——数码类目的浏览权重被高估了。
调试阈值时,我会画标签分布的直方图,看是否出现“双峰”或“断崖”。如果某个标签的分布集中在两端,说明阈值把用户硬生生切成了两类,中间没有过渡。这时候需要调整分位数或改用聚类方法。调试权重时,我会做敏感性分析:把某个行为的权重调高或调低10%,看标签结果变化大不大。如果变化很大,说明权重设计不稳定,需要重新评估。
数据窗口太短是新手常犯的错误。比如只用最近7天的数据算RFM,R值会很准,但F和M会因为窗口太短而失真。我的经验是,行为窗口至少30天,购买窗口至少90天。如果数据量允许,用180天甚至365天的购买数据算F和M会更稳定。
5.3 常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| 用户标签数量异常多 | 置信度阈值太低 | 检查偏好标签的占比和次数阈值 | 提高占比阈值到15%以上,次数阈值到5次以上 |
| RFM分群结果不均衡 | 分位数切分不适合长尾分布 | 画F和M的分布直方图 | 改用自定义阈值,确保每档用户量均衡 |
| 画像更新后标签突变 | 数据源异常或窗口滑动 | 对比更新前后的原始数据量 | 保留数据快照,更新前做质量检查 |
| 偏好类目与购买类目不一致 | 浏览和购买行为权重混淆 | 分别计算浏览偏好和购买偏好 | 保留两套偏好标签,交叉分析 |
| 计算速度慢 | 数据倾斜或全量计算 | 检查用户行为分布 | 对头部用户单独处理,用增量更新替代全量 |
注意:排查问题时,先看数据、再看逻辑、最后看代码。我见过太多人一上来就怀疑代码写错了,结果查了半天发现是数据源本身有问题。养成先做数据质量检查的习惯,能省下大量调试时间。
6. 从画像到运营策略的落地经验
6.1 不同用户群的触达策略
画像算出来不是终点,能指导运营动作才有价值。我一般把用户群按RFM九宫格和偏好标签组合,给出具体的触达策略。比如“近-低频-美妆偏好”用户,他们最近有互动但购买少,偏好美妆,适合推送美妆类目的首单券或小样试用装。“远-高频-母婴偏好”用户,曾经买过很多次母婴用品但最近不来了,适合推送母婴用品的召回券或新品通知。
触达渠道也要匹配用户群。年轻用户偏好推送和站内信,中老年用户可能更习惯短信。时段偏好标签在这里很有用:夜猫型用户在晚上10点后推送,打开率明显更高。这些策略不是拍脑袋,而是基于画像标签的交叉分析。我做过一次A/B测试,按画像标签分群推送的转化率比全量推送高了40%以上。
6.2 画像效果的评估指标
画像做得好不好,不能只看标签数量,要看业务效果。我常用的评估指标有三个:覆盖率、准确率和提升度。覆盖率是指有标签的用户占总用户的比例,低于60%说明标签体系覆盖不足。准确率需要人工抽样验证,我一般抽200个用户,看标签与人工判断的一致率,低于80%就需要优化。提升度是看按画像分群运营后,转化率、客单价等指标相比全量运营提升了多少。
这三个指标里,提升度最重要,但也最难算。我的做法是设计对照实验:随机选一部分用户按画像分群运营,另一部分用户全量运营,对比两组的转化率差异。如果提升度不显著,说明画像标签没有抓住关键差异,需要重新设计标签体系。
6.3 我踩过的坑与经验总结
做用户画像这些年,踩过的坑不少。最大的一个坑是过度依赖RFM。早期我做画像只算RFM,结果发现很多高价值用户被漏掉了,因为他们最近没有购买但一直在浏览和加购。后来加入行为活跃度标签,才把这些“沉默高潜”用户找出来。另一个坑是忽略数据时效性。有一次我用三个月前的数据做画像,结果运营按画像推送的券全部过期了,转化率惨不忍睹。从那以后,我坚持画像数据不超过7天,重要标签每天更新。
还有一个经验是画像要可解释。我见过一些团队用深度学习做用户 embedding,效果确实好,但运营看不懂,不知道怎么用。用户画像的标签必须是运营能理解、能直接对应到动作的。比如“价格敏感型”比“向量维度37的值高”有用得多。所以我现在做画像,优先用规则和统计方法,只有在规则方法效果不够时才考虑复杂模型。
最后分享一个小技巧:画像标签的命名要统一规范。我一般用“维度_具体值”的格式,比如“偏好类目_美妆”、“价格带_100-200”、“活跃度_高”。这样在SQL查询和报表展示时一目了然,不会出现“美妆偏好”和“喜欢美妆”两个标签指同一件事的情况。规范命名看起来是小事,但能省下大量沟通成本。