
1. 这次作业的来龙去脉从选题到拆解题意第五次作业交上去之后我坐在电脑前愣了好一会儿。倒不是说题目有多难而是这次和前四次完全不是一个量级——前几次顶多让你跑通一个流程、验证一个函数这次直接给了一整份电商用户行为数据集要求做完整的复购分析并给出业务建议。表面上是“第五次作业”实际上相当于一个小型实战项目。我拿到题目后的第一反应不是写代码而是先花了一个晚上把题目要求读了三遍把关键词全部圈出来。作业原话大概是这样的基于某电商平台用户行为数据分析用户复购行为特征识别高价值用户群体并给出可落地的运营建议。数据表给了三张用户信息表、订单表、商品类目表。看起来清晰但真正动手才发现这份数据比你想象中脏得多。先说我的选题思路。复购分析其实有好几种切入角度可以按时间维度看复购间隔分布可以按用户维度看复购频次和金额贡献也可以按商品维度看哪些类目更容易产生复购。我最后选了“用户分层为主、商品类目为辅”的路线。原因很简单作业要求里明确提到了“识别高价值用户群体”这就意味着必须从用户视角出发做分层而商品类目分析的价值在于帮你解释“为什么这群用户复购率高”——是因为他们买的品类本身复购周期短还是因为用户忠诚度高。两者结合结论才站得住脚。这道题最迷惑人的地方在于它看起来像一道数据分析题实际上考的是业务理解能力。数据清洗、透视、画图这些技能前四次作业已经考过了第五次真正想看你的是拿到一堆数字之后你能不能讲出一个有逻辑、能落地的商业故事。想通了这一点后面所有步骤都有了方向。2. 数据预处理的那些坑清洗比分析更花时间2.1 数据集的“第一眼印象”与字段梳理打开数据文件的那一刻我就知道这事儿没那么简单。订单表一共67万行用户表2.4万行而订单表里居然有将近8万行是重复记录。这应该是线下渠道和线上渠道数据合并时产生的重复同步不是单纯的导出失误。我先做了字段梳理列了个清单表名关键字段字段类型常见问题用户信息表user_id, 注册时间, 城市等级, 年龄区间, 性别文本/日期城市等级有缺失性别有未知分类订单表order_id, user_id, 下单时间, 实付金额, 商品类目ID文本/数值/日期存在重复订单、金额为0或负数的异常记录商品类目表类目ID, 一级类目, 二级类目文本部分类目ID在订单表中找不到对应关系字段梳理这件事千万别偷懒。我踩过前四次作业的坑那会儿拿到数据就急着跑describe()和info()结果分析做到一半才发现某个字段的含义理解错了被迫返工。这次我老老实实把每个字段都看了一遍特别是那些一眼看不懂的编码字段——比如订单表里有个pay_type字段取值是0、1、2、3但题目文档里根本没解释。我后来翻了好几页数据说明才发现0代表在线支付1代表货到付款2和3是分期和其他。如果一开始不搞清楚后面分析支付方式与复购的关系时就全乱了。2.2 去重、补缺、剔除异常三步走的细节决策第一步是去重。我对订单表按order_id做了去重保留最早的一条记录。这里有个细节有些订单虽然order_id相同但商品类目ID不同说明一单买了多个类目的商品。这类记录不能简单按order_id去重否则会损失类目信息。我的处理方式是先按order_id类目ID维度去重再按order_id聚合出每单的类目数量、总金额、商品件数。最后去重后订单总数是59万行左右比原始数据瘦身了12%。第二步是缺失值处理。用户信息表里城市等级缺失了1200多条占比约5%。我没有直接删除这些用户因为后面做用户分层时城市等级只是辅助维度删掉反而会让样本有偏。我采用的是把“城市等级”缺失的用户单独标记为“未知”分类。性别字段的处理逻辑类似只是我把“未知”性别也保留着因为后续分析中发现这个群体反而有不错的复购表现算是一个意外收获。第三步是异常值处理。这里要特别小心。订单金额为0的记录我一开始想直接删除后来随机抽了50条去看发现这类订单大量集中在某几个特定类目极有可能是“赠品订单”或“内部调拨单”本质上不是真实消费行为删除是合理的。但金额为负数的记录必须查清楚——负金额可能是退款记录但退款订单并没有单独的退款时间字段。如果直接删掉会虚增销售额如果当成正常订单又会拉低客单价。我的折中方案是将实付金额小于0的订单剔除同时统计退款订单占比在报告里说明这部分用户可能存在的退货倾向。最终有效订单58.2万行占原始数据的86.7%。2.3 时间字段处理最容易被忽视的定时炸弹时间字段是这次作业里最大的隐藏地雷。订单表里的下单时间字段是字符串格式我一开始按Y-m-d H:i:s的格式解析本地测试没问题结果全量跑的时候报错了。排查后发现部分订单的时间格式是2024/3/5 9:30混用了斜杠分隔符而且在日期和时间之间有的用单个空格有的用了多个空格。这类问题在真实工作中太常见了。我用pandas的to_datetime()加errorscoerce参数先做一次宽松解析把所有无法解析的时间置为NaT然后统计无法解析的行数和分布情况。当时发现有2000多行时间解析失败占0.4%左右比例不大但在做“首次购买时间”和“最近一次购买时间”这类计算时这些脏数据足以让结果产生明显偏差。我的处理思路是分两批能解析的先解析不能解析的尝试用正则表达式提取日期部分手动拼接格式实在解析不了的才删除。最后损失不到800行订单数据整体影响可以接受。还有一个细节用户表中的注册时间字段只有日期没有时分秒但订单表有完整时间戳两者关联做“注册后多久产生首单”这个分析时需要统一粒度否则会出现负值——用户注册当天就下单价差为负的荒谬结论。我统一把时间粒度降到“天”才避免了这个尴尬问题。3. 核心分析思路与模型选择逻辑3.1 复购指标怎么定义先统一口径再谈策略数据分析里最怕的就是口径不统一。什么叫“复购”行业内常规定义是“非首次购买行为”即一个用户完成了至少两笔订单第二次及以后的订单都算复购订单。但这里有个细节部分用户在第一笔订单里买了多件商品或者多个类目那“第二次下单”算复购还是“第二次买同一个类目”算复购我最后定了一套统计口径写进了报告开头复购用户在观察周期内下单次数 ≥ 2 的用户复购订单该用户的第2笔及之后的订单复购率复购用户数 / 总下单用户数回购间隔相邻两笔订单之间的时间差这套口径的好处是直观、好解释也方便后面做用户分层。我在报告里明确写了口径说明这样即使别人拿到我的分析结果也能清楚知道每个数字是怎么算出来的。3.2 为什么选RFM简化版而不是完整版RFM模型是用户分层里的经典方法按最近一次消费时间Recency、消费频率Frequency、消费金额Monetary三个维度打分每个维度分高/中/低三档组合出8类用户。但我实际跑数据的时候发现这套模型在这个场景里有两个问题第一电商数据天然存在“高金额低频”和“低金额高频”两类用户完整版RFM按三分位数切成8类之后很多用户类别的人数极少难以形成统计意义。 第二作业维度是一份课程作业不是正式商业咨询项目结论要能让老师一眼看懂8类用户太碎。所以我做了一点改动把RFM简化成“FM”二维矩阵其中F表示观察期内的下单次数分档M表示累计实付金额分档各分三档组成9宫格。R维度作为辅助参考不参与矩阵划分。这样做的好处是这样高F高M核心高价值用户铁粉高F低M高频低价用户羊毛党或低价品爱好者低F高M低频高价值用户大促型用户低F低M沉默边缘用户实际上我跑了9宫格的人数分布后发现高F高M用户只占总用户数的6.3%却贡献了31.5%的累计销售额头部效应特别明显。这个数字成了整篇报告里最核心的一个论据。3.3 数据分析里最容易被忽略的“对照组思维”做复购分析很容易陷入一种陷阱只看复购用户的表现不看非复购用户的差异。比如你算出复购用户的平均客单价是185元沉默用户是120元就得出结论“复购用户消费能力更强”。但这里有个隐藏问题客单价高可能是复购用户买的东西本身就贵而不是因为他们复购所以客单价高。关联关系不等于因果关系。我在报告里加了一层“类目对照”分析把复购用户和非复购用户的首次订单类目分布做对比发现两者在类目偏好上确实存在显著差异。复购用户的首次订单中美妆个护和母婴类目占比明显更高而沉默用户的首次订单中服饰内衣和食品生鲜类目占比更高。这说明复购行为不只是用户属性造成的和品类本身的消费周期也有很大关系。比如母婴用户一旦买了奶粉后续的纸尿裤、辅食都是高频刚需天然更容易复购。这个维度的加入让整份作业的深度一下子不一样了。老师评语里专门提到“控制了类目变量之后来谈复购思路是对的”。4. 可视化呈现怎样让图表自己会说话4.1 图表选型的三个原则少用饼图、强调对比、标注结论作业要求里有一条是“必须包含不少于5张可视化图表”。我一开始按“每张图说明一个观点”的思路来规划而不是先画一堆图再往报告里塞。我最终选了7张图每张都有明确的表述重心复购用户与沉默用户的订单分布对比用柱状图9宫格用户分层的人数占比用热力图不同类目的复购率排名用水平条形图用户复购间隔的时间分布用折线图重点标出峰值区间高价值用户首次购买类目分布用堆叠柱状图城市等级与复购率的关系用分组柱状图用户生命周期价值TOP20类目用气泡图这里我不建议用饼图。饼图的视觉欺骗性太强尤其是超过5个分类的时候人眼很难分辨两个相近面积的扇形谁大谁小。而且饼图本质上只能展示占比没法承载太多对比信息。如果你的老板、客户、老师都是看数据说话的人尽量少用饼图。4.2 用Python画图的实战代码与参数细节这次作业我全程用了Python的matplotlib和seaborn库统一主题风格。下面贴一段我画9宫格热力图时的核心代码给有需要的同学参考。import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # rf 每个用户的F/M分档结果包含F_level和M_level两列 pivot rf.pivot_table(indexM_level, columnsF_level, valuesuser_id, aggfunccount) # 顺序调整让高段位在左上角 pivot pivot.loc[[高M, 中M, 低M], [高F, 中F, 低F]] plt.figure(figsize(8, 6)) sns.heatmap( pivot, annotTrue, fmtd, cmapYlOrRd, linewidths0.5, annot_kws{size: 12}, cbar_kws{label: 用户数量} ) plt.xlabel(消费频率分档, fontsize12) plt.ylabel(消费金额分档, fontsize12) plt.title(用户F-M矩阵分层人数分布, fontsize14, pad20) plt.tight_layout() plt.savefig(user_matrix.png, dpi200) plt.show()几点实操心得。第一annotTrue显示数值时如果人数差异太大比如某些格子上万人某些格子几十人建议用归一化后的占比百分比否则热力图色差会被极值主导视觉上失去区分度。第二字体问题matplotlib默认字体在中文环境下会漏字一定要在代码开头设置中文字体比如plt.rcParams[font.sans-serif] [SimHei]同时设置plt.rcParams[axes.unicode_minus] False否则负号会显示成方块这种细节扣分很冤枉。4.3 图上标注“所以呢”让图表替你做汇报我在批改前几次作业的时候注意到一个普遍问题图壮是壮观但图下面是空的没有任何解释读者得自己去猜想表达什么。这次我在每张图下面都配了两到三句话的“图注”结构是“这张图展示了什么 最关键的发现 可能的业务含义”。比如复购间隔分布那张折线图从数据可以看出用户复购间隔的峰值集中在7到14天和28到35天两个区间。如果只画一条曲线这个信息就在那里但大部分人不会自己去解读。我在图注里点明第一峰值大概率对应周消费习惯第二峰值大概率对应月度囤货行为建议运营在用户首次购买后的第6天和第25天左右推送针对性商品效果可能更好。这样一来图和策略就形成了闭环而不是两张皮。这一点我认为作业交上去能不能拿高分真的很大程度取决于此——老师不是只给你图打分而是给你的“解读能力”打分。5. 建模过程中的意外发现偏离预期才是常态5.1 原本以为性别差异很大结果数据把这种假设推翻了在做用户画像分析时我原本假设女性用户的复购率会显著高于男性用户。这个假设来自直觉也是很多电商运营文章里常见的论点。但实际跑出来的数据却是女性用户的复购率为34.2%男性用户为33.8%差异不到0.5个百分点统计检验也没有通过显著性水平。这是一个重要的“反直觉”结果。我刚开始怀疑是不是数据有问题专门又查了一遍性别字段的质量。结果发现性别字段中“未知”分类的占比高达18%这批用户在订单中的复购率反而是最高的达到42%。所以我后来在报告里从两个可能解释的角度展开了讨论——一是这部分用户填写性别意愿低但不代表消费行为不活跃二是存在相当比例的“代购”场景用户购买的商品不是自己使用所以性别信息缺省本身可能就是一个有信息量的特征而不是单纯的缺失数据。这个发现告诉我数据分析不要预设答案哪怕是行业共识也要在自己拿到数据上验证一遍再下结论。真实世界的数据往往比教科书里的案例复杂得多。5.2 高价值用户的“首单类目”特征竟然如此集中另一个意外发现是在9宫格中属于高F高M的核心用户他们的首次购买类目极度集中。前5个类目占了全部核心用户首单的67%。尤其是母婴类下的“奶粉/辅食”子类目虽然整体订单量占比只有4.3%但在高价值用户中的首单占比高达12.6%是整体占比的将近三倍。这个数字的含义很清晰某些类目天然具有“钩子效应”——用户一旦在这个类目完成首次购买后续产生复购的概率远高于平均水平。从运营角度来说这就意味着通过优惠补贴换取新客时不应该所有类目平均用力而应该优先选择这些“钩子类目”投入资源拉来的新客更可能沉淀成高价值用户。这部分分析我用了交叉列联表和卡方检验来验证类目与用户分层的关联性p值远小于0.001结果是显著的放在报告里说服力很强。5.3 时间窗口的选择暗藏玄机为了分析用户生命周期我把观察周期设成了2023年10月到2024年9月一共12个月回看注册用户在这段时间内的订单行为。但这里有个边界效应问题观察期开始时已经注册的老用户和观察期内新注册的用户两者的“观测时间长度”不一样如果用同一套复购频率标准去衡量必然导致老用户复购次数占便宜。我当时做了两套方案做对比。方案一是以所有用户为基准计算方案二是只计算“在观察期内注册的用户”。两套方案算出的复购率差异接近10个百分点这让我意识到时间窗口的选择真的会直接影响结论方向。我最后在报告里以“观察期内新注册用户”为主数据集因为这样可以完整追踪从首单到复购的全过程不会出现“首单在观察期之前”的情况逻辑更干净。这样处理带来一个额外的好处我可以计算每个用户从注册到首单的间隔时间分布发现76.3%的用户在注册当天就完成了首单另有12%在注册后7天内完成首单。这个“注册即首单”的高时效性说明平台的激励引导政策非常有效但从复购角度看初始刺激过后用户很容易流失真正需要运营投入精力的窗口期在首单后的第7到第30天。6. 提交前的自查与复盘这些坑希望你们绕开6.1 自查清单数据、代码、图表、业务结论四层检查在提交第五次作业前我列了一个自查清单按顺序过了一遍口径检查报告里出现的每一个指标是否都有明确的文字定义有没有两个地方用了同名词但含义不一致代码检查关键SQL或Python代码能否重新跑通随机抽了20%的代码重新执行确认结果一致图表检查图的坐标轴是否有标签中文字体是否正常配色是否对色弱读者友好结论检查每一个业务结论是否都有对应的数据和图表支撑有没有自己脑补的内容其中最容易翻车的是最后一条。因为写着写着就会不自觉地把“我觉得”变成“数据显示”有时候数据和结论之间根本没有因果链条。我的应对方式是给报告里每条结论前面加一个标记——“[数据支撑]”和“[推断]”两类一目了然。6.2 我提交之前临时改掉的一个重大问题第一次跑完整个分析流程后我准备直接写报告后来做数据校验时发现一个严重问题我把“复购率”定义成“复购用户数 / 总用户数”但分母里的“总用户数”包含了大量从未下单的注册用户算出来的复购率只有13.7%会严重低估平台的复购表现。实际上用户分析里更通用的口径是“复购用户数 / 有成交用户数”也就是把零成交用户排除在外。换了这个分母之后复购率提升到34.6%数字差异巨大。这个问题如果提交前没抓到整个报告的核心指标就会失真。它提醒我一件事数据分析报告里最可怕的错误不是代码跑错或者图表画错而是“指标定义错误”这种看似基础、实际上能误导所有人的问题。后来我把分母定义用粗体标注在报告开头的方法论部分并且提供两种口径的对比数据既显示出严谨性也让老师一目了然知道我意识到了这个问题。6.3 复盘总结第五次作业教会我的三件事第一次做完整个复购分析闭环回头看我发现这五个环节虽然看起来各有各的复杂之处但它们其实是串联在一起的数据准备是为了让后续分析可信分析是为了让数据可视化有的放矢可视化是为了让业务结论有据可依而业务结论最终又要回头验证前面的数据口径是否正确。任何一个环节出了问题整条链路都会坍塌。另一个我在过程中反复体会到的点是业务知识和分析技术是同样重要的。光会写pandas和matplotlib但不懂“什么叫复购”“什么叫用户生命周期”做出来的分析大概率是自嗨。相反如果只懂业务不会用数据验证得出的结论也容易变成拍脑袋。第五次作业真正想考察的可能就是这两者的结合而这也现实工作中分析师和运营岗的日常状态。最后分享一个我自己现在还在用的小习惯之后接到任何新作业、新任务我会先花至少20%的时间做“题意理解和口径定义”再动手取数和建模。磨刀不误砍柴工这条道理在这次作业里得到了最完整的验证。