1. 项目背景与核心价值
海南作为国内热门旅游目的地,每年吸引数千万游客。但面对庞大的景区、酒店、餐饮等旅游资源,游客常常陷入"选择困难症"——攻略信息过时、个性化推荐缺失、行程规划不合理等问题普遍存在。这正是我们开发这套旅游推荐系统的初衷:通过数据挖掘技术,从海量旅游数据中提取有效信息,为游客提供精准的个性化推荐。
这个毕业设计项目完整实现了从数据采集、算法设计到系统部署的全流程。与市面上简单的信息展示系统不同,我们重点解决了三个行业痛点:
- 冷启动问题:新用户缺乏历史行为数据时如何推荐
- 多维度融合:如何平衡景点热度、用户偏好、季节因素等不同维度
- 实时性要求:如何快速响应最新评价数据和突发情况(如景区临时关闭)
提示:系统采用SpringBoot+Vue前后端分离架构,推荐算法部分使用Python实现,通过REST API进行交互。这种混合架构既保证了系统性能,又便于算法迭代优化。
2. 系统架构与技术选型
2.1 整体架构设计
系统采用典型的三层架构:
表示层:Vue3 + Element Plus (Web前端) 业务层:Spring Boot 2.7 (Java后端) 数据层:MySQL 8.0 + Redis (数据存储与缓存)推荐引擎作为独立模块运行,通过Flask提供API服务。这种解耦设计使得算法团队可以独立迭代模型,不影响主系统运行。
2.2 关键技术选型解析
数据采集方案对比:
| 方案 | 优点 | 缺点 | 最终选择 |
|---|---|---|---|
| 爬虫采集 | 数据实时性强 | 法律风险高 | × |
| 公开API | 稳定合规 | 字段受限 | √ (选用美团/携程API) |
| 人工录入 | 质量可控 | 效率低下 | 仅作补充 |
推荐算法选型:
# 混合推荐算法核心逻辑 def hybrid_recommend(user_id, current_location): # 基于内容的推荐 content_based = content_filtering(user_preferences[user_id]) # 协同过滤推荐 cf_rec = collaborative_filtering(user_id) # 实时上下文过滤(地理位置/天气等) context_rec = context_aware_filter(current_location) # 加权融合 return 0.4*content_based + 0.3*cf_rec + 0.3*context_rec选择混合推荐而非单一算法,实测准确率提升27%(通过A/B测试验证)。特别加入了海南特有的"台风季规避"因子,在7-9月自动降低沿海景点权重。
3. 核心功能实现细节
3.1 旅游数据ETL流程
数据质量直接决定推荐效果。我们设计了五步清洗流程:
- 去重处理:基于景点ID+时间戳建立唯一索引
- 异常值处理:删除评分>5分或<1分的明显错误数据
- 文本标准化:将"三亚湾/三亚湾海滩"等别名统一
- 情感分析:使用SnowNLP处理中文评价
- 特征增强:添加"亲子友好度"等衍生特征
-- 数据表示例结构 CREATE TABLE `scenic_spot` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `location` point NOT NULL SRID 4326, `tags` json DEFAULT NULL, -- 存储["海滩","亲子","网红"]等标签 `season_factor` json DEFAULT NULL, -- 各月份推荐权重 PRIMARY KEY (`id`), SPATIAL KEY `idx_location` (`location`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;3.2 推荐算法优化技巧
冷启动解决方案:
- 地域映射:新用户IP属地→推荐该省份游客常选景点
- 热门衰减:使用时间衰减因子,避免老牌景点长期霸榜
def time_decay(score, days): return score * (0.9 ** (days/30)) # 每月衰减10%
性能优化实践:
- 预计算:每日凌晨批量生成各景点的相似度矩阵
- 多级缓存:
- Redis缓存热门推荐结果(有效期2小时)
- 本地缓存用户最近一次推荐(有效期30分钟)
4. 系统部署实战指南
4.1 环境准备清单
硬件要求:
- 最低配置:2核CPU/4GB内存/50GB存储(仅演示)
- 生产建议:4核CPU/8GB内存/SSD存储
软件依赖:
# 后端服务 JDK 17 MySQL 8.0 Redis 6.2 # 推荐引擎 Python 3.8 Flask 2.0 scikit-learn 1.04.2 关键配置项说明
application-prod.yml 核心配置:
recommend: api-url: http://localhost:5000/api timeout: 3000ms fallback: true # 启用降级策略(当推荐服务不可用时返回热门列表) spring: redis: host: 127.0.0.1 password: ${REDIS_PASSWORD:}注意:必须设置合理的连接超时和降级策略,避免推荐服务故障导致整个系统不可用。
5. 典型问题排查实录
5.1 推荐结果重复问题
现象:部分用户反馈连续收到相同推荐排查过程:
- 检查缓存有效期配置(正常)
- 发现新注册用户未设置初始偏好标签
- 算法过度依赖热门景点列表
解决方案:
// 在用户服务中添加默认标签 public void initUserTags(Long userId) { String ipRegion = getIpRegion(userId); List<String> defaultTags = regionTagMapping.get(ipRegion); userTagService.batchAdd(userId, defaultTags); }5.2 高并发下的性能瓶颈
压测数据:
| 并发量 | 平均响应时间 | 错误率 |
|---|---|---|
| 500 | 320ms | 0% |
| 1000 | 1200ms | 5% |
| 2000 | 超时 | 98% |
优化措施:
- 引入Guava缓存本地热门景点ID列表
- 对推荐结果进行分页预加载
- 使用Nginx限制单个IP的请求频率
6. 项目扩展方向
在实际使用中,我们发现几个有价值的改进点:
实时反馈闭环:当前用户对推荐结果的点击/收藏行为需要次日才能影响推荐,可引入Kafka实现分钟级更新
多模态推荐:现有系统主要处理结构化数据,后续可加入:
- 景点图片分析(使用CNN提取视觉特征)
- 语音评价处理(ASR+情感分析)
行程规划优化:现有推荐是单点推荐,可加入:
def route_optimization(spots): # 基于地理位置和开放时间的旅行商问题变种 return genetic_algorithm(spots)
这个项目最让我意外的发现是:在A/B测试中,加入简单的"本周避雷"提示(基于近期差评)使点击率提升了41%。这说明游客对负面信息的敏感度远高于我们的预期。