每年到毕业设计季节,总有不少同学拿着“短视频平台用户浏览行为简单数据分析系统”这类题目来找我讨论。这个题目乍一看很“普通”,甚至带点“烂大街”的味道,但仔细拆开来看,它其实是非常典型的“数据链路完整型”选题——要数据有数据,要分析有分析,要展示有展示,要论文有论文。如果你正在做这个题目,或者准备拿它去开题,这篇文章值得你花十分钟读完。我会按我自己带项目的思路,把整个系统从需求拆解、数据准备、功能实现到论文写作、答辩避坑全部串一遍,尽量做到你照着走就能把东西完整交出来。
这个系统解决的核心问题是什么呢?一句话说清楚:针对短视频平台上“用户看了什么、点了什么、滑动到哪个位置、停留了多久、是否完播、是否互动”这一类浏览行为数据,进行采集、清洗、统计、可视化,并从中发现用户的观看规律和兴趣偏好,最终形成一套可解释、可复现的分析结果。适合的人群包括:准备做毕业设计的本科生、需要交一个“成体系项目”的求职者,以及刚接触数据分析想练手的新人。内容不会去追逐炫酷的深度学习或实时计算,核心落在“简单、完整、可答辩”这六个字上。
1. 先把这个题目的真实需求拆清楚
很多人拿到题目第一反应就是“我先把爬虫写了,去爬真实平台的用户数据”。这个思路我能理解,但实际操作里基本行不通,而且也没必要。
1.1 题目本质:一条从数据到洞察再到论文的完整链路
拆开题目里的关键词,核心是这几个:短视频平台、用户浏览行为、数据分析系统、毕业设计(含论文)。它不要求你做推荐系统,不要求你做实时流量监控,甚至不要求你的算法有多深。它考察的是你能否完成一条完整的“数据链路”:业务理解(用户有哪些行为)→ 数据获取(模拟或采集)→ 数据预处理(清洗、去重、补缺)→ 指标计算(浏览量、完播率、互动率等)→ 可视化展示(图表/看板)→ 结论输出(论文中的分析章节)。这其实就是企业里初级数据分析师日常工作的缩小版,也是答辩时老师最关注的主线。
所以,第一件事不要急着写代码,而是先把这条链路画清楚。我通常会让同学在开题报告里先写一页“系统逻辑图”:以“原始行为日志 → ETL清洗 → 指标库 → 可视化与结论”为骨架,再在每一层下面标注具体技术点。画清楚之后,你的题目就已经完成一半了,因为之后所有代码都是往这个框架里填东西。
1.2 为什么选模拟数据,而不是对接真实平台数据
我特别想在这里统一说一个观点:毕业设计里用程序生成的模拟数据,不但不丢人,反而是更稳妥、更专业的选择。原因有三个。第一,真实短视频平台的用户行为数据涉及用户隐私、商业机密和平台合规问题,直接在毕设里使用真实脱敏数据很难获取,也不适合公开写进论文。第二,真实数据包含大量噪声和复杂业务语义,比如推荐算法干扰、信息流刷新的动态逻辑,对于初学者来说反而更容易迷惑。第三,模拟数据是你自己设计的,每一个字段的含义你都清清楚楚,指标算出来之后你可以直接判断“对还是不对”,这种可控感对调试和答辩都极其重要。
当然,模拟数据不是瞎造。它必须符合短视频平台的业务规律:少量头部视频占据大量播放量、用户观看时长近似长尾分布、晚间和午间活跃度高、不同年龄段的偏好有差异化。这些规律在论文里写出来,本身就是有说服力的“数据质量验证”环节。
1.3 技术选型:解决好“够用”“好答辩”“能写出东西”三个问题
我见过太多同学一上来就想用最复杂的技术栈:Hadoop、Spark、Kafka、Flink……结果环境配了一个星期,最后连书上的 WordCount 都跑不顺。这个题目的定位是“简单数据分析系统”,技术选型应该以把链路跑通为第一优先。
我建议的基础方案是:
| 环节 | 推荐技术 | 理由 |
|---|---|---|
| 数据生成 | Python + Faker/random | 灵活可控,能构造出带业务规律的日志 |
| 数据存储 | SQLite | 单文件数据库,够轻量,论文里也好截图展示表结构 |
| 数据处理 | Python + Pandas | 清洗、分组、聚合、透视表一条龙 |
| 可视化 | Matplotlib + Pyecharts | Matplotlib 画论文用静态图,Pyecharts 做答辩演示用的交互图 |
| 系统组织 | 模块化脚本 + main 入口 | 体现“系统”,避免用一个 Jupyter Notebook 糊完所有内容 |
这套选型的核心逻辑是:本科毕设阶段,稳定可复现比分布式集群重要得多。你答辩时能现场跑一遍数据生成和指标输出,比放几张渲染好的项目截图有说服力得多。如果你还有精力,可以在 Web 展示上用 Flask 包一个简单页面,把图表嵌入进去,但这不是必须项,属于锦上添花。
2. 动手之前,先把业务指标定义清楚
这一步最容易被忽略,但恰恰是决定论文质量的关键。代码写得再漂亮,如果没有清晰的业务口径,答辩时老师一句“你这个点击率是按什么分母算的?”就能把你问住。
2.1 把浏览行为按“用户行为漏斗”拆开来看
短视频平台的浏览行为,远不止“播放”这一个动作。你可以把它理解为一条完整的漏斗路径:曝光 → 点击进入 → 开始播放 → 播放过程中跳走或滑走 → 完播 → 互动(点赞/评论/分享)。每一步都对应着不同的产品含义。
拿曝光来说,它代表推荐引擎把视频推给了用户,但用户没点开;点击进入代表用户对封面或标题感兴趣;开始播放代表真正产生了消费;完播是一个强信号,代表内容质量足够好;互动则代表用户的情感卷入。把这些行为串成漏斗之后,你自然就能定义出“曝光→播放转化率”“点击→播放转化率”“完播率”“跳出率”等核心指标。指标口径统一了,后面的代码就是计算问题,不再是思考问题。
2.2 指标字典:论文里不会替你写,你得自己定义
让论文显得专业的技巧之一,就是专门做一节“指标定义”,把系统里用到的所有指标列成一张表。一个完整的指标定义至少包含:指标名称、计算口径、业务意义、数据来源字段。这份字典既是开发阶段的规范,也是论文里“系统需求分析”章节的重要素材。
我常用的指标清单大概是这样:
| 指标名 | 公式/口径 | 业务含义 |
|---|---|---|
| 曝光量 | 行为类型为 exposure 的日志条数 | 内容触达人群规模 |
| 点击率 CTR | 点击次数 / 曝光次数 | 封面与标题吸引力 |
| 播放转化率 | 开始播放次数 / 点击次数 | 落地页引导效果 |
| 完播率 | 完播行为数 / 开始播放数 | 内容留人能力 |
| 平均观看时长 | 总观看时长 / 播放次数 | 内容消费深度 |
| 跳出率 | 播放后 5 秒内滑走次数 / 播放次数 | 前 5 秒内容质量 |
| 互动率 | (点赞+评论+分享)/ 播放次数 | 用户激活程度 |
| 人均观看条数 | 播放次数 / 活跃用户数 | 用户粘性 |
这张表做出来之后,你后续的每个分析图基本都是在算这些指标在不同维度下的分布。答辩时如果老师问“你做了什么分析”,你就把这张表往上一指,思路立刻清晰。
2.3 模拟数据也要讲“业务感”:分布、量级、字段设计
模拟数据不是简单地 random 一把,而是要带出“业务感”。打个比方,真实短视频平台里热门视频的播放量动辄几十万上百万,但绝大多数视频只有几百播放,这就是典型的幂律分布。如果你用均匀分布随机生成播放量,老师一眼就能看出数据是假的,更重要的是,你后续分析出的结论会很奇怪,无法自圆其说。
我在设计模拟数据时,一般生成三张表:用户表、视频表、行为日志表。用户表包含 user_id、年龄、性别、地区、注册时间;视频表包含 video_id、类别、时长、发布时间;行为日志表则包含 log_id、user_id、video_id、行为类型、行为时间、停留时长、设备类型、网络环境。行为类型我设定为五类左右:exposure、click、start、complete、interact,其中 interact 可以再细分点赞、评论、分享。日志条数通常控制在 10 万到 50 万之间,既能保证统计结果稳定,又不会让本地脚本跑太久。
时间分布上,我一般设置“晚上 19-23 点为活跃高峰,午间 12-13 点为小高峰”,工作日和周末也有差异。停留时长按指数分布生成,大部分用户只看几秒或十几秒,少数视频能让用户看满全程。
3. 从零实现一个可运行的浏览行为分析系统
到这里,我们终于可以进入代码了。下面这套实现是我自己整理过的,结构上尽量贴合“数据层-分析层-展示层”的系统架构,你可以直接参考,也可以改成自己习惯的写法。
3.1 数据层:写一个可复现的行为日志生成器
我建议把数据生成独立成一个脚本,比如 data_generator.py。好处是论文里可以明明白白写“本系统通过脚本生成实验数据,支持参数调节”,答辩时现场跑一遍也不尴尬,因为你调参数就能改变数据规模。
生成模拟数据时,先建用户和视频,再根据行为漏斗去生成行为日志。核心代码如下:
import pandas as pd import numpy as np from datetime import datetime, timedelta np.random.seed(42) # 生成 2000 个用户 users = pd.DataFrame({ "user_id": range(1, 2001), "age": np.random.randint(13, 60, 2000), "gender": np.random.choice(["男", "女"], 2000, p=[0.5, 0.5]), "city_level": np.random.choice(["一线", "新一线", "二线", "三线及以下"], 2000, p=[0.15, 0.2, 0.25, 0.4]), "reg_days": np.random.randint(1, 365, 2000) }) # 生成 500 个视频 videos = pd.DataFrame({ "video_id": range(1, 501), "category": np.random.choice(["美食", "旅行", "游戏", "知识", "影视", "音乐"], 500), "duration_sec": np.random.randint(15, 300, 500), "author_level": np.random.choice(["尾部", "腰部", "头部"], 500, p=[0.6, 0.3, 0.1]) })这里有一个细节:给用户加“城市等级”和“注册天数”并不是随随便便设计的,它们是为了后面分析用户分层用的。有了这两个字段,你论文里就可以写“分析不同城市等级用户的观看时长差异”“新老用户的完播率对比”,分析维度一下子就丰富起来。
接着生成行为日志。漏斗概率我通常设计为:曝光后点击概率 30%,点击后进入播放 80%,播放后完播 25%,完播后互动 35%。另外,播放过程中有 40% 的概率发生“滑走”行为,滑走时间随机在 5-60 秒分布。你可以把这些概率做成全局变量,方便调整。
def gen_logs(users, videos, num_users=500): logs = [] for _ in range(num_users): user = users.sample(1).iloc[0] video = videos.sample(1).iloc[0] base_time = datetime(2024, 1, 1) + timedelta( minutes=np.random.randint(0, 60 * 24 * 30) ) # 曝光 logs.append((user["user_id"], video["video_id"], "exposure", base_time, 0)) # 点击 if np.random.rand() < 0.3: logs.append((user["user_id"], video["video_id"], "click", base_time + timedelta(seconds=2), 0)) # 开始播放 if np.random.rand() < 0.8: ... return logs代码我在这里只给一个骨架,因为完整版太长。但思路你已经懂了:每一个行为是否发生,都由上一个行为的结果决定,这就是漏斗模型在代码里的落地方式。生成完之后转换为 DataFrame 并保存为 CSV,再写入 SQLite 数据库。写入数据库用 Pandas 的to_sql方法即可。
3.2 分析层:ETL 与漏斗计算怎么做才算“系统”
日志生成完之后,第一步是清洗。我见过不少同学拿到数据就直接 groupby 画图,结果画出来的图错误百出,原因大多出在数据没洗干净。清洗至少要处理四件事:去重、缺失值、时间格式统一、异常值处理。
行为日志的去重逻辑确实不是简单的“所有字段完全重复才去重”,而是要看业务语义。同一个用户对同一个视频,点击和播放可能各出现一次,这是正常现象,不能删。真正的重复是指同一用户在同一秒对同一视频同一动作出现多次,这种一般是程序生成或日志重复上报导致的,才应该去掉。时间字段要统一成datetime类型,否则做小时维度、日期维度聚合时会乱。异常值方面,最常见的坑是停留时长超过视频时长,比如一个 30 秒的视频记录了 120 秒的观看时长,这明显不合理,应该做截断处理。
清洗完之后,就进入指标计算。用 Pandas 做漏斗分析非常直接:
import pandas as pd df = pd.read_sql_query("SELECT * FROM behavior_log", engine) # 各行为的去重用户数 funnel = df.groupby("action").agg( uv=("user_id", "nunique"), pv=("log_id", "count") ).reset_index()这里的uv是去重用户数,pv是总行为次数。论文里说“某功能的使用人数”用 uv,说“被使用的总次数”用 pv。这两个口径千万不要搞混,答辩时经常被问。算完各行为的总数后,转化率就很好求了:后一步的 uv 除以前一步的 uv。
我还建议在系统里加一个“时间窗口分析”模块:按小时分组,统计各小时曝光量和完播率,画出 24 小时趋势曲线。这个模块能明显提升系统的丰满度,而且实现成本很低,一句groupby(df['hour'])就能搞定。
3.3 用户偏好分析:找出谁在看什么
用户画像分析是另一个答辩加分点。核心做法就是做交叉维度统计,比如“不同年龄段 × 视频类别”的播放量矩阵。用 Pandas 的透视表可以一步实现:
# 构造年龄分组 df["age_group"] = pd.cut( df["age"], bins=[0, 18, 25, 35, 50, 100], labels=["0-18", "19-25", "26-35", "36-50", "50+"] ) # 交叉统计播放量 pivot = pd.pivot_table( df[df["action"] == "start"], index="age_group", columns="category", values="user_id", aggfunc="count", fill_value=0 )拿到这个透视表之后,你可以做两个层面的结论:一是找出每个年龄段的头部内容品类,比如“19-25 岁用户更偏好音乐和游戏类视频”;二是计算每个品类的用户年龄中位数,发现不同品类受众的年龄差异。这些结论是论文“实验结果分析”章节最核心的素材,也是答辩时最有话说的部分。
代码逻辑本身不难,难在你能不能让结论有依据。我在做这类分析时,通常都会在结论里带上数据支撑,比如“美食类视频完播率高于平台平均 12 个百分点,说明当前样本中美食内容质量整体较好”。离开数据支撑下结论是论文写作的大忌,养成这个习惯对你未来写任何报告都有帮助。
3.4 可视化:让论文图表好看又好讲
可视化方面我习惯用两套工具配合:Matplotlib 出论文用的静态图,Pyecharts 出答辩演示用的交互图。
Matplotlib 画柱状图时,有一个高频踩坑点必须提醒你们:中文字体要显式配置,否则图里全是方块。需要在绘图脚本开头设置字体:
import matplotlib.pyplot as plt plt.rcParams["font.sans-serif"] = ["Microsoft YaHei", "SimHei"] plt.rcParams["axes.unicode_minus"] = False如果是在 Linux 服务器上跑,系统里没有微软雅黑,还要先安装中文字体包。建议你本地把图保存成 PNG,dpi 设置 300,直接插入论文,别用 Word 重新截图,否则清晰度会变差。
Pyecharts 在毕业设计里特别受欢迎,因为它能生成 HTML 交互动图,像漏斗图、桑基图、时间轴折线图都可以直接用现成组件,效果很“高级”。我这里不展开完整代码了,只说一个关键点:Pyecharts 从 1.x 之后,不同小版本的用法差别不小,安装时最好固定一个版本,并把版本号在论文里写明,方便复现。如果画图时发现组件导入报错,大概率是版本兼容问题,用pip show pyecharts查看版本后再去搜对应 API 更靠谱。
3.5 一个可选的加分功能:简单内容推荐规则
真正把系统从“统计”推向“应用”的,是一个简单的推荐模块。我建议可以做这样一个东西:对每个用户,找出他观看次数最多的前三个品类,在这些品类里挑出他没看过但热度最高的视频推荐给他。这个逻辑叫“基于品类偏好的规则推荐”,相比协同过滤来说简单得多,但在毕设这个体量下完全够用,而且它的代码量不大。
def recommend(user_id, df, top_k=5): # 用户偏好品类 pref = (df[(df["user_id"] == user_id) & (df["action"] == "start")] .groupby("category")["video_id"].count() .nlargest(3).index.tolist()) # 候选池:偏好品类 + 未观看 watched = set(df[df["user_id"] == user_id]["video_id"]) candidates = df[df["category"].isin(pref)] candidates = candidates[~candidates["video_id"].isin(watched)] # 按热度排序 hot = candidates.groupby("video_id").size().nlargest(top_k).index.tolist() return hot答辩时老师如果问“你的分析系统除了看数据还能干什么”,你把推荐模块演示一下,问题的难度就降下去了。当然,这里和真实平台上用的重排算法有很大差距,论文里要诚实写清“本模块仅用于验证数据分析结果的应用价值,后续可替换为更复杂的召回排序模型”,这样既诚实又显得你有方向感。
4. 论文写作与答辩经验,能让你少走三个月弯路
代码写完了,毕业设计也就完成了一半,剩下那一半是论文。这部分我按自己的经验给你几个实在的建议。
4.1 论文结构不是抄模板,是按“系统链路”展开
很多学校的论文模板长得差不多:摘要、绪论、需求分析、系统设计、系统实现、测试调试、总结展望。你可以按这个框架走,但内容骨架一定要按你自己的系统链路来对应。我建议你按下面这张表来对应:
| 论文章节 | 对应系统内容 |
|---|---|
| 绪论 | 短视频行业背景、用户行为分析的意义、国内外相关综述 |
| 需求分析 | 功能需求(数据生成、清洗、分析、可视化)、非功能需求(性能、易用性) |
| 系统设计 | 总体架构、数据库表结构设计、核心模块划分 |
| 系统实现 | 数据生成实现、ETL实现、指标计算实现、可视化实现、推荐模块实现 |
| 系统测试 | 对清洗逻辑做用例测试、对指标计算做手算验证、对系统稳定性做多轮运行测试 |
| 总结展望 | 成果总结,诚实写明不足,提出实时计算、深度学习、更大数据量改进方向 |
写论文最忌讳的是把代码直接贴到 Word 里,贴得密密麻麻,老师根本不想看。你应该贴的是“核心代码片段 + 结果图 + 一两句话说明这段代码做了什么”。做到“图 > 表 > 代码”的信息层次,论文的可读性会好很多,通过率也能高不少。
4.2 图表与数据呈现:老师最在意什么
我帮不少同学审过论文,发现初稿最容易出现的问题是图表的“说明文字”写得太弱。你辛辛苦苦画了一张柱状图,结果下面只写一句“不同年龄段的播放量对比”,这基本等于白画。好的图表说明应该包含三层内容:图里是什么(总体描述)→ 哪部分最突出(局部对比)→ 这说明什么业务规律(结论解释)。比如“由图 4-3 可以看出,19-25 岁用户的播放量占全部播放量的 36.8%,显著高于其他年龄段,说明该平台的用户群体呈明显的年轻化特征”。像这样写,每张图都在替你说话,而不是仅停留在展示的层面。
图表的规范问题也要注意:每一章里图要按“图 3-1、图 3-2”连续编号,表按“表 3-1、表 3-2”编号,图题在图的下面,表题在表的上面。这些格式细节虽然琐碎,但对论文的观感提升非常直接。
4.3 常见技术坑与排查方法速查表
这部分算是我最想输出给你的经验。整理了一张速查表,都是我在实际项目里被问过、也帮学生排查过的问题:
| 现象 | 常见原因 | 排查办法 |
|---|---|---|
| 画出的图全是方块 | 中文字体未设置 | 在绘图脚本头部配置plt.rcParams["font.sans-serif"] |
| Pandas 读 CSV 后日期列变成字符串 | 没做类型转换 | pd.to_datetime(df["ts"]) |
| groupby 后中文表头乱码 | 输出终端的编码问题 | CSV 导出时指定encoding="utf-8-sig" |
| 漏斗转化率超过 100% | 分母口径拿错 | 检查是否混用了 pv 和 uv,必须同一个口径相除 |
| SQLite 写入速度慢 | 循环逐条 insert | 用pd.to_sql批量写入 |
| Pyecharts 图表空白 | 版本 API 不匹配 | 固定 pyecharts 版本,按对应版本文档写 |
| 模拟数据跑出来的结论不合常理 | 随机概率设置不真实 | 调整漏斗概率,让行为发生率符合常识 |
排查问题的核心思路是“分层缩小范围”:先判断是哪一层出的问题,数据层就用最简单的 print 去看数据结构,分析层就用小样本手动算一遍,可视化层就先画最小数据集。我不建议一上来就断点调试,先看最明显的输入输出,往往一瞬间就能定位。
4.4 答辩高频问题,该怎么回答
答辩本质上是一次“把你的项目讲明白”的交流。老师最常见的提问和对策,我提前给你捋一遍。
第一个高频问题:“你这个数据是哪来的?”我建议你在论文和 PPT 里都明确写一句“本系统使用符合业务规律的模拟数据,数据生成程序支持参数调节,可以模拟不同用户规模和不同活跃时长的数据集”。这样回答非常坦荡,老师一般不会再纠结真实性。
第二个高频问题:“为什么选这些技术栈?为什么不换 Spark/Flink?”别慌,先强调课题定位是“简单数据分析系统”,再讲技术匹配场景。比如“Spark 适合集群海量数据场景,本系统的数据量级在几十万级别,用 Pandas 处理更直接,复现成本更低”。这样回答既有理性,又显得你在设备选型上思考过。
第三个高频问题:“你系统的不足和展望是什么?”我教你一个万能套路:从三个维度讲,实时性不足(当前是离线批处理)、推荐智能化不够(目前是规则推荐)、数据维度不够丰富(可以去尝试引入观看行为序列特征和点击序列模型)。把自己主动暴露的问题讲清楚,老师反而认为你有反思深度,比空洞地吹自己强很多。
第四个高频问题:“某个指标算得对不对?”这时候你就把指标字典那张表拿出来,先解释口径再现场演示。所以做项目的时候一定把每张分析图对应的代码和数据文件保留好,答辩前再跑一遍,确保现场环境能运行,这种“现场演示”的冲击力远大于口头解释。
写到最后再聊几句实际体会
这些年帮人看过的选题里,“短视频数据分析”类的项目很多,真正做得扎实的都有一个共同点:他们并不追求用最夸张的工具和算法,而是把每一个环节的细节都照顾到位,从业务指标定义到代码组织,从图表排版到论文措辞,都能说得清清楚楚。我个人在实际操作中的体会是:这个题目的上限很高,下限也很低,最终成绩好不好,不是看你是不是用了深度学习模型,而是看你的系统能不能完整回答“用户到底怎么刷短视频”这件事。把这个主线守住,你的代码和论文就是自洽的、稳的。
最后再分享一个小技巧:把整个项目跑通的完整流程录屏保存下来,答辩前自己反复看两遍。这个习惯救过我不少次,因为你临场阶段很有可能忘记某个脚本的运行顺序,录屏就像操作笔记,随时帮你拾起来。希望这篇经验对你做毕业设计有帮助,也能让你少走一些我当年走过的弯路。祝你顺利完成这个题目。