
简介面向大数据分析与电商毕业设计场景这份可运行源码以淘宝用户行为数据为对象覆盖数据导入、清洗、异常值处理、Hive统计分析及可视化全流程。项目时间跨度2017年11月25日至12月3日数据规模超1亿条重点包括用户流量与购物情况、行为转化率、行为习惯分析、基于RFM模型的高价值用户识别以及商品维度分析。压缩包共20个文件、约16.37MB核心为5个Python脚本与5个JSON结果文件配套HTML可视化页面、CSV数据样本、Shell部署脚本及多份Markdown说明文档结构清晰便于直接运行或二次修改。源码附带论文级指导文档可帮助理解分析思路与建模细节适合作为毕业设计参考或大数据分析入门练习。目前已有85人学习具备一定参考价值。 做电商数据分析这行最怕什么不是没有数据而是数据拿到手里不知道从哪下手。我经常收到类似留言老板丢了一份用户行为日志让分析自己却只会跑个describe()漏斗、分层、留存这些概念看着都会一写代码就懵。所以这次我直接开源了一个可运行的电商用户行为分析项目把数据清洗、流量分析、漏斗转化、RFM分层、留存分析整套流程串起来。项目基于 Python 实现代码注释完整替换成自己的数据就能跑适合刚入行的数据分析师、运营同学也适合想练手 Python 的在校学生。这套分析的思路不复杂拿到用户行为日志后先做数据清洗再按用户和商品维度拆解行为路径最后落到转化率、复购率、RFM分层这些业务指标上。下面我把项目的整体设计、核心源码逻辑、实操过程和踩过的坑一次性讲清楚。1. 项目整体设计与技术选型1.1 为什么选 Python 做用户行为分析市面上做行为分析的工具很多商业产品能直接出报表企业自研一般走埋点平台。但作为个人项目或小团队内部的轻量分析Python 一直是最稳的选择。原因很实在一是 pandas 处理表格数据几乎是无脑快几千万行 CSV 读进来也就是几秒到几十秒的事二是 Matplotlib 和 Seaborn 出图表方便漏斗、分布、热力图改几行参数就能调整三是整个分析链路都在同一个脚本里清洗、聚合、建模、可视化连贯执行不像用 Excel 那样每个步骤都要手动点一次。这个项目我选择了 pandas 2.x Matplotlib 3.x Seaborn 0.13 组合。pandas 负责数据处理Seaborn 负责好看一点的统计图Matplotlib 做底层微调。可视化部分没有上 Plotly因为大多数公司内部报告还是以静态图为主交互图实际用到的频率并不高而且静态图对机器性能要求低跑起来不卡。1.2 数据源选型用公开数据集复现真实场景项目默认使用的数据集是阿里天池的 UserBehavior 数据集这个数据集在电商分析领域很常用包含用户 ID、商品 ID、商品类目 ID、行为类型和时间戳五个字段。字段结构如下字段名含义示例user_id用户ID10001082item_id商品ID233137168category_id商品类目ID475610884behavior_type行为类型pv / cart / fav / buytimestamp行为时间戳1511544070behavior_type 是核心字段pv 代表点击、cart 代表加购、fav 代表收藏、buy 代表购买。基于这些行为可以还原用户的完整决策链路看到商品、收藏或加购、最终下单购买。如果你没有天池的账号也没关系UCI 的 Online Retail 数据集也可以做类似分析只是字段结构需要适配。我项目里把数据读取封装成了一个独立函数换数据源时只需要修改加载部分分析逻辑不用动。2. 项目结构与数据预处理2.1 源码目录设计项目结构我尽量保持简单清晰拿到手就能看懂扩展也不费劲ecommerce_user_behavior/ ├── data/ │ ├── UserBehavior.csv │ ├── preprocess.py │ └── sample_data.py ├── analysis/ │ ├── traffic_analysis.py │ ├── funnel_analysis.py │ ├── rfm_analysis.py │ └── retention_analysis.py ├── output/ │ ├── charts/ │ └── result_tables/ ├── main.py └── requirements.txtdata 目录放原始数据和预处理脚本analysis 目录放四个分析模块output 目录存输出图表和结果表main.py 作为总入口。这样的好处是每个模块职责单一想单独看某一项指标时直接运行对应的脚本不需要跑全流程。2.2 数据清洗的四个关键点用户行为日志的脏数据比想象中多这里有几个必须处理的步骤第一步是时间戳转换。UserBehavior 数据集里的 timestamp 是秒级 Unix 时间戳直接读进来是数字需要转换成日期格式才能按天做聚合。这里有个坑有的数据集时间戳是毫秒级直接用pd.to_datetime(ts, units)得到的结果会变成 1970 年需要先判断单位是秒还是毫秒。第二步是重复值处理。用户连续点击同一个商品的 pv 记录严格来说应该去重但实际业务里如果连续点击可能代表用户犹豫或者页面反复加载是否去重取决于分析口径。我在项目里提供了一个参数drop_duplicate控制默认保留全部记录。第三步是异常值过滤。比如浏览时间非常短的记录1秒通常是爬虫或误触产生时间戳超出统计周期的记录也可能是测试数据。项目中过滤掉了明显超出数据集时间范围的记录。第四步是空值处理。UserBehavior 数据集的字段基本没有空值但如果是自己公司导出的埋点日志user_id 或 item_id 经常有 null这类记录直接丢弃即可不要填充因为填充了反而制造假数据。预处理核心代码如下import pandas as pd def load_user_behavior(file_path: str) - pd.DataFrame: df pd.read_csv( file_path, names[user_id, item_id, category_id, behavior_type, timestamp] ) df[timestamp] pd.to_datetime(df[timestamp], units) df[date] df[timestamp].dt.date df df.dropna(subset[user_id, item_id, behavior_type]) df df[df[behavior_type].isin([pv, cart, fav, buy])] return df3. 核心分析模块从流量到用户价值分层3.1 流量与商品维度分析第一块基础分析是流量概览。计算 PV总点击量、UV独立访客数、人均点击量、日活跃用户数等基础指标判断整体流量规模和健康度。这里有一个容易被忽视的点PV/UV 比值。如果这个数字在 3 以内说明大多数用户点到第二层就离开了如果超过 10一方面可能说明内容吸引力强另一方面也可能是爬虫或刷量在干扰数据。结合会话时长和跳出率一起看才能判断流量质量。商品维度的分析同样重要。项目里统计了被浏览次数最多的前 20 款商品、被购买最多的前 20 款商品并且计算了每个商品的“浏览-购买转化率”。这个指标直接反映商品本身的吸引力与价格匹配度转化率特别低的商品可以考虑调整详情页或定价策略。流量分析代码如下daily_stats df.groupby(date).agg( pv(behavior_type, lambda x: (x pv).sum()), uv(user_id, nunique), buy_cnt(behavior_type, lambda x: (x buy).sum()) ) daily_stats[pv_uv_ratio] daily_stats[pv] / daily_stats[uv]3.2 漏斗转化分析找到用户流失的关键环节漏斗分析是电商行为分析里最有业务价值的部分。标准电商漏斗是浏览pv→ 收藏fav→ 加购cart→ 支付buy。很多新手做漏斗会直接把四种行为的用户数算出来然后算相邻环节的转化率。这么做有一个严重的逻辑问题收藏和加购两种行为并不是严格递进的。有的用户可能不收藏直接加购有的用户收藏了也没加购。严格漏斗要求每一步操作都发生在下一步之前并且是针对同一件商品。我项目里的漏斗实现方式是按用户和商品维度对齐先判断每个用户对每个商品的路径顺序再做整体漏斗统计。核心逻辑如下def build_funnel(df: pd.DataFrame) - pd.DataFrame: behavior_rank {pv: 1, fav: 2, cart: 3, buy: 4} df[rank] df[behavior_type].map(behavior_rank) # 按用户商品提取行为链路判断是否按顺序经历各环节 user_item_path df.sort_values(timestamp).groupby([user_id, item_id])[behavior_type].agg(list) stats { pv: 0, fav: 0, cart: 0, buy: 0 } for path in user_item_path: # 按时间有序且不重复的行为集合 seq [] for act in path: if behavior_rank[act] not in [behavior_rank[s] for s in seq]: seq.append(act) if pv in seq: stats[pv] 1 if any(behavior_rank[a] behavior_rank[fav] for a in seq): stats[fav] 1 # 同理处理 cart、buy return pd.DataFrame([stats])实际上跑全量几百万行数据时这个逐行循环会非常慢。我在实际项目中做了优化先用groupby聚合出每个用户商品的有序行为序列再用自定义函数向量化判断。完整代码在开源项目的 funnel_analysis.py 里这里展示的是理解逻辑的核心版本。从漏斗数据能直接看出问题环节。大部分电商项目里最大的流失发生在 pv 到 cart 之间通常是因为价格不透明、运费过高或评价不佳如果 pv 到 cart 的转化率正常但 cart 到 buy 很低一般是支付流程复杂或用户还在比价。3.3 RFM 用户分层把用户分成可运营的群体RFM 是用户价值分析的经典模型RRecency最近一次消费时间、FFrequency消费频率、MMonetary消费金额。通过三个维度的综合打分把用户划分为重要价值客户、重要召回客户、普通客户等群体。由于 UserBehavior 数据集没有消费金额字段我在源码里用购买次数近似替代 M 值并在注释中做了说明。如果你有自己的订单表可以很方便地替换成真实金额。RFM 的核心实现步骤def rfm_analysis(order_df: pd.DataFrame, ref_date) - pd.DataFrame: rfm order_df.groupby(user_id).agg( recency(date, lambda x: (ref_date - x.max()).days), frequency(behavior_type, count), monetary(amount, sum) ) # 用四分位数给每个维度打分 rfm[R_score] pd.qcut(rfm[recency], 4, labels[4, 3, 2, 1]) rfm[F_score] pd.qcut(rfm[frequency].rank(methodfirst), 4, labels[1, 2, 3, 4]) rfm[M_score] pd.qcut(rfm[monetary].rank(methodfirst), 4, labels[1, 2, 3, 4]) rfm[RFM_score] rfm[R_score].astype(int) rfm[F_score].astype(int) rfm[M_score].astype(int) return rfm分层结果显示价值最高的 20% 用户通常贡献了 60% 以上的销量这就是电商里典型的二八法则。RFM 分层最大的价值在于运营侧可以针对性制定策略高价值用户做会员权益维护高频率但低金额的用户做交叉销售高金额但低频的用户做召回。3.4 用户留存分析留存分析是衡量用户粘性和产品健康度的核心指标。第七日留存率次日/3日/7日/30日留存是电商产品最常用的观察维度。用户留存分析需要先把用户首次行为日期和后续活跃日期做匹配计算每个用户在第 N 天是否再次活跃。具体实现def retention_analysis(df: pd.DataFrame) - pd.DataFrame: first_active df.groupby(user_id)[date].min().rename(first_date) df df.merge(first_active, onuser_id) df[day_diff] (df[date] - df[first_date]).dt.days retention df.pivot_table(indexfirst_date, columnsday_diff, valuesuser_id, aggfuncnunique) # 按天计算留存率 retention_rate retention.div(retention[0], axis0) return retention_rate留存在电商场景下和内容产品不一样用户不一定要每天打开所以看 7 日留存比看次日留存更有业务意义。实际操作中我建议把留存率按新用户和回访用户分开观察新用户的留存数据更真实地反映产品的首次体验质量。4. main.py 全流程编排与可视化输出4.1 总入口设计main.py 的设计目的是让整个分析流程可以一键跑通。模块之间通过函数调用衔接不依赖全局变量每个函数接收 DataFrame 参数并返回结果方便单独调试。from analysis.traffic_analysis import traffic_analysis from analysis.funnel_analysis import funnel_analysis from analysis.rfm_analysis import rfm_analysis from analysis.retention_analysis import retention_analysis from data.preprocess import load_user_behavior def main(): df load_user_behavior(data/UserBehavior.csv) traffic_stats traffic_analysis(df) traffic_stats.to_csv(output/result_tables/traffic_stats.csv) funnel funnel_analysis(df) funnel.to_csv(output/result_tables/funnel.csv) order_df df[df[behavior_type] buy].copy() order_df[amount] 1 # 无金额字段时用购买次数替代 rfm rfm_analysis(order_df, ref_datedf[date].max()) rfm.to_csv(output/result_tables/rfm_result.csv) retention retention_analysis(df) retention.to_csv(output/result_tables/retention.csv) if __name__ __main__: main()所有输出统一写到 output 目录图和表分开存放复盘的时候直接打开文件夹就能看到所有产物。4.2 图表输出细节可视化部分我做了模板化的函数封装不管哪个分析模块调用图表的风格保持一致。以漏斗图为例Matplotlib 本身没有直接的漏斗图类型可以用条形图模拟关键是横向条形图加上百分比标签import matplotlib.pyplot as plt def plot_funnel(stage_names, stage_values): fig, ax plt.subplots(figsize(10, 6)) y_pos range(len(stage_names)) bars ax.barh(y_pos, stage_values, color[#4C72B0, #55A868, #C44E52, #8172B3]) for i, (bar, val) in enumerate(zip(bars, stage_values)): if i 0: label f{val} (100%) else: rate val / stage_values[0] * 100 label f{val} ({rate:.1f}%) ax.text(bar.get_width() 2, bar.get_y() bar.get_height()/2, label, vacenter, fontsize11) ax.set_yticks(list(y_pos)) ax.set_yticklabels(stage_names) ax.invert_yaxis() ax.set_xlabel(用户数) plt.tight_layout() plt.savefig(output/charts/funnel.png, dpi150) plt.show()这段代码有两点值得注意一是ax.invert_yaxis()让漏斗从浏览到购买呈从上到下的顺序二是标签中显示每个环节占总体浏览用户的比例这个比例才是业务方最关心的一级转化率。5. 常见问题与排查技巧5.1 数据量太大pandas 处理卡顿怎么办UserBehavior 数据集全量约一亿条记录个人电脑直接读全量数据大概率内存溢出。我实际测试过几种方案最有效的是按天切片先读取一天或一周的数据做分析这样既能跑通逻辑也不影响业务结论的准确性。如果一定要全量处理建议在读 CSV 时指定dtype参数把 user_id 和 item_id 都指定为np.int32比默认的 int64 节省一半内存import numpy as np df pd.read_csv( data/UserBehavior.csv, names[user_id, item_id, category_id, behavior_type, timestamp], dtype{ user_id: np.int32, item_id: np.int32, category_id: np.int32 } )5.2 时间戳分析结果全是 1970 年这是最经典的坑。看到 1970 年就说明时间戳单位不对。秒级时间戳用units毫秒级时间戳用unitms。判断方法很简单打印一行原始时间戳如果是 10 位数字就是秒13 位就是毫秒。5.3 漏斗数据出现“收藏人数大于点击人数”出现这类异常最可能是数据中同一个用户对不同商品产生了不同行为漏斗统计时没有按用户商品维度对齐。比如用户 A 浏览了商品 X但收藏和购买了商品 Y如果直接按行为类型聚合就会放大漏斗每一层的规模。解决方法是按 user_id item_id 分组后再判断各行为是否按顺序发生。5.4 完整运行环境配置项目根目录的 requirements.txt 内容pandas2.0.0 matplotlib3.7.0 seaborn0.12.2 numpy1.24.0用pip install -r requirements.txt安装依赖。建议 Python 3.9 以上版本pandas 2.x 在某些旧版本 Python 上会报兼容错误。6. 从分析结果到业务动作代码跑通只是第一步真正的价值在于把数字变成业务动作。以我实际跑出来的结果为例某天的数据漏斗显示浏览到收藏的转化率只有 3%明显低于其他电商平台 5%-8% 的常见水平。进一步拆解发现收藏行为的入口在详情页底部用户需要滑动很长的商品介绍才能看到收藏按钮这对于高客单价商品来说等于把一批精准用户挡在了门外。这种结论没有办法从单纯的指标计算里得到必须回到业务场景去理解数据背后的含义。这也是我对所有用这个项目的人最想强调的一点分析代码只是工具数据背后的业务语境才是决策的依据。如果你拿到这套源码建议先不要追求把所有分析模块都跑完先把单个模块吃透理解每一步清洗和聚合背后在解决什么问题。然后换一份自己的数据源从这个项目的固定分析框架出发试着增加一个自己关心的维度比如不同渠道用户的转化差异或者不同品类商品的行为路径对比。当你改代码改到第五六个版本的时候这套分析体系基本就长在你身上了。本文还有配套的精品资源点击获取