
每年准备毕业设计的同学里总有一批人会盯上网约车和出租车数据。滴滴早在几年前就开放过规模不小的订单轨迹数据集加上天气、节假日、POI这些公开数据源做出来的分析系统既贴近生活场景又能把数据清洗、时序预测、可视化这些硬技能全串起来。我陆陆续续带过好几个做这个方向的学生自己也把供需平衡这块完整复现过一遍今天这篇就把整个《DjangoLLM大模型滴滴出行分析 出租车供需平衡优化系统》从题目拆解到答辩演示一条线捋清楚帮拿到这个题目的同学说说哪些环节千万别踩坑。这个题目乍看是“大数据毕业设计”本质上其实是一个**“时空数据分析业务建模系统集成”**的三层结构。出租车供需平衡优化的核心问题很简单某些区域在某些时段乘客打不到车而司机却在旁边空驶绕圈。做系统不是为了炫技而是要让平台运营者或城市管理者能直观看到错配发生的时间、地点和原因然后给出一组可执行的调度建议。LLM大模型在这个系统里承担的是“解释和建议”层而不是硬去替代时序预测模型这是后面所有设计的出发点。这篇内容主要面向两类人一类是已经拿到这套源码和文档、准备快速跑通并弄懂逻辑的同学另一类是准备自己做网约车或出租车方向选题、正在想架构和技术栈的人。我会先讲清楚供需失衡这个业务问题怎么被量化再拆系统的整体架构然后进到Django和LLM的具体实现细节最后把答辩和演示需要注意的实务经验放出来。1. 题目拆解三个关键词分别扛什么活1.1 供需失衡本质上是“时空错配”不是单纯运力不够做这个系统之前我一直提醒学弟学妹先把业务模型想明白。出租车供需问题不能简单说“车不够”因为高峰期全市平均来看可能运力是够的但局部区域瞬时需求飙高司机从周边过去需要时间这就产生了供需剪刀差。典型场景就是晚高峰的CBD、雨后的大型商圈、演唱会散场后的体育馆周边这些地方的应答时长和取消率会显著高于城市均值。从数据处理的角度看供需状态的原始表达非常简单每一个订单都有起点坐标、起点时间、终点坐标、是否完成、从发单到应答的等待时长。把订单按空间网格时间窗口做聚合就能得到每个格子每段时间内的需求量再把司机轨迹数据按同样方式聚合就能得到运力供给量。供需差、需求满足率、平均等待时长都是在这个聚合结果上计算的。我给学生画过一张很直白的图把城市切成1公里×1公里的网格时间切成15分钟一个窗口每格里有两个数字——需求订单数和可接单车辆数。系统的第一层价值就是把这个二维矩阵算出来剩下所有预测和优化都建立在这个矩阵之上。1.2 Django、LLM和大数据在系统中的分工三个关键词在标题里是并列的但在系统里它们的职责完全不同Django是整个系统的骨架负责MTV架构、ORM数据模型、REST API、后台管理和Web页面渲染。所有分析结果、预测结果、LLM生成的内容都要通过Django统一输出到前端大屏。大数据侧重数据处理和分析链路包括Pandas清洗、Hive或ClickHouse式的聚合查询思路、基于时间序列的预测模型以及最终的可视化呈现。毕设场景不需要上真正的分布式集群但“大数据”的思路要体现为“能处理大规模订单数据并提取有价值指标”的能力。LLM大模型是这个题目近几年新加进来的亮点它承担的是传统分析系统做不了的事情把冷冰冰的指标表格翻译成人类能理解的业务洞察回答“为什么这个区域出现供需失衡”这类归因问题并生成具体的运力调度建议文本。我见过不少翻车的毕设问题就出在把LLM硬塞到预测环节。LLM去做纯数值预测既慢又不稳定而且评委一问就露馅。正确做法是数值预测交给树模型或深度学习模型LLM站在模型结果之上做语义理解和文本生成两者各干各的活。1.3 为什么这个选题在毕业设计市场里热度这么高从带学生的经验来看这个题目受欢迎有几个很现实的原因。第一数据题材好讲网约车和出租车的供需问题全社会都有体感开题报告和答辩都能轻松讲清楚背景第二技术栈覆盖面广从数据库设计到后端API再到前端可视化再到模型训练和LLM调用几乎把本科阶段能用的技术都串了一遍工作量表很好写第三可扩展性强同一个数据管道加一个模块就能变成景区客流分析、共享单车调度、外卖骑手热力分析改题成本低。这些特点决定了一件事拿着源码跑通只是起步你要真正理解数据是怎么流动的、LLM是在哪个环节介入的、系统怎么回答业务问题的否则OpenCV类的“PPT式集成”一眼就会被导师看穿。接下来我把整套系统的搭建步骤和实现原理按实战顺序完整过一遍。2. 数据工程订单轨迹如何变成供需指标2.1 数据来源与字段设计做网约车分析常用的公开数据有两类一类是滴滴盖亚数据计划开放的部分城市订单和轨迹数据另一类是TLC纽约出租车数据。国内毕设场景绝大多数用滴滴盖亚的几个城市子集我这边复现用的也是这类数据。订单数据核心字段包括订单ID、司机ID、乘客ID、开始时间、结束时间、起点经纬度、终点经纬度、正常计价时长、计价里程。如果拿到的是轨迹数据那还需要按时间序列拆出每辆车的行驶方向变化。数据库表设计上我建议按五张表来做职责分明表名核心字段用途order_info订单ID、乘客ID、司机ID、起终点经纬度、开始/结束时间、状态原始订单明细driver_info司机ID、车辆类型、所在区域、在线状态、活跃时段运力方信息demand_agg网格ID、时间窗口、订单量、平均应答时长需求侧聚合结果supply_agg网格ID、时间窗口、可用车辆数、平均空驶时长供给侧聚合结果imbalance_index网格ID、时间窗口、供需指数供需要素融合大多数毕设代码里会直接落一个宽表叫agg_15min之类的派生表。宽表虽然查询快但业务语义不清晰如果要加新指标还得改表结构。我一般还是推荐拆窄表再用视图层聚合。Django的ORM在跨表查询上性能可以接受因为毕设数据量一般就几百万行加好索引之后完全不用担心。2.2 时空聚合向后兼容的网格划分网格划分是这个系统数据链路的第一个关键决策点。1公里方形网格的做法实现简单、用经纬度整除就能算但存在边界效应——某辆在网格边缘的车可能离乘客只有100米却因为位置编码落到了邻居格子。更合理的做法是使用H3六边形网格Uber开源的那套方案边界误差更小而且天然支持多级分辨率。我个人建议直接采用H3的resolution 7作为聚合粒度每格大约1.2平方公里对应城市15分钟级的供需分析正好合适。Django代码里加一个h3-py依赖把原始经纬度转成H3索引再按索引和15分钟时间窗口做group by逻辑干净又高效。如果是赶工图快也可以用Geohash它能精确到米级但跨格跳变比H3更频繁绘图时不够平滑。2.3 数据处理链路从CSV到模型输入的完整管道实际数据处理流程我拆成四步数据清洗去掉经纬度为0、时间异常、订单状态非正常的脏数据同一司机ID在同一时间窗口的重叠订单要去重。特征工程对时间戳拆出小时、星期、是否节假日、是否为早晚高峰标记对网格坐标补出该区域的POI密度、周边小区数、商圈距离等静态特征。供需聚合按H3网格15分钟窗口聚合计算每格需求数、供给数然后算供需指数。模型数据集构建把历史N个时间窗口的供需指标拼成滑窗特征未来一个窗口的值作为预测目标按时间顺序切训练集和测试集避免随机切分造成数据泄漏。这里要特别注意一条纪律模型训练只能用过去预测未来。很多人直接把数据随机打乱训练调参调出来效果很好结果一拿给导师看就被质疑因为测试集里混着未来的信息。时序项目切数据集必须按时间截点来比如用前75%时间窗口做训练、后25%做验证模型选型和评估全在时间轴上操作。3. 供需不平衡度量与预测建模3.1 核心指标供需指数怎么算才不虚供需平衡需要一个可量化、可比较的指标。常用的定义是每个时空格子内“需求订单数/可用车辆数”的比值但直接用订单数做分母是不对的因为需求本身是和运力互相作用的——运力充足时需求会被释放运力不足时一部分乘客直接放弃叫车你不会看到这部分隐性需求。所以业界更常用的做法是结合实际完成订单量和接单率来反推需求规模。我在这套系统里用的定义是supply_demand_ratio total_demand_orders / max(active_supply_vehicles, 1)其中total_demand_orders不是当天总订单量而是该时间窗内的“发单请求数”包括最终被取消的单active_supply_vehicles是网格内空闲或即将空闲的车辆数。当比值大于阈值比如2.0时标记为供不应求低于阈值时标记为运力过剩。为让失衡程度更直观可以构造一个区间在0到1之间的指数imbalance_index (supply_demand_ratio - 1) / (supply_demand_ratio 1)这样正值表示供不应求负值表示供给过剩范围天然对称。这个指数在时间轴上画出来能清楚看到早晚高峰的错配形态。3.2 时序预测树模型为主、深度学习为辅需求预测是这个系统的技术核心之一。预测对象可以选网格级的订单量也可以选城市级总需求前者空间维度高、单个格子序列噪声大后者序列平滑但丢失调度场景。毕设层面我建议采用折中方案先做城市级需求总量预测再把总量加上历史空间分布比例下推回网格级。模型选择上我用过Prophet、LightGBM、LSTM三个方案对比下来LightGBM在这个场景是性价比最高的理由很实在特征工程友好的离散特征小时、星期、节假日树模型天然能处理对2019年疫情前后的市场突变树模型在短周期特征上的适应速度快于LSTM训练时间短一台普通笔记本就能跑十几个城市级别模型。Prophet看着是时序专用但对节假日和突发事件的建模太粗预测曲线的峰值比真实值平滑很多LSTM表现中规中矩但特征归一化和调参成本高如果论文里没有充足分析和对比容易被评委追问细节。我的建议是主模型用LightGBM同时跑一个Prophet做对比曲线展示出你比较过不同方案的能力。3.3 LLM在预测之外的增值场景把预测结果交给LLM之前需要先准备一套归因知识库。这个知识库可以预置一些规则和相关指标比如“周日17:00-19:00商圈周边POI密集区供需指数偏高”LLM拿到实时聚合结果后会从知识库里抽取相关因素生成一段自然语言解释。这比直接甩一个数字给用户有用得多也是系统在答辩时最容易被记住的亮点。实际操作时可以把当天各网格的供需指数计算好拼成一段JSON然后让LLM从以下角度分析供需失衡最严重的3个区域及其共性特征与上周同期相比的变化幅度、可能的原因建议的调度策略比如从闲置率高的区域引导多少辆车过去这一步利用的是LLM的上下文理解和生成能力不需要它做任何数值推理避免让大模型算错数这种尴尬局面。数值都是后端算好的LLM只负责“好看地说话”和“解释”。4. Django系统实现从ORM模型到可视化大屏4.1 MTV代码组织与核心模型用Django做这套系统项目结构我建议按模块切分而不是堆在一个app里。推荐分出四个appanalysis承载数据聚合和指标计算逻辑predict模型训练、预测调度和结果缓存llm_service封装与大模型接口的交互dashboard可视化页面和API接口模型层的核心可以落在analysis里。定义一个GridStat模型代表每个网格每个时间窗口的聚合数据class GridStat(models.Model): h3_index models.CharField(max_length32, db_indexTrue) time_window models.DateTimeField(db_indexTrue) demand_count models.IntegerField() supply_count models.IntegerField() imbalance_index models.FloatField() create_time models.DateTimeField(auto_now_addTrue) class Meta: indexes [ models.Index(fields[h3_index, time_window]), ]这个模型是系统所有查询的核心入口。大屏上的热力图、柱状图、趋势线底层全是按不同维度对这个表做group by。索引建对了查询速度才有保障。4.2 异步任务链定时预测与WebSocket实时推送为了让系统有“实时分析”的感觉不能每次页面刷新都现算指标必须有一个定时任务管道。我用的是Celery Redis的经典组合定期任务每15分钟拉一次最新订单数据跑聚合计算写库更新预测模型缓存把结果通过WebSocket推给前端页面。这里有个实现细节容易被忽略Django默认的同步ORM在Celery的异步任务里调会阻塞事件循环。如果你用了Django Channels的WebSocket建议在异步消费者里用database_sync_to_async包一层或者干脆把推送给前端的数据从Redis缓存里读不直接查库。我踩过的坑就是WebSocket连接建立后第一次查库直接把事件循环卡了几秒前端所有推送全部乱序后来改成从Redis读最近一轮结果才稳定下来。Django Channels的消费者核心逻辑类似这样class DashboardConsumer(AsyncWebsocketConsumer): async def connect(self): await self.accept() self.group_name dashboard await self.channel_layer.group_add(self.group_name, self.channel_name) async def push_data(self, event): await self.send(text_datajson.dumps(event[data]))然后Celery任务里算完指标通过channel_layer.group_send往这个组里扔数据就行。前端收到后直接刷新ECharts图表的setOption大屏就是这样“动”起来的。4.3 LLM模块的接口封装与提示词设计LLM模块建议独立封装一个llm_client.py对外只暴露analyze_imbalance(data_json)和generate_suggestions(context)两个函数底层用哪个大模型都可以方便在答辩现场切换模型。默认实现可以走OpenAI兼容接口也可以在本地用Ollama跑Qwen等开源模型。提示词设计对输出质量影响极大我贴一个实际调优过的模板结构你是一位城市运力调度分析专家。以下是某城市在最近15分钟内的供需聚合数据JSON格式 {data_json} 请基于数据完成以下任务 1. 指出供需失衡最严重的三个区域及其特点 2. 结合历史同期数据进行归因分析说明可能的原因 3. 提出具体可执行的运力调度建议按优先级排序。 要求语言简洁专业不超过500字。注意这里没有让LLM计算任何数值所有结论都基于输入JSON里的指标所以它的输出大部分情况下是准确且可信的。答辩时评委问“大模型在系统里的价值是什么”你就可以很坦然地讲它负责把结构化数据翻译成决策者可读的建议并生成归因假设而不是参与数值计算。5. 可视化大屏与交付演示别让答辩毁在演示细节上5.1 大屏页面布局与地图呈现可视化是毕业设计最直观的分数来源。我建议大屏按三列布局中间是城市热力地图展示当前时段供需指数分布红色表示供不应求、蓝色表示供给过剩左侧放订单量趋势曲线和预测对比图右侧放供需不平衡Top10榜单和LLM生成的调度建议文本。地图用ECharts的bmap或map系列把H3网格渲染成多边形热力图。颜色映射建议用红色系表示需求大于供给蓝绿色表示供给大于需求中间色表示平衡这样一眼就能看出问题区域。地图上的数据来自API接口地址类似/api/v1/grid_stats/?window2024-01-15 18:00:00Django的DRF写起来干净利落。预测模块单独放一个对比图画两条线历史上真实订单量与模型预测值并标注RMSE和MAPE。这里不需要做得太复杂但一定要让人看出模型“预测得差不多”而不是画了一堆看不懂的曲线。5.2 演示前检查清单从数据到模型再到LLM答辩演示最容易翻车的环节有三个我逐个说第一数据过旧或为空。如果数据库里只导入了两个月前的数据演示时点开实时大屏会发现所有数据都是静止的。解决办法是初始化时把数据时间改为“最近一段时间”让趋势图和热力图看起来像活的。第二模型预测结果不加载。预测模型如果每次答辩前重新训练很容易因环境差异导致性能下降甚至直接报错。正确做法是把训练好的模型缓存为文件或存入Redis页面加载时直接读取预测结果后台异步重新训练。第三LLM接口超时。大模型API在网络波动时有概率长时间无响应页面因此卡死这种情况非常被动。必须在Django视图层加超时和降级逻辑——LLM调用超过8秒就返回一条预设的缓存建议保证页面永远有内容可看。5.3 源码复现时的高频报错与修复拿到这套源码照着作者文档跑基本上会有三个高频报错点Python版本不匹配。老版本Django项目对3.10以下有兼容问题但新版Django 5.x又要求Python 3.10以上。建议直接建Python 3.10的虚拟环境装requirements.txt之前先看Django版本再决定。MySQL时区问题。聚合表按15分钟窗口分组时如果MySQL和Django的时区设置不一致会出现整点结果对不齐。保险做法是全局设UTC展示层再转本地时间。H3依赖安装失败。h3-py在某些Windows环境需要预编译二进制解决方案是安装h3-py之前先装Microsoft C Build Tools或者直接改用Geohash库绕开。这些问题大多不是代码逻辑问题是环境问题。冷静下来看报错栈往往一条命令就能解决。6. 论文、PPT与答辩论点让评委觉得你“懂业务”6.1 论文写作主线问题驱动而非技术堆砌写论文时很多同学喜欢先讲Django多好、LLM多强再讲自己用了哪些技术这是评委最反感的写法。好的主线应该是问题驱动的先讲出租车供需存在什么样的时空错配问题再推导出要量化这个错配需要哪些数据和指标进而推导出需要怎样的系统来监控和辅助决策最后落到Django和LLM如何支撑这套系统。这样一来Django是解决业务问题的工程框架LLM是解决解释与建议问题的智能助手两者都在业务链条上找到位置而不是两个孤立的“技术亮点”。6.2 论文结构建议与每个章节的“废话禁区”我建议论文按七章走绪论、相关技术介绍、系统需求分析、系统设计、系统实现、系统测试、总结展望。其中第三章“需求分析”是答辩印象分的重要来源一定要包含用例图和数据流描述第四章“系统设计”要把数据库表结构、接口设计、模型训练流程放进去第五章“系统实现”多放截图和核心代码片段。写这类技术论文尤其要避开的雷区是“大段全抄官方文档介绍”。Django和LLM的技术介绍写三页可以但必须落回到你这个系统里比如讲Django的ORM时顺手带出GridStat表的索引设计讲LLM时引出你设计的提示词结构。技术是为业务服务的这一句话在论文里要贯彻始终。6.3 答辩高频问题与参考应答方向答辩前可以把下面这几个问题背熟思路问为什么用Django而不用Spring Boot答一是Python生态在数据处理和机器学习上更顺畅从Pandas清洗到训练模型到Django后端可以共用一套语言二是项目定位是数据分析系统不是高并发工程平台Django开发效率更高。问LLM大模型在这个系统里究竟起了什么作用答它不参与数值计算主要负责把结构化分析结果转化为自然语言的业务洞察和调度建议保证分析结果的易读性和可解释性。问预测模型的可解释性怎么保证答树模型可以输出特征重要性排序再加上时间窗口内的对比分析可以解释“为什么某个区域未来一小时会供不应求”而不是只给一个预测数字。这些都是把系统的业务价值和技术细节结合起来讲的应答方式。顺着这个思路绝大多数评委问不倒你。最后再分享一个实操小技巧答辩演示前把LLM调用的提示词模板预先放置到页面配置文件里演示时完全不用现场写。系统初始化时就把当天的历史数据预热好模型结果和LLM建议都预生成一份缓存。这样评委看到的永远是“秒开”的状态而不是现场等待进度条。我每次给这套系统做演示都会额外加一个“数据刷新按钮”放在角落里既展示了实时能力又不影响主流程的流畅度。记住好演示的核心不是功能多而是节奏稳。