1. 为什么我推荐这个毕设选题每到毕业设计选题季总会有人问我“有没有那种能写、能答、还能写在简历里的项目”。我的标准答案是基于HadoopDjango的股票历史行情数据分析系统。这个题目的核心价值不在于“炒股”而在于它把Hadoop的分布式存储、MapReduce离线计算、Django后端开发、ECharts可视化和机器学习预测完整串了起来。股票历史行情数据获取路径成熟、字段结构规整非常适合作为毕业设计的载体。真正做完之后你会发现自己既接触到了“大数据”的常见玩法又没有掉进“为分布式而分布式”的坑里性价比非常高。这个选题并不要求你造出什么量化投资神器它更像是一个“数据全链路”作品从行情数据采集清洗到HDFS存储和MapReduce指标计算再到Django接口和页面展示最后用机器学习做一段趋势预测实验。每一个环节都有明确的技术点可以展开写也都有对应的结果可以演示。所以这一个题目基本上等于把数据分析和Web工程两个方向都覆盖到了。1.1 为什么选“股票历史行情”而不是其他数据毕设里最怕的就是找数据环节被卡住。股票历史行情的最大好处是数据源免费、开放、稳定。通过AkShare或者Tushare用Python就能批量下载A股日线数据字段包含股票代码、交易日期、开盘价、收盘价、最高价、最低价、成交量等覆盖率足够一个毕设项目使用。相比之下电商数据、政务数据、社交数据往往要处理爬虫封禁、字段缺失、权限申请等问题时间成本完全不可控。数据结构也很适合当“毕设素材”。股票日线数据是典型的时间序列天然带有日期字段适合做排序、聚合、滑动窗口和预测评估。股票代码和行业信息还可以用来做分类统计比如按行业算平均收益率、按年份算波动率。老师不需要听你解释半天业务背景看到K线图就明白系统在做什么。这种“低解释成本、高可视化收益”的题材在答辩时尤其占便宜。1.2 难度梯度合理不会“难到放弃”这个题目的妙处在于难度可控。Hadoop部分做伪分布式环境就够了不需要真去申请一台集群MapReduce作业用Hadoop Streaming加Python写Mapper和Reducer难度比写Java版低很多。Django部分就是常规的MVT开发做一个股票列表页、行情详情页、预测结果页再配几个JSON接口工作量完全在可控范围内。机器学习模块更加弹性你可以只做简单的线性回归或随机森林也可以挑战LSTM走通“特征构造—训练—评估—回测”流程答辩时能讲清楚为什么这么用就已经够了。我见过不少同学一上来想做大项目又搞实时流计算又搞分布式消息队列结果光是搭环境就花了一个月。反观这个选题把Hadoop伪分布式跑起来把Django页面做出来再加一个预测实验三个模块独立开展每个模块都能单独验收。进度再慢也能先交一个能跑通的“最小版本”后面再逐步完善。1.3 选这个题前先确认三件事第一Python和Pandas得能写。这里不是要你成为专家至少要会读CSV、处理空值、用DataFrame做分组聚合。第二Linux基础命令要熟练。Hadoop基本跑在Linux或者虚拟机上至少要会用tar解压、vim改配置文件、jps查进程。如果一看到“修改环境变量”就发怵建议先花一周补补基础。第三要有阅读报错日志的耐心。Hadoop和Django的排错最终靠的都是日志里的那几行ERROR而不是靠猜。如果这三点都没问题这个选题很适合。假如你觉得自己Python基础较弱但系统结构想得明白可以把机器学习模块降级成“统计分析”——计算均线、波动率、最大回撤这仍然是完整的数据分析闭环并不会显得项目单薄。2. 技术栈角色拆解Hadoop、Django、机器学习各管哪一段很多同学选完题后还是不清楚这些技术到底在项目里承担什么角色最后写代码时容易变成“为了用而用”。我建议你把整个系统理解成一条流水线Hadoop负责存储和离线计算Django负责把结果变成Web服务机器学习负责从历史规律里做预测实验。三者各管一段不重叠、不混乱论文写起来也顺。2.1 Hadoop处理历史数据而不是为了“分布式”三个字如果数据量只有几兆你非说用HDFS分布式存储答辩老师基本会追问一句“为什么不用Pandas直接读”所以你要把数据规模这件事想清楚。当你把全市场几千只股票近十年的日线数据都下载下来文件总量很容易达到几个GB单机Pandas处理起来开始吃力这时HDFS作为一个可扩展的分布式文件系统就派上了用场。更重要的是MapReduce可以做离线批处理清洗、采样、计算全市场年化收益率、波动率、最大回撤等指标逻辑上符合“大数据平台”的定位。我推荐用Hadoop Streaming来写Python版的MapReduce而不是强行写Java。原因是项目后端本身就是DjangoPython是主力语言再用Java另外写一套MR作业开发和调试成本都会增加。Hadoop Streaming允许你把Python脚本当作Mapper和Reducer命令行方式提交作业方便快捷。另外伪分布式模式下不需要额外配置ZooKeeper别被网上那些Hadoop整合ZooKeeper的教程带偏单节点验证阶段先保持最小依赖。2.2 Django让分析结果“被看见”而不是算了白算Django在这个项目里承担三件事对外提供数据接口、渲染可视化页面、管理登录用户。为什么选Django而不是Flask核心原因是Django自带ORM、Admin后台和用户认证能节省大量重复开发时间。你要做的股票列表、日线查询、自选股收藏本质上都是模型、视图、模板的关系Django的全家桶方案非常合适。Django的ORM还有个容易被答辩老师问到的点模型关联查询性能。比如查询日线数据时如果需要同时展示股票名称和行业普通写法会产生大量重复SQL。用select_related或prefetch_related可以一次性把关联对象查出来明显减少数据库压力。这个细节写在论文里说明你真的考虑过查询优化。Django侧的App划分我建议按业务职责拆账户管理、行情数据、预测模块三个App各管各的目录清晰。2.3 机器学习定位成“辅助分析实验”才是加分项机器学习是这个题的亮眼标签但也最容易翻车。如果你在开题报告里写“预测股票涨跌准确率达到90%”基本是给自己挖坑。正确的定位是构建一个基于历史行情数据的“趋势预测实验”用MA5、MA10、MA20、成交量变化率等指标作为特征预测未来几日收盘价然后用后20个交易日的数据做回测计算均方误差、平均绝对误差并和真实收盘价画在同一张图上对比。这样既展示了机器学习建模能力又守住了“预测存在不确定性”的底线。学有余力的话可以对比线性回归、随机森林和LSTM三种模型的效果但不要勉强。LSTM训练时间更长、参数更多毕设周期内很容易陷入调参泥潭。我更建议以随机森林或线性回归为主模型把实验设计做规范训练集和测试集按时间顺序划分不用随机打乱。光是“时间序列预测不能乱打乱数据”这一句话就能在答辩时帮你挡掉很多“你这个评估有没有问题”的追问。页面文案也要克制不要出现“必涨”“稳赚”这种字眼整个预测模块以“分析参考”的口吻来呈现。2.4 技术选型对比为什么不追求“最新最火”毕设阶段经常有一个误区别人用Spark我也要用Spark别人上Vue我也要前后端分离。我的建议是技术选型以“能稳定交付”为第一原则。Spark确实比Hadoop更现代但学习成本更高而且单机部署Spark的内存压力也不小Vue确实能做出酷炫交互但会和Django的模板渲染形成两套体系联调工作量直接翻倍。Django自带的模板系统配合ECharts已经足够完成所有演示需求。为了让你更直观地看明白我整理了一张比选表候选方案更适合的场景在毕设里的风险Spark大规模快速迭代计算、实时流处理学习曲线陡单机资源不足容易烂尾Flask Vue前后端分离的小型系统模块装配成本高登录鉴权需要自己写Hadoop Django离线批处理 快速开发Web后台技术不算最前沿但架构完整、容易讲清Hadoop Streaming Python想用Python实现MapReduce性能不如Java但胜在和后端语言统一表格里的“风险”一栏不是说不可以用而是提醒你评估自己的时间预算。毕设是在有限时间内做出完整作品技术栈和你已有基础越契合越容易稳定交付。3. 系统设计与数据链路完整方案不管论文里写得多复杂系统实际只有两条链路一条是从数据源到HDFS离线分析另一条是从HDFS分析结果到Django页面展示。下面我把每一步都拆开方便你照着搭。3.1 数据从哪来免费行情源怎么选我推荐优先用AkShare因为它完全开源不需要注册token安装后直接调用接口就能返回DataFrame。Tushare Pro也可以但部分接口有积分门槛新手注册后可能拿不到完整历史数据。下载日线数据时字段至少要包括股票代码、交易日期、开盘价、收盘价、最高价、最低价、成交量、成交额。股票基本信息单独再拉一份股票代码、名称、行业用于Django端做列表展示和分组统计。下载脚本建议写成“断点续传”式每下载一只股票的CSV先检查本地是否已有该文件避免重复请求接口被限流。有些接口会有频率限制两次请求之间最好sleep 0.2秒。最终把原始CSV统一放在data_etl/download目录批量上传到HDFS的/stock_data/raw路径。数据量上不用追求“完全覆盖全市场”可以挑选沪深300成分股或某个行业板块的数据既能说明问题又不会让HDFS上堆满几万个小文件。对毕设来说数据“有代表性”比“全量”更重要。3.2 原始层、清洗层、指标层三层设计HDFS上的路径建议设计为三级/stock_data/raw、/stock_data/clean、/stock_data/analysis。raw目录存放原始CSV数据从接口下载后原封不动保存clean目录存放清洗后的日线数据字段统一、空值剔除、停牌行补齐处理analysis目录存放MapReduce计算出的指标结果。这种分层方式对应大数据平台里常见的ODS、DWD、ADS思想写在论文里显得规范。清洗规则要提前定义好第一删除表头和全空行第二剔除收盘价为0或成交量为负的异常记录第三处理重复的“股票代码交易日期”组合保留最后一条。这里有个坑股票除权会导致价格跳空直接计算收益率会失真建议在数据准备阶段使用后复权价格或者下载时明确选择“后复权”数据。数据规模可以简单估算如果选200只股票、每只股票近10年约2400个交易日总量大约是48万行日线记录单文件并不大但足够体现MapReduce“把任务拆开处理”的思路。论文里你可以写“覆盖了数十万级别的历史交易记录”这个数据规模对于毕设演示来说是合理的。3.3 数据库表结构与关系Django侧不直接读CSV而是把清洗后的数据导入数据库用ORM查询。我建议至少设计三张业务表股票信息表StockInfo、日线行情表DailyQuote、统计分析表StockStats。StockInfo字段建议包括stock_code股票代码唯一索引、stock_name、industry、list_date。DailyQuote字段建议包括stock_info外键关联StockInfo、trade_date、open_price、close_price、high_price、low_price、volume、amount、adjust_factor。这里建议给“stock_info trade_date”加联合唯一约束防止重复数据。StockStats可以用OneToOneField挂在StockInfo上存MapReduce计算出的年化收益率、年化波动率、最大回撤、统计区间起始日期和结束日期。查询最近N天K线时Django代码可以这么写from django.core.paginator import Paginator from stockdata.models import DailyQuote quote_list DailyQuote.objects.filter( stock_info__stock_code600519 ).select_related(stock_info).order_by(-trade_date)[:120]这里用select_related是因为DailyQuote外键关联StockInfo查询每一条行情时要连带获取股票名称和行业如果不优化会产生大量SQL查询列表页面会很卡。Django的ORM写起来简单但这些细节得自己注意。3.4 项目目录怎么规划我习惯把大数据处理部分和Web部分分成两个顶层目录避免源码堆在一层导致导师看不懂。一个相对稳当的目录结构是这样的stock-analysis-system/ ├── data_etl/ # 数据采集与上传脚本 │ ├── download_hs.py │ └── upload_to_hdfs.sh ├── hadoop_jobs/ # MapReduce作业 │ ├── clean_mapper.py │ ├── clean_reducer.py │ ├── stats_mapper.py │ └── stats_reducer.py ├── django_web/ # Django工程根目录 │ ├── manage.py │ ├── config/ # settings、urls配置 │ ├── apps/ │ │ ├── accounts/ # 用户登录 │ │ ├── stockdata/ # 股票行情数据 │ │ └── prediction/ # 机器学习预测 │ └── templates/ # 页面模板 ├── scripts/ # 启动、初始化脚本 └── docs/ # SQL脚本、架构图、说明文档这样的结构在答辩说明时很清晰data_etl说明数据来源hadoop_jobs说明核心离线计算django_web负责展示和交互docs放论文需要的图表和说明。源码打包交付时这个结构也能给评阅老师留下“工程化”的印象。4. 核心功能实操实现从Hadoop到Django的一条龙我们需要把每条链路真正的落地步骤写出来包括环境搭建、MapReduce作业、Django读取结果、前端展示、机器学习预测。你可以把这一章节当作一份“重建指南”来用。4.1 Hadoop伪分布式环境的快速搭建Hadoop伪分布式搭建是老生常谈但版本选不对会浪费很多时间。推荐使用Hadoop 3.3.x搭配JDK 8配置前先确认java -version能正常输出。解压Hadoop安装包到/usr/local/hadoop后需要修改四个关键文件第一个是hadoop-env.sh主要设置JAVA_HOME可能还需要设置HADOOP_HOME。第二个是core-site.xml把NameNode地址指向hdfs://localhost:9000同时配置临时目录。第三个是hdfs-site.xml设置副本数为1并显式指定NameNode和DataNode的数据目录不要用默认的/tmp路径否则系统重启容易丢数据。第四个是yarn-site.xml配置MapReduce和ResourceManager相关参数。配置完成后先执行hdfs namenode -format然后执行start-dfs.sh和start-yarn.sh。用jps能看到NameNode、DataNode、SecondaryNameNode、ResourceManager、NodeManager这5个进程就说明启动正常。接下来用hdfs dfs -mkdir -p /stock_data/raw创建目录再通过hdfs dfs -put把本地CSV上传上去。伪分布式的意义是让你在单机上体验完整的HDFS读写和任务调度流程论文里描述时不要写“搭建了多节点集群”而应写“以伪分布式方式在单节点上验证了分布式存储和离线计算的可行性”。4.2 用MapReduce完成日线数据清洗与统计Hadoop Streaming是指定Mapper和Reducer为Python脚本的方式提交命令大致长这样hadoop jar $HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-*.jar \ -input /stock_data/raw \ -output /stock_data/clean \ -mapper python3 clean_mapper.py \ -reducer python3 clean_reducer.py \ -file clean_mapper.py \ -file clean_reducer.pyclean_mapper.py做的事情是读一行原始CSV解析字段剔除异常行再按股票代码作为Key输出#!/usr/bin/env python3 import sys import csv for line in sys.stdin: line line.strip() if not line or line.startswith(stock_code): continue row next(csv.reader([line])) if len(row) 7: continue code, trade_date, open_p, close_p, high_p, low_p, vol row if not all([code, trade_date, close_p, vol]): continue if float(close_p) 0: continue print(f{code}\t{trade_date}\t{open_p}\t{close_p}\t{high_p}\t{low_p}\t{vol})clean_reducer.py在这个作业里可以只做去重合并因为同一只股票可能从多个数据源重复写入Reducer按key汇总后统一输出。这样“清洗”这一步就有了明确的大数据语义Mapper并行做字段级检查Reducer做全局归并。另一个更出效果的统计作业是计算每只股票的年度收益率、年化波动率和最大回撤。思路是Mapper输出“股票代码\t日期\t收盘价”Reducer内部维护每只股票的收盘价列表最后统一计算。相关公式建议固定下来写进论文日收益率 当日收盘价 / 前一日收盘价 - 1年化波动率 日收益率标准差 * sqrt(252)最大回撤 min(当日净值 / 历史最高净值 - 1)MapReduce最终的输出会写入/stock_data/analysis目录下文件名通常是part-r-00000不是单个易读的CSV文件名。所以Django端读取的时候需要找到这个part文件读取或者直接把结果再导入MySQL避免每次都从HDFS拉取。4.3 Django读取HDFS分析结果并写入业务库Django侧最简单的做法是脱离HDFS API先通过命令行把计算结果拉到本地再用Pandas解析并写入数据库。示例命令hdfs dfs -cat /stock_data/analysis/part-r-00000 /tmp/stock_stats.tsv然后在Django脚本里用pandas.read_csv加载这个TSV逐行更新StockStats表。这种做法的好处是稳定、易调试不需要额外引入HDFS客户端依赖。如果你希望程序化一点可以用hdfs库from hdfs import InsecureClient client InsecureClient(http://localhost:9870, userhadoop) with client.read(/stock_data/analysis/part-r-00000) as reader: content reader.read().decode(utf-8)拿到内容后解析成结构体再调用Django ORM批量写入。这一步要注意的是WebHDFS端口新版Hadoop是9870老教程里的50070已经不用了。很多同学第一次调接口连不上就是端口写错。写入数据库后Django视图可以直接查StockStats和DailyQuote再返回JSON给前端。建议为行情接口设计两个URL/api/stock/list/返回股票基本信息列表/api/stock/kline/?code600519返回某只股票的日线序列视图里用JsonResponse返回数据即可不需要额外做序列化框架。保持简单反而更稳定。4.4 前端展示K线图、均线和预测对比可视化框架推荐ECharts文档丰富、K线图成熟而且能用CDN引入。在Django模板中写一段页面通过fetch请求后端接口拿JSON再组装到ECharts配置项里。这里给一个K线图的核心配置const option { xAxis: { type: category, data: dates }, yAxis: { scale: true }, series: [{ type: candlestick, data: klineData }] }; chart.setOption(option);特别提醒ECharts中K线图的数据顺序是[开盘价收盘价最低价最高价]不是常见的“开高低收”。我第一次做的时候按“开高低收”传数据结果K线影线全错位排查了很久。后端返回JSON前最好直接按ECharts要求的顺序组装好前端代码里不要再做二次转换。均线可以单独加line类型的seriesMA5、MA10、MA20在Django后端用Pandas滚动窗口算好然后和K线数据一起返回。页面右下角再放一个“预测对比图”真实收盘价和模型预测值用两条线对比这样机器学习模块的成果就能直观展示出来。ECharts的静态资源建议下载到本地static目录不要在答辩时依赖外网CDN现场网络一抖页面就白屏了。4.5 机器学习预测模块的落地写法我用随机森林回归做例子因为它稳定、参数少、不容易跑崩。特征工程部分要先按日期排序然后构造移动平均和成交量变化率import pandas as pd from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_absolute_error def build_dataset(df): df df.sort_values(trade_date) df[ma5] df[close].rolling(5).mean() df[ma10] df[close].rolling(10).mean() df[ma20] df[close].rolling(20).mean() df[volume_pct] df[volume].pct_change() df[target] df[close].shift(-1) return df.dropna() df build_dataset(quote_df) X df[[ma5, ma10, ma20, volume_pct]] y df[target] train_size len(X) - 20 X_train, X_test X[:train_size], X[train_size:] y_train, y_test y[:train_size], y[train_size:] model RandomForestRegressor(n_estimators100, random_state42) model.fit(X_train, y_train) pred model.predict(X_test) print(MAE:, mean_absolute_error(y_test, pred))这段代码把最后20个交易日作为回测区间完全按时间顺序划分。为什么不能随机打乱因为股票数据是时间序列如果测试集里混入训练期间的“未来数据”模型就相当于提前知道了答案评估指标会虚高。这一点你主动写进论文或答辩PPT是很典型的加分细节。训练完成后用joblib保存模型文件Django的预测接口里加载模型从最新行情里算出特征并返回预测结果。4.6 让系统更完整的补充模块自选股与回测报告如果时间和精力允许我建议再补两个小功能一个是自选股管理一个是简单回测报告。自选股管理就是注册用户可以收藏股票在列表页点一下“加入自选”Django侧建一张Watchlist表外键关联User和StockInfo。查询自选列表时用select_related(stock_info)避免循环查询。回测报告更简单用户选定股票和日期区间系统计算“买入持有”策略的年化收益、最大回撤和夏普比率和同期沪深300指数做对比渲染成一张结果页。这两个功能不需要复杂算法但会让系统从“只有展示”变成“能操作”论文里的功能模块图也会更丰满。答辩演示时用户登录、加自选、看回测整个交互链条很完整。5. 毕设过程中的高频问题与排查技巧这里整理我实际带项目时见过最多的问题按Hadoop、Django、数据特征和答辩演示四类来讲。5.1 Hadoop集群“起不来”怎么排查伪分布式搭好后最常见的报错是NameNode启动失败。很多教程让你把临时目录放在/tmp下但Linux重启或清理临时文件后NameNode的元数据就会丢于是启动失败。建议在hdfs-site.xml里显式配置property namedfs.namenode.name.dir/name value/usr/local/hadoop/data/name/value /property property namedfs.datanode.data.dir/name value/usr/local/hadoop/data/data/value /property改完配置后一定要删除旧的元数据目录再重新格式化否则会报“version file missing”之类的错误。NameNode还是起不来时去$HADOOP_HOME/logs目录下看hadoop-hadoop-namenode-*.log日志里会直接写明是端口被占用还是目录权限不对远比自己猜效率高。另一个高频问题是MapReduce任务提交后一直停在Accepted状态。这多半是Yarn的内存配置太低或太高。在低配笔记本上建议在yarn-site.xml里设置property nameyarn.nodemanager.resource.memory-mb/name value2048/value /property property nameyarn.scheduler.minimum-allocation-mb/name value512/value /property然后重启Yarn相关进程任务一般就能跑起来。5.2 Django连接HDFS和数据库的常见问题Django连HDFS最常见的是WebHDFS权限不足。HDFS默认权限比较严格当前操作用户如果不是Hadoop启动用户读取文件会报Permission denied。开发阶段可以使用InsecureClient(..., userhadoop)指定用户或者先用命令hdfs dfs -chmod -R 777 /stock_data放开权限。正式文档里建议表述成“创建专用分析用户并设置目录访问权限”不要写“把目录设成777”这种操作。数据库方面很多人用MySQL时会遇到Error loading MySQLdb module原因是没有安装mysqlclient或者缺少系统依赖。建议直接换成SQLite开始开发先把功能跑通最后再切MySQL如果坚持用MySQL记得统一字符集utf8mb4并在Django的数据库配置中加入OPTIONS: {charset: utf8mb4}。在PyCharm里导入Django工程时注意把运行配置指向manage.py而不是直接在IDE里打开某个py文件运行否则会丢失项目路径。5.3 股票数据特征工程里的坑第一个坑是“未来数据带入”。计算rolling均值前没有按交易日排序会把后面的数据混进前面的窗口导致预测结果假性偏高。最稳妥的做法是每组股票数据在进入特征构造前先执行sort_values(trade_date)。第二个坑是停牌日和上市首日。停牌日成交量可能为0pct_change会变成无穷大或NaN上市首日没有前收盘价收益率也是NaN。这些行要么剔除要么用前向填充否则模型会报错或者学到错误模式。第三个坑是除权除息。如果你拿的是不复权价格遇到分红送股会出现价格突然跳空收益率曲线会出现假的大跌建议统一处理后复权数据。特征工程看起来简单但这些细节才是项目质量的试金石。5.4 常见问题速查表现象可能原因处理建议NameNode进程不存在元数据目录丢失或端口冲突检查日志重建name目录并重新格式化DataNode无法启动数据目录不一致统一dfs.datanode.data.dir配置MapReduce任务一直AcceptedYarn内存配置不合适调低map/reduce内存重启yarnHDFS读取文件403WebHDFS用户不对指定userhadoop或调整目录权限预测结果几乎不变特征缺乏区分度或数据顺序错重构特征检查排序和窗口计算ECharts K线影线错乱数据顺序不对改为[open, close, low, high]Django迁移报错MySQL字符集或驱动版本问题统一utf8mb4更新mysqlclient版本5.5 答辩演示时容易翻车的三个细节答辩演示千万不要现场从零启动集群因为格式化、上传数据、跑MapReduce非常容易超时。我建议提前做三件事第一集群提前启动好HDFS上保存好已经跑完的结果文件第二Django服务提前开启分析结果已经同步到MySQL点页面秒开第三录一个2分钟的操作视频展示数据上传、提交MapReduce、查看日志的过程当作PPT里的动态补充。演示顺序一般是先讲架构再演示页面最后打开终端展示HDFS目录和任务日志证明数据确实走了一遍分布式流程。6. 写进论文和答辩演示的几个加分点6.1 论文结构怎么安排最稳妥论文结构建议沿用“背景—技术—需求—设计—实现—测试—总结”的顺序。关键技术章节拆成三部分HDFS与MapReduce、Django框架、机器学习评估方法系统设计章节画好整体架构图、数据流图、功能模块图和数据库ER图实现章节按模块写每个小节开头先说明这个模块要实现什么再贴关键代码最后说测试结果。这里我特别提醒架构图和数据流图一定要自己重画不要直接截网上的图答辩老师一眼能看出来。测试章节不能只写“系统运行正常”至少要包含功能测试用例表、MapReduce作业结果对比、预测模型评估指标表这三块这样“测试”才算真正有内容。6.2 答辩开场怎么讲“为什么用Hadoop”这几乎是必问的问题。回答思路不要慌分三层讲第一当数据覆盖全市场十年日线数据时数据量已经是千万行级单机Pandas处理吃力所以需要分布式存储与离线计算框架第二项目目标是验证HDFS和MapReduce在金融时间序列数据上的可行性采用Hadoop是方法论上的选择而不是为了炫技第三Hadoop生态可以横向扩展到Spark等计算引擎项目具备后续演进空间。讲清楚这三点既回应了“为什么不用Pandas”也说明你对技术选型有过思考。6.3 交付源码前记得做一次“三清理”最后分享一个我自己的习惯源码交付前一定做三清理。第一清理掉本地测试生成的临时文件和大数据缓存只保留一份能运行的样例数据集避免压缩包几个G发出去第二清理代码里的绝对路径像/Users/me/stock-analysis-system这种路径到别的电脑上必炸要全部改成相对路径或者用配置文件统一管理第三清理调试用的print输出保留日志级别的输出即可。清理完成后按README从零开始启动一遍确认能在20分钟内把环境跑起来再打包交付。这一步花不了太多时间但能让整个项目的完成度上一个台阶。根据我自己的经验这个选题最值得投入的地方不是“把某个模型调到多准”而是把大数据处理链路和Web展示真正打通。只要HDFS上有数据、MapReduce能出结果、Django页面能展示、预测模块有评估指标这就是一个完成度很高且经得起追问的毕设项目。如果你正在为选题纠结不妨就从这个方向开始。