资讯动态

基于Python的电商用户行为分析系统实战:从数据清洗到RFM用户分层

发布时间:2026/9/30 3:34:35 来源:尧图企业网站定制
开题那会儿导师跟我说“电商用户行为分析”这个题目时我心里想的是这不就是查查点击量、画几个柱状图吗直到自己把数据拉下来、跑完第一版分析、再看着那些漏斗数字发呆的时候才明白这个题目真正恶心的点不在于写代码而在于——你到底能不能从几千万条用户点击记录里讲出一个让答辩老师点头的业务故事。这篇博文我尽量把整个系统的设计思路、数据库建表、核心分析模块、踩坑记录全部抖出来给正在做课程设计或者毕业设计的同学一个能直接抄作业的版本。1. 项目从哪来、要解决什么问题1.1 电商用户行为分析到底分析啥很多人把“用户行为分析”理解成统计PV和UV这个理解不能说错但太浅了。电商平台每天产生的用户行为数据本质上是用户在跟商品、页面、活动发生交互的完整轨迹用户今天几点打开了App、先看了什么商品、有没有加购、有没有收藏、最终有没有下单这些行为串在一起才是完整的用户故事。所以这个系统的核心任务不是做报表而是从行为数据中还原用户决策路径并从中找到业务优化的切入点。实操中我把它拆成了四个分析主题第一流量健康度也就是PV、UV、人均点击量这些基础指标判断平台整体流量是涨是跌第二转化漏斗从点击到收藏、加购、支付每一步都在流失流失在哪一步最严重哪里就是优化重点第三用户价值分层不同用户在平台上的活跃程度和消费意愿差异很大得用RFM模型把用户分成高价值、潜力、流失风险等群体这是后续做精准运营的基础第四商品与时段偏好哪些商品最受欢迎、用户集中在什么时间段活跃对应的是选品策略和营销活动排期。这套分析逻辑放到课程设计里就构成了系统的四大功能模块放进论文里则是完整的业务分析框架。答辩时老师问“为什么做这四个模块”你就可以从流量诊断、转化优化、用户运营、选品策略四个业务场景去答比单纯说“我分析了PV和UV”有说服力得多。1.2 课程设计与毕业设计的选题差异在做之前得先搞清楚一点课程设计和毕业设计对这个系统的要求完全不同。课程设计一般只要求你跑通流程、把分析结果展示出来功能完整性是第一位的数据量小一点没关系甚至用本地SQLite都能交差。但毕业设计会要求你体现“系统性”和“研究深度”这意味着你不仅要能跑出图表还得有数据库设计、模块化代码、合理的项目结构以及最终的结论分析——往往还要求你把数据导入MySQL这类正经的数据库管理系统而不是光在Pandas里跑完就拉倒。我做的时候是把两者兼顾了代码层做得模块化每个分析维度独立成一个函数数据库层用MySQL建库建表同时保留了CSV读取的快速通道。这样课程设计答辩时我可以演示从数据库读取的完整链路平时自己调参验证时又可以直接读取原始文件不用反复跟数据库打交道。另外要提醒一点选题虽然叫“基于Python的电商用户行为分析系统”但本质上它是一个数据分析项目不是Web开发项目。所以不要跑偏去搞什么Django、Flask前端页面——系统的主界面就是你的图表输出和结论文档。把这些图表组织好、把业务结论写清楚比套一个花架子网页值钱得多。1.3 数据从哪来数据集说明与预处理思路这个题目通用的数据集是淘宝的UserBehavior行为日志网上很容易找到通常是一个CSV文件每行代表一条用户行为记录。字段一共五个用户ID、商品ID、商品类目ID、行为类型、时间戳。行为类型只有四种取值pv代表点击、buy代表购买、cart代表加入购物车、fav代表收藏。注意这里没有“支付金额”字段所以后面所有跟金额相关的分析比如传统的RFM模型中的M值都要做改造我会在3.4节详细讲怎么处理。时间戳是Unix秒级格式需要转换成可读的时间。原始数据集可能非常大完整版动辄上亿条学生电脑直接跑Pandas很容易内存爆掉。我的做法是先抽取一个子集按用户ID抽样比如取20万用户的所有行为记录大约能抽出几百万条数据。这个量级对16G内存的笔记本来说在Pandas里可以流畅处理同时也足够支撑各类分析结论的统计显著性。2. 整体架构与技术选型2.1 技术栈选型与选择理由这个系统的技术栈选型是我经过对比后确定的Python 3.10作为主开发语言数据分析生态最成熟Pandas、NumPy、Matplotlib、Seaborn这些库全部是现成的课程设计阶段不用重复造轮子。Pandas承担核心的数据清洗和聚合计算它的groupby、merge、pivot_table三个方法能覆盖这个项目95%以上的数据处理需求。MySQL作为最终的数据库存储方案因为毕业设计需要体现数据库设计能力建表语句、索引设计、Python连接MySQL的链路都是加分项用SQLite虽然简单但答辩时撑不住追问。SQLAlchemy负责Python和MySQL之间的数据交互能写ORM也能直接执行原生SQL我主要是用它做批量写入和查询。Matplotlib Seaborn负责可视化中文字体和样式需要额外配置这是几乎所有同学都会遇到的问题后面5.2节会详细讲。选型逻辑其实很朴素不是选最潮的技术而是选最不容易翻车、同时能满足评分要求的技术。比如可视化也可以用Plotly做交互式图表很炫但课程设计答辩现场的电脑不一定装好了依赖而且静态图片直接嵌进论文里更方便。所以我的原则是核心工具求稳次要工具求简。2.2 核心流程设计从原始数据到业务结论整个系统的处理流程可以概括为五条线原始数据读取、数据清洗、数据库入库、指标计算、可视化输出。听起来简单但每一条线展开都有细节。读取环节我用Pandas的read_csv按指定列名加载数据同时指定数据类型来减少内存占用——user_id、item_id、category_id都用int32behavior用category类型这样一个字段能省下不少内存。清洗环节要做的是去重、过滤异常时间戳、剔除无效用户。入库环节是把清洗后的数据写入MySQL注意写入前要建好索引不然几百万条数据查询会慢到怀疑人生。指标计算环节把业务问题翻译成Pandas操作这个环节要反复验证计算口径是否正确。可视化输出环节是最后一步用图表回答业务问题并且配上一段文字结论。我在做这个项目时最大的体会是一定要把“数据流”意识贯穿始终。很多同学写着写着就把代码写成一个大脚本清洗和分析都搅在一起改一个参数就得从头跑一遍。我在代码结构上做了清晰的阶段划分每个阶段有独立的入口函数数据状态清晰后期调试和写论文时都省力很多。2.3 数据库设计建表、字段与索引思路数据库设计是这个项目的核心收分点。我设计的核心表叫user_behavior字段如下CREATE TABLE user_behavior ( id BIGINT AUTO_INCREMENT PRIMARY KEY, user_id BIGINT NOT NULL, item_id BIGINT NOT NULL, category_id BIGINT NOT NULL, behavior VARCHAR(10) NOT NULL, ts DATETIME NOT NULL, INDEX idx_user (user_id), INDEX idx_item (item_id), INDEX idx_behavior (behavior), INDEX idx_ts (ts) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;这张表的设计有几个意图要解释清楚。第一行为类型用VARCHAR而不是ENUM虽然在Python这边有限定只有四种取值但数据库层面留一点灵活性后续如果业务需要新增行为类型就不用改表结构。第二索引策略上四个查询字段都建了独立索引没有建联合索引因为我的查询场景大多是单字段过滤加聚合联合索引的使用率不高反而会占用额外空间。第三表引擎选InnoDB是为了支持事务和行级锁虽然这个项目没有复杂事务但InnoDB的聚簇索引特性对主键查询效率有帮助。数据入库时有个性能细节几百万条数据一条条INSERT肯定不行。我整理了一个批量写入的策略用Pandas的to_sql方法配合chunksize参数每批五千条实测写入速度比逐条INSERT要快几十倍。还有一个坑是csv里的时间戳最初是Unix秒格式写入MySQL前要先转换成Python的datetime对象否则数据库里存的全是1970年后面查起来非常痛苦。3. 核心模块实现一步步拆细节3.1 数据清洗最容易翻车的环节不要以为数据清洗只是把空值删掉那么简单。电商行为日志里的脏数据比你想象得多同一个用户在同一秒点击同一商品可能重复记录了多次我们叫这种数据为爬虫或刷量制造的垃圾流量时间戳也有异常的有些时间戳转换成年份之后是2035年一看就是数据源错误还有些用户ID对应的行为记录只有一条点击没有其他任何行为这种极短会话用户对整体分析结论的影响很小可以在过滤噪声时一并剔除。我实现的清洗流程分四步走。第一步去重基于所有业务字段做全字段去重注意不能带上自增ID去比较否则永远不可能重复。第二步时间戳转换使用pd.to_datetime加units参数转换成标准时间后过滤掉超出分析时间范围的记录。第三步用户过滤按用户维度计算行为总数把行为数小于5的低活跃用户剔除减少噪声。第四步格式统一把Behavior字段做映射确保只有pv、buy、cart、fav四种取值其他值一律标记为异常并删除。columns [user_id, item_id, category_id, behavior, timestamp] df pd.read_csv(user_behavior.csv, namescolumns, headerNone) df[timestamp] pd.to_datetime(df[timestamp], units) # 去重 df df.drop_duplicates(subset[user_id, item_id, category_id, behavior, timestamp]) # 行为类型过滤 valid_behaviors [pv, buy, cart, fav] df df[df[behavior].isin(valid_behaviors)] # 剔除极低活跃用户 user_counts df.groupby(user_id)[behavior].count() valid_users user_counts[user_counts 5].index df df[df[user_id].isin(valid_users)]清洗完成后一定要打印一份清洗前后的数据量对比写论文时这个数字就是数据质量分析的证据。我当时清洗前是500万条清洗后剩460万条左右大约8%的脏数据被剔除这个比例在电商日志的清洗中是正常范围。3.2 流量指标从PV、UV到用户活跃画像流量分析是用户行为分析的基础模块但这里也有大学问。PV页面浏览量和UV独立访客数虽然是一组最基础的指标但计算口径稍有不同结论就会完全不一样。比如UV的计算严格来说是去重后的用户数如果你直接count那得到的是PV而不是UV。我在代码里是这样做的PV直接用行为记录计数UV则使用nunique方法对用户ID去重计数人均浏览量用PV除以UV。有了PV和UV之后进一步按天聚合就能得到流量趋势图。我画了两张核心图第一张是每日PV和UV的双折线图用来观察整体流量的变化趋势第二张是每小时平均PV的柱状图用来分析用户在一整天里的活跃时段分布。这个时段分布非常有意思我发现凌晨两点到四点是流量低谷晚上八点到十点则是明显的高峰期这说明平台的用户群体偏年轻化晚间的运营活动空间更大。再往下还可以做用户活跃度分层。我把用户按日均行为数分成了三类小于10条为普通用户10到30条为活跃用户30条以上为重度用户。分层用Pandas的cut方法实现然后统计每一层的人数占比和行为占比。我跑出来的结果相当符合二八法则大约15%的重度用户贡献了超过40%的行为量这类用户是平台最核心的资产后续的RFM分层也印证了这一点。3.3 转化漏斗找到业务流失的关键断点转化漏斗是电商用户行为分析里业务价值最高的模块。它回答的问题是一百个用户点了商品究竟有多少人走到了最后的下单环节每一步流失了多少人从电商的业务逻辑来看用户决策路径基本是点击商品pv→ 收藏商品fav→ 加入购物车cart→ 购买buy。虽然真实的决策路径可能更复杂比如有的人跳过收藏直接下单但做漏斗分析时我们只看整体环节的转化率这样能判断整个平台在哪个环节的用户流失最严重。funnel df.groupby(behavior)[user_id].nunique().reindex([pv, fav, cart, buy]) funnel_rate funnel / funnel[pv] * 100我在计算时有一个重要细节漏斗的每一步用户数都做了去重处理。比如同一个用户点击了100次商品在pv这一步只计入1个用户这样算出来的转化率反映的是“有多少独立用户走到了这一步”而不是“有多少次行为走到了这一步”。如果不去重漏斗数据会被高频用户的刷量行为严重污染。我实际跑出来的结果是点击到收藏的转化率大约为5%收藏到加购约30%加购到购买约25%。最关键的信息藏在第一步——从点击到收藏这一步流失了绝大部分用户。这说明大量用户在浏览商品后并没有产生收藏或加购意愿要么是推荐不精准要么是商品详情页缺乏吸引力。答辩时你如果能把这个断点跟推荐策略优化建议关联起来整个项目的业务深度瞬间就立起来了。3.4 用户价值分层RFM模型的本地化改造RFM模型是一种经典的客户价值分析模型它从三个维度衡量用户价值R是最近一次购买时间距离现在有多久F是购买频率M是累计购买金额。问题来了我们的数据集里没有金额字段经典的RFM做不了完整的M值。怎么办我当时的处理方案是对M做替代用“收藏加购次数”作为M的替代指标因为收藏和加购代表用户的购买意向强度。这个替代在逻辑上是成立的——一个经常收藏加购但还没下单的用户其潜在价值可能比一个只买过一次但从不加购的用户更高。这个思路在论文里写清楚了之后答辩老师反而觉得你动了脑子不是生搬硬套模型。实现RFM的关键是每个用户只保留一条打分记录。R值等于分析窗口的最大日期减去用户最后一次购买日期天数越小得分越高F值等于用户购买行为的总次数次数越高得分越高替代M值等于收藏与加购行为的总次数同样越高越好。然后分别用三分位数把三项指标分成高、中、低三档最终组合成8类用户。用户类型RF替代M运营建议高价值用户高高高重点维护提供专属权益潜力用户高低高推送优惠券促进首购新用户高低低加强引导提升留存流失风险低高低召回策略推送新品流失用户低低低暂时搁置大促再激活我跑出来的数据结果是高价值用户只占总用户数的2%左右但这部分用户贡献了全部购买行为里相当高的比例。整体用户金字塔结构非常典型说明平台的用户价值分布极度不平衡运营重心应该放在高价值用户的维护上。3.5 商品偏好与时间维度分析商品维度的分析比较直接但有几个容易忽略的细节需要提醒。热门商品排名不仅要看点击量更要看购买转化率。经常会出现一个点击量很高的爆款商品但它的购买转化率远低于平均水平这种商品很可能是标题党或引流款真实转化效果并不好。所以我把商品的点击排行和购买排行做了对比把“高点击高转化”、“高点击低转化”的差异商品都识别出来作为商品运营的分析结论。时间维度的分析则更有意思。一周七天的活跃度分布能反映用户的周内行为规律工作日用户活跃度相对平稳周末尤其是周日晚间会有明显的活跃高峰。结合时间维度还可以做更深层的交叉分析比如工作时间段用户更喜欢直接购买而晚间用户更多是收藏加购这反映了不同场景下用户决策的差异这些结论都可以写进论文的总结章节。另外商品类目的分析也不能少。类目点击分布用水平柱状图展示最好看按点击量取Top10类目即可。我跑出来的结果是女装类目的点击量一骑绝尘远超其他类目但购买转化率最高的却不是女装而是家居用品类说明女装虽然流量大但竞争激烈用户比价行为明显家居用品的购买决策路径反而更短。这种“流量结构”和“转化结构”的差异正是平台商品运营最值得深挖的地方。4. 可视化呈现与图表细节处理4.1 图表选型与业务解读的配合图表的选型要跟你想表达的业务结论匹配不是随便堆图就算完成任务。我最终的图表清单是每日流量趋势用双折线图、时段活跃分布用柱状图、转化漏斗用横向漏斗图、用户分层用堆叠柱状图或散点图、商品类目Top10用水平柱状图、用户活跃度分布用箱线图。画图有一个很容易犯的错图表的样式不规范。默认的Matplotlib图表在论文里看起来非常业余我做了三处统一调整全局字体设置成SimHei、图表的坐标轴标签和标题字号统一调大、配色方案固定为同一套色系。这些细节在答辩时很拉好感一眼就能看出你认真对待了数据可视化这件事。还有很重要的一点每张图一定要配文字结论而不是光秃秃扔一张图。图表是证据结论是观点论文和答辩PPT里必须做到“一图一结论”。比如你画了时段活跃分布图下面的文字要明确写出“用户在20-22点达到活跃峰值建议将营销活动集中在该时段推送”而不是让老师自己去图表里找结论。4.2 中文字体与样式配置的一次性解决Matplotlib的中文乱码问题十个做数据分析的人有九个都踩过。网上搜到的各种改rcParams的博客抄下来经常还会遇到警告或者不起作用。我在这里给出一个当前版本下实测可用的统一方案直接放在代码开头即可。import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei, Microsoft YaHei, PingFang SC] plt.rcParams[axes.unicode_minus] False第一行指定中文字体第二行确保负号能正常显示。SimHei在Windows系统上基本是标配如果你用的是Mac改成PingFang SC更稳定。Linux服务器环境下需要先安装中文字体或者直接用文泉驿正黑。另外还有个细节是Seaborn画图时会覆盖Matplotlib的rcParams需要在import seaborn之后再次设置上面两行配置才能保证图表正常显示中文。5. 开发中的真实踩坑与排查实录5.1 千万级数据量下Pandas卡死和内存溢出这是我这个项目遇到的第一个大坑。第一次我把完整数据集一亿条直接读进Pandas结果内存占用直接飙到20G以上笔记本风扇狂转最后IDE直接失去响应。那时候我才意识到大数据量处理不能硬碰硬。我的解决思路是抽样加降级。抽样方面完整数据集上做用户维度抽样只取部分活跃用户的全量行为记录几百万条的量级在16G内存笔记本上完全可跑。降级方面在读取CSV时指定dtype把数值字段用int32或int64替代默认的int64行为字段转成category类型内存占用能显著下降。还有一个优化是用Pandas的chunksize参数分块读取对数据做初步过滤后再合并。如果数据量还要大就该上Dask或者PySpark了对于课程设计来说没必要走这么远。答辩时老师如果问“数据量过大怎么处理”你先答抽样策略再答数据类型优化最后补充分布式方案作为扩展思路这个问题的回答就已经完整了。5.2 时间戳转换之后全是1970年Unix时间戳转datetime这个操作最容易踩的坑就是忘了指定单位。pandas的to_datetime默认会把数字当作纳秒精度去解析所以你不传units的话得到的时间会变成1970年附近。另外还有一个坑原始数据里有少数时间戳可能超出正常范围比如等于0或者负值这种情况下转换后是1970-01-01甚至更早的时间。我加了一道过滤逻辑把转换后的时间限定在数据集所属的时间窗口内窗口外的记录直接删除。这样做既保证了数据质量又避免了后续按天聚合时出现一个诡异的1970年柱子。5.3 MySQL写入报错与连接不稳的排查用SQLAlchemy往MySQL批量写入时我遇到过几个问题。第一个是驱动没装全SQLAlchemy默认连MySQL还需要装PyMySQL这个驱动包不装会报ModuleNotFoundError。第二个是字符集问题写入的中文变成问号这是因为建库时没有指定utf8mb4字符集。第三个是连接超时问题当数据量太大、写入时间太长时MySQL会主动断开空闲连接报OperationalError。我的排查习惯是三步走先看报错类型如果跟驱动有关就补包跟字符集有关就删库重建并指定utf8mb4跟连接有关就检查SQLAlchemy的pool_pre_ping参数把它设为True让每次请求前先探测连接是否可用。这块的调试经验写进文档里也是答辩时可以讲的“解决实际工程问题”的能力证明。5.4 聚合计算时结果对不上同样的指标自己手工数跟程序跑出来的结果不一样这个问题很常见。最常见的原因是重复计算和口径不统一。比如计算UV你必须用user_id.nunique()而写成count()就变成了PV。计算转化率时分子分母的去重口径也要一致分子是购买用户数分母是点击用户数两者都必须是“去重后的用户数”否则转化率会虚高。我的调试方法非常朴素先用小数据集手工验证。从全部数据里随机抽1000条手工在Excel里算出每个指标再用同样的数据跑代码两边对比。一旦小数据对上了全量数据的结果基本不会错。这个方法我强烈建议你也试一试能帮你发现不少隐蔽的bug。6. 源码工程结构、文档撰写与交付体会6.1 工程目录怎么组织才算“系统性”答辩评分时老师非常看重代码的工程组织能力。我最后的工程目录是这样的project/ ├── data/ # 存放原始数据与清洗后数据 │ ├── raw/ │ └── cleaned/ ├── scripts/ # 核心代码脚本 │ ├── 01_data_clean.py │ ├── 02_db_import.py │ ├── 03_traffic_analysis.py │ ├── 04_funnel_analysis.py │ ├── 05_rfm_model.py │ └── 06_visualization.py ├── docs/ # 万字设计文档与答辩PPT ├── output/ # 图表输出目录 ├── requirements.txt └── README.md每个脚本文件只承担单一职责通过文件名前缀数字来体现执行顺序。README里写清楚运行环境、安装依赖命令、逐步骤运行说明。有的同学喜欢把所有代码写在一个大文件里说实话运行是没问题但答辩效果会打折扣老师翻代码时很难定位核心逻辑。6.2 万字设计文档的结构、写作要点与答辩现场课程设计通常要求提交一份完整的设计文档毕业设计则要搭配开题报告、中期报告、论文正文和答辩PPT。不管要求多少字数文档底层逻辑是一致的需求背景、系统设计、实现细节、结果分析、总结展望。写作时最忌讳的是堆代码。论文里贴几十行代码的通常都会被批“这不是论文是代码附录”。正确做法是文字描述核心逻辑和选型理由流程图展示处理流程表格整理分析结果代码只在关键实现处引用一小段做解读。所有图表要有标题、有编号、有文字结论。最后讲一下答辩现场。老师对这个题目的追问通常集中在三个地方一是数据从哪里来的、数据质量怎么保证二是每个分析模块的业务含义是什么三是如果数据量再扩大十倍你的方案怎么优化。这三个问题分别对应我在5.1、3.x和5.1里的回答提前准备一遍现场基本不会冷场。另外演示时建议提前把图和数据库截图准备好现场运行容易因为环境问题翻车有静态结果兜底会稳很多。我当时答辩时旁边一组同学的代码现场运行直接报错我这边因为提前准备了输出图表集整个过程非常顺利。这个系统做完之后我的一个很深的体会是绝大多数课程设计和毕业设计考察的并不是你用了多高深的技术而是你能不能把一件完整的事情从头到尾做扎实。电商用户行为分析恰好是那种“看起来大家都做过、但真正把业务逻辑讲清楚的人不多”的题目。如果你正在做这个题不要只盯着代码跑通多想想你的每一张图在回答什么业务问题、每一个分析结论能支撑什么运营决策。把这条线理顺了你的代码、数据库、文档就都有了真正的灵魂。

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

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

免费获取报价 →
↑