资讯动态

旅游智能推荐与数据可视化系统:基于Python/Django协同过滤实现

发布时间:2026/10/8 15:24:20 来源:尧图企业网站定制
1. 先把项目拆开看旅游智能推荐和数据可视化到底做的什么事1.1 这套系统要解决的真实问题如果你正在找毕业设计的源码看到“Python旅游智能推荐与数据可视化系统”这个标题第一反应大概率是源码拿到了然后呢这套系统到底做了什么这篇博文我会把它的设计思路、协同过滤的落地方式、可视化的实现路径以及我实际跑通项目时踩过的坑完整地写一遍。它不算什么黑科技但确实是毕业设计里性价比很高的题目Django负责业务逻辑协同过滤负责推荐图表库负责可视化链路完整答辩时讲得清楚。先说说需求背景。用户打开一个旅游平台面对几百个景点根本不知道从哪下手平台记录了大量浏览、收藏、评分数据却没有被利用起来。这套系统的目标就是把这两件事打通一方面基于用户历史行为与相似人群的判断给出个性化推荐另一方面把数据库里的行为数据转成图表让管理员直观看到热门景点、出行偏好和趋势变化。所以它不是一个单纯的景点展示网站。系统至少要覆盖三种视角普通用户能注册登录、浏览景点、收藏评分、查看推荐列表推荐引擎能根据行为记录计算出潜在兴趣管理员能通过图表掌握平台运行状况。三种视角放在同一个Django工程里不同功能用不同的app和路由组织模块边界非常清晰。1.2 适合谁拿来学习和参考说到适用人群计算机、软件工程、大数据相关专业的毕业生都合适想快速熟悉Python Web开发的人也可以拿它练手。它的知识点覆盖量很均衡数据层有MySQL和Django ORM业务层有用户与景点模块算法层有协同过滤表现层有可视化页面。这个复杂度比“博客系统”高一点又没有电商系统那种支付、库存、分布式之类的复杂模块刚好卡在“够得着”的位置。对想用它做论文的人来说这套结构也足够支撑一整篇毕业论文。需求分析可以写用户痛点系统设计画架构图和数据库E-R图算法章节写协同过滤原理和相似度公式可视化章节写图表选型与指标设计测试章节写功能测试和推荐效果对比。一条线串下来论文不会缺内容也更不容易在答辩时被问住。1.3 模块全景先看一眼把系统切开来看大概是这几个模块用户模块注册、登录、个人中心。用户所有操作在这里产生记录。景点模块景点名称、图片、城市、评分、价格、简介是推荐和统计的共同基础。行为模块浏览、收藏、评分记录协同过滤需要的原料都在这里。推荐模块基于用户的协同过滤算法负责生成个性化推荐列表。可视化模块统计景点热度、地区分布、用户变化、评分分布输出图表数据。管理后台Django Admin自带的数据管理系统演示和运维都方便。用户每一次浏览、收藏、评分都会留下行为日志。当他点击“获取推荐”系统会拿当前用户的行为去对比其他用户找出最相似的一批人再把他们喜欢而当前用户没见过的景点召回按预测分数排序后返回。这套链路看着简单但涵盖了推荐系统里召回、排序的基本思路写到论文“系统设计”章节很合适。2. 为什么选 Django、Python 和协同过滤这套组合2.1 Django 在毕业设计场景里的优势先回应一个高频问题用Flask不行吗用Spring Boot不行吗当然可以但Django是综合下来起步成本最低的选项之一。它自带Admin后台表格数据的维护界面自动生成自带认证系统注册登录不用自己写session和cookie自带ORM数据库操作全部面向对象自带模板引擎既能服务端渲染页面也能配合Vue或原生JS。Django的MTV分层也让论文好写很多。Model对应数据表Template负责渲染View承接业务逻辑。答辩演示时可以说是“模型层定义了景点表视图层实现了推荐接口模板层渲染了可视化页面”考官基本能理解你的设计。对初学毕业设计的人来说这种清晰度非常重要能减少“代码写完了但说不清”的尴尬。2.2 推荐算法为什么用协同过滤而不是深度学习有些同学的题目里挂着“大数据”“大模型”就想着直接上神经网络。我的建议是在毕业设计阶段先把协同过滤做扎实。大模型技术虽然热度高但放到这类项目里很容易变成“硬蹭”。数据量不够训练效果不好答辩时也容易被追问过拟合、调参、训练环境等细节反而给自己挖坑。协同过滤的逻辑用一个生活化的说法就是“人以群分”如果你和我去过的景点高度重合那我想去哪里大概率也是你的菜。它不需要GPU不需要大规模数据集不需要复杂的训练流程用Python字典加数学公式就能实现。论文里可写的点还很多相似度计算、邻居选择、打分加权、冷启动处理每一项都能展开写几百字。这套成本收益比在毕业设计场景里几乎是最优的。2.3 可视化选 ECharts 的原因旅游项目做可视化ECharts是首选。它支持柱状图、折线图、饼图、散点图、地图、热力图这些常用图表基本覆盖旅游项目所有展示需求。更重要的是它纯前端运行和Django之间只交换JSON前后端松耦合后期改图表样式完全不影响后端逻辑。整个链路是这样的后端用Django ORM做聚合统计比如统计每个城市的景点数量、每个景点收到的收藏数然后序列化成JSON前端在页面加载时请求接口拿到数据后喂给ECharts渲染。这种模式通用性极强学会之后再做数据大屏、后台报表都是同一套思路。我后来接过的几个数据分析项目基本也都是这个套路。3. 协同过滤推荐算法核心逻辑拆解与代码落地3.1 行为数据怎么设计评分矩阵是协同过滤的基础。每个用户一行每个景点一列格子里放用户对景点的偏好程度。不过很多系统没有显式评分只有浏览、收藏等隐式行为。所以先要对行为做权重映射按照“动作越主动信号越强”的原则我这里给了三档行为类型权重数据来源浏览1浏览记录表收藏2收藏表评分3评分表这样构建出来的用户偏好向量就能综合反映行为强度。有一点要注意同一个用户对同一个景点可能有多种行为例如先浏览后收藏处理时要合并取权重最大的行为即可避免重复计算导致分数虚高。3.2 相似度计算选哪种相似度计算推荐优先用皮尔逊相关系数。公式是这样的r Σ((x_i - x̄)(y_i - ȳ)) / sqrt(Σ(x_i - x̄)² * Σ(y_i - ȳ)²)它的好处是做了中心化处理。有的用户习惯打高分有的用户永远给低分如果直接用余弦相似度评分尺度的差异会影响结果中心化之后系统在意的是“你比自己的平均偏好更喜欢什么”而不是绝对分数。这个细节写进论文考官会认为你是真的理解算法而不是单纯背了一个公式。3.3 完整的推荐流程整个推荐流程可以拆成六步读取当前用户的行为记录组装成偏好向量。遍历其他用户算出和当前用户的相似度。取相似度最高的N个用户作为邻居。汇总邻居用户喜欢过而当前用户没接触过的景点。按“相似度乘行为权重”累加计算候选景点得分。排序取前K个返回给前端。代码组织上我习惯把算法单独放到一个模块里比如 recommmend/utils.py不直接依赖Django的request对象方便单独调试和单元测试。接口层再从request里拿user_id调用算法模块。这样做职责分离后期想换矩阵分解、混合推荐只要改一个文件就行。3.4 冷启动问题怎么兜底新用户没有任何行为相似用户无从谈起。这几乎是协同过滤被问得最多的缺陷。处理办法是加一个兜底逻辑如果用户行为记录太少比如少于3条就直接按热度排序推荐。热度可以综合浏览量、收藏数、平均评分来计算用一个简单的加权公式hot_score 0.4 * 浏览量 0.3 * 收藏数 0.3 * 平均评分这个逻辑简单又可解释。论文测试部分可以专门写一节“冷启动场景测试”说明系统在用户没有历史行为时依然能给出合理推荐。答辩答到“冷启动”这个问题时也不会慌张。4. 可视化与数据分析从数据库到图表页面4.1 可视化指标怎么设计做可视化之前先想清楚一个页面要回答哪几个问题。我的建议是围绕四组指标来做景点热度浏览量排前10的景点、收藏数榜、评分榜。地区分布各省市景点数量或者用户所在城市分布。用户发展近6个月新增用户趋势、活跃用户占比。评分分析评分分布直方图、价格区间占比。这些指标都能用Django ORM直接统计出来图表上有很直观的差异演示时视觉效果也好。我见过一些项目图表非常多但每张图都看不出业务含义反而不如四到五张重点图来得清晰。可视化是为了辅助判断不是为了撑页面篇幅。4.2 后端输出图表数据的标准写法后端只需要做好一件事把统计结果序列化成JSON。用Django的JsonResponse输出核心代码很短from django.db.models import Count from django.http import JsonResponse from .models import ScenicSpot def top_scenic_api(request): data ScenicSpot.objects.values(name, city) \ .annotate(totalCount(id)) \ .order_by(-view_count)[:10] result [{name: item[name], value: item[view_count]} for item in data] return JsonResponse({code: 0, data: result}, json_dumps_params{ensure_ascii: False})注意ensure_ascii参数。不设置的话中文会被转成\uXXXX接口虽然能用但排错时满屏转义字符看着非常费力。这个细节属于“网上教程很少写、但实战一定会遇到”的类型建议直接记住。4.3 可视化大屏的布局思路毕业设计里出现“可视化大屏”不一定非得用DataV之类的付费产品ECharts就能拼出来。布局上我建议按“顶部标题区、中部地图区、两侧榜单区、底部趋势区”来排。顶部放系统名字与数据更新时间中部用地图组件展示各地景点热度左侧放热门景点TOP10柱状图右侧放用户来源饼图底部放新增用户折线图和评分分布直方图。实现方式很简单整个页面分成多个div每个div对应一个ECharts实例。写代码时会发现最麻烦的不是图表本身而是容器高度。ECharts初始化时会读取容器尺寸如果CSS没给高度图表就渲染不出来或者只显示一条线。建议统一设置.chart-box { height: 380px; }并且在窗口缩放时调用resize方法。这个小细节能替你在演示时省掉不少尴尬。5. 数据模型设计表结构定得好后面少走弯路5.1 核心表有哪些建模是这种系统最容易踩坑的地方。表设计不佳后期补字段、改迁移文件会非常痛苦。我建议一开始就把下面几张表定义清楚用户表继承Django的AbstractUser加一个头像或手机号即可。景点表名称、城市、地址、简介、图片、评分、浏览量、价格。评分表外键关联用户与景点字段包含评分值和创建时间。收藏表外键关联用户与景点记录收藏时间。浏览记录表外键关联用户与景点记录浏览时间。地区表城市名、省份名、经纬度地图可视化需要用到。行为数据表是协同过滤的数据源一定要给外键字段加上索引尤其是(user_id, scene_id)这种组合查询频繁的字段。虽然项目数据量小不加索引也能跑但养成加索引的习惯是专业性的体现。5.2 Django ORM 的表定义示例用Django ORM写景点表代码不算多class ScenicSpot(models.Model): name models.CharField(max_length100, verbose_name景点名称) city models.CharField(max_length50, verbose_name所属城市) address models.CharField(max_length200, verbose_name详细地址) intro models.TextField(verbose_name景点简介) image_url models.URLField(verbose_name图片地址) score models.FloatField(default0, verbose_name评分) view_count models.IntegerField(default0, verbose_name浏览量) class Meta: db_table scenic_spot verbose_name 景点verbose_name不影响数据库结构但后台管理界面会显示中文标签。对毕业设计来说任何能完善展示细节的地方都值得做因为演示和截图都会进论文管理员后台保持全中文字段视觉效果会专业很多。5.3 数据怎么来模拟还是爬虫毕业设计最怕系统做完库里没数据。数据来源我建议首选模拟脚本。写一个Django management command或者独立Python脚本用random模块批量生成用户、景点、收藏和评分。数据量控制在三百到五百条就足够算法跑出效果。手动造数据的好处是可控可以专门设计几个偏好鲜明的用户比如一个用户全部收藏自然风光另一个用户全收藏人文古迹测试推荐效果时肉眼可见演示效果也好。爬虫也可以作为备选但实际体验并不好。爬回来的数据字段值很乱空值多清洗就要花掉大量时间还涉及数据合规问题。对重点在系统搭建的毕业设计来说模拟数据的性价比高得多。6. 实操从零跑通这套旅游推荐系统6.1 环境准备和依赖安装实际动手时我习惯先建虚拟环境再装依赖避免污染全局Python。项目需要的基础依赖其实很少django、pandas、numpy。pandas和numpy主要用于数据整理如果推荐算法用纯Python写不装它们也能跑装上则便于扩展成pandas版本。操作命令给出来python -m venv venv # Windows venv\Scripts\activate # macOS / Linux source venv/bin/activate pip install django pandas numpyDjango版本建议用3.2 LTS或4.2 LTS这两个版本比较成熟社区资料多遇到报错搜起来方便。别一上来就用最新的5.x有些第三方库可能还没跟上没必要给自己增加新的不确定因素。6.2 创建工程与 app进入项目目录后执行django-admin startproject travel_project cd travel_project python manage.py startapp travel python manage.py startapp recommend python manage.py startapp analysis我习惯分三个apptravel负责景点与用户交互recommend负责推荐算法analysis负责可视化和统计接口。职责清晰论文里的模块划分也能一一对应。划分好之后一定要到settings.py的INSTALLED_APPS里把三个app注册进去否则后面migrate一张表都不会生成。这个问题我在不少学弟的项目里见过属于低级的“日常坑”提前避开。6.3 迁移数据库与创建管理账号初始化数据库这几步python manage.py makemigrations python manage.py migrate python manage.py createsuperusercreatesuperuser走完登录后台就能维护景点和行为数据。到这一步系统的数据骨架已经建立。接着把模拟数据脚本跑一遍再访问推荐接口和可视化页面整套功能就能串起来演示。正式演示前再用无痕浏览器跑一遍完整流程避免缓存或登录状态影响前端效果这个习惯很实用。6.4 推荐接口怎么调试最方便推荐模块建议做成JSON接口通过GET参数传user_id返回推荐列表。调试时浏览器直接访问接口地址最方便python manage.py runserver # 浏览器访问 http://127.0.0.1:8000/recommend/?user_id1返回JSON里包含用户ID、景点列表和预测分数一眼就能判断推荐逻辑对不对。如果推荐结果不对先看行为数据的时间线再看相似度计算有没有问题最后检查是不是把用户ID或景点ID的类型搞混了。这种排查思路对新手很友好比闷头加print更高效。7. 常见问题与排查记录7.1 推荐结果一直为空怎么查推荐结果为空说明链路某一段断了。按数据流排查最有效先确认当前用户是不是真的没有行为记录再确认相似度计算时两个用户的偏好向量有没有共同元素最后确认推荐函数是否把候选景点全部过滤掉了。我实际遇到最多的坑是用户ID和景点ID的类型不一致。数据库里查出来的是int但造数脚本或接口传参时用了字符串字典匹配不上计算结果自然为空。构建数据映射时统一强制转int就能解决user_item_dict.setdefault(int(user_id), {})[int(scene_id)] weight统一类型之后再计算绝大概率能解决空结果问题。7.2 可视化图表不出来图表不出来九成是数据格式或容器高度问题。ECharts的数据格式很严格柱状图要求data是数组饼图要求每个元素带name和value。先用浏览器控制台把接口返回打印出来对照文档检查格式比瞎猜快得多。另一个隐蔽问题是容器div没有显式高度或高度为0ECharts初始化后没有渲染空间。解决办法是给图表容器固定高度并确保在页面生命周期完全结束后再初始化。如果页面同时渲染多个图表建议写一个公共初始化函数统一传入容器ID和option减少重复代码。7.3 迁移冲突和字段修改问题开发中改model是常事改完再makemigrations时经常遇到“没有检测到变化”或迁移依赖冲突。常见原因是原先的迁移文件已经落库但模型字段与迁移文件不一致。处理办法是如果数据库可以重置删除对应app的migrations目录下除__init__.py之外的文件重新执行makemigrations和migrate如果已有重要数据必须先备份再处理。这里也提醒一下别在生产环境或交了初稿后还随意改表结构。毕业设计虽然评审压力没有生产环境大但多次删库会造成截图和论文里的字段对不上最后返工的都是自己。7.4 问题排查速查表现象常见原因排查方向推荐结果为空ID类型不一致、无行为数据检查user_item_dict、确认行为记录图表空白容器高度为0、数据格式不符检查CSS高度、打印接口JSON页面中文乱码ensure_ascii未关闭JsonResponse加json_dumps_params后台没有表app未注册检查INSTALLED_APPS相似度全为0偏好向量无交集检查行为权重是否合并成功这张表基本覆盖了我在跑通项目时遇到的大部分问题。保存下来不管你是自己改代码还是复现别人的源码都能省很多时间。8. 我实际跑完这套系统的体会完整跑完这个项目后我最大的感受是毕业设计项目的核心不在于代码量多豪华而在于每个模块之间有没有一条清晰的逻辑线。推荐算法哪怕简单只要动机讲得清、结果跑得通、测试做得完整就是好模块。可视化图表哪怕花哨如果回答不了任何一个业务问题也只是纯粹的视觉堆砌。最后再给一个答辩加分的小技巧建议在论文里加一组“邻居数量K对推荐效果影响”的对比实验。把K5、10、20时生成的推荐结果放到一张表里指出K太小时覆盖不足K太大时结果会偏向热门景点。实现起来只需要在推荐函数里留一个参数跑三组数据即可但带来的答辩素材非常值。如果之后想再扩展还可以把协同过滤升级成混合推荐用户行为充足时用协同过滤行为不足时基于景点类型、标签匹配用户画像。等系统稳定了甚至可以在推荐结果基础上调用大模型接口自动生成一句简短的旅行推荐文案。这些都是有实际价值的进阶方向不过先保证当前链路稳定再谈扩展才靠谱。

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

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

免费获取报价 →
↑