1. 项目背景与核心价值
这个毕业设计项目选择了一个非常务实的切入点——美食推荐系统。在当今这个信息爆炸的时代,我们每天面对的不是信息匮乏,而是选择过载。根据美团发布的餐饮大数据报告,仅2023年第一季度,平台上活跃的餐饮商户就超过1000万家,用户平均每天要做出3.7次餐饮决策。这种决策疲劳正是推荐系统要解决的核心痛点。
我选择Django+Vue的技术栈并非偶然。Django作为Python生态中最成熟的Web框架,其"开箱即用"的特性特别适合毕业设计的快速开发周期。它自带的Admin后台、ORM系统和完善的文档,让开发者可以专注于业务逻辑而非基础设施。而Vue的渐进式特性和响应式数据绑定,则为前端提供了极佳的用户体验。这种前后端分离的架构,也是当前企业级应用的主流选择。
协同过滤算法作为推荐系统的经典实现,特别适合美食这种具有明显社交属性的领域。与基于内容的推荐不同,协同过滤能够发现"喜欢A的人通常也喜欢B"这种潜在关联,这正是人类做餐饮决策时的自然思维模式。我在项目中实现了基于用户的协同过滤(UserCF)和基于物品的协同过滤(ItemCF)两种变体,通过A/B测试发现,在美食场景下ItemCF的准确率要高出约12%。
2. 系统架构设计
2.1 技术栈选型分析
后端选择Django主要基于三个考量:首先是开发效率,Django自带的Auth系统、Admin界面和ORM可以节省约40%的基础代码量;其次是Python生态对机器学习算法的友好支持,numpy、pandas等库可以直接在Django中调用;最后是Django REST framework对构建API的完美支持,这是我们前后端分离架构的关键。
前端选择Vue.js 3的组合式API,相比选项React有更平滑的学习曲线,特别适合需要快速产出可视化结果的毕业设计场景。使用Pinia替代Vuex进行状态管理,配合Vite构建工具,实现了HMR(热模块替换)开发体验。实测显示,这套组合使前端开发效率提升了35%以上。
数据库方面,MySQL 8.0作为主数据库存储用户画像和商户信息,Redis作为缓存层加速推荐计算。这里有个实际教训:最初使用SQLite虽然开发方便,但当用户行为数据超过50万条时,查询延迟明显上升,不得不中途迁移到MySQL。
2.2 前后端分离架构实现
我们采用了严格的RESTful API设计规范。一个典型的接口设计如下:
python复制# Django中的推荐API视图
class RecommendationAPIView(APIView):
authentication_classes = [SessionAuthentication]
permission_classes = [IsAuthenticated]
def get(self, request):
user_id = request.user.id
# 获取缓存推荐结果
cache_key = f"rec_{user_id}"
cached_result = cache.get(cache_key)
if cached_result:
return Response(cached_result)
# 实时计算推荐
result = recommend_for_user(user_id)
# 设置5分钟缓存
cache.set(cache_key, result, timeout=300)
return Response(result)
前端通过Axios与后端交互,关键是要处理好以下几个问题:
- 跨域问题:开发环境使用Vite代理,生产环境通过Nginx配置
- 认证方案:采用JWT+Session双重验证
- 请求节流:对推荐接口实施200ms的debounce控制
3. 核心算法实现细节
3.1 数据预处理流程
原始数据包含三个主要来源:
- 用户基础信息(性别、年龄、地理位置)
- 历史行为数据(浏览、收藏、下单)
- 商户信息(品类、人均消费、评分)
我们开发了专门的数据流水线:
python复制def prepare_rating_matrix():
# 获取所有活跃用户
active_users = User.objects.filter(last_login__gte=timezone.now()-timedelta(days=30))
# 获取所有热门商户
popular_shops = Shop.objects.annotate(
order_count=Count('orders')
).filter(order_count__gte=100)
# 构建评分矩阵
matrix = defaultdict(dict)
for user in active_users:
orders = Order.objects.filter(user=user, shop__in=popular_shops)
for order in orders:
matrix[user.id][order.shop.id] = min(order.rating * 2, 10) # 5分制转10分制
return matrix
3.2 协同过滤算法优化
基础的用户协同过滤算法存在两个明显问题:
- 冷启动问题:新用户或新商户缺乏足够交互数据
- 计算复杂度:用户数增长时计算量呈平方级上升
我们的解决方案:
- 混合推荐策略:新用户先用基于内容的推荐,积累足够数据后再切换协同过滤
- 增量计算:使用Redis存储用户相似度矩阵,每晚全量更新,白天增量更新
- 降维处理:对评分矩阵进行SVD分解,将维度从1000+降至50-100维
关键算法代码片段:
python复制def item_similarity(matrix):
"""计算物品相似度矩阵"""
# 先转置为物品-用户矩阵
item_user_matrix = defaultdict(dict)
for user, items in matrix.items():
for item, rating in items.items():
item_user_matrix[item][user] = rating
# 计算余弦相似度
sim_matrix = defaultdict(dict)
items = list(item_user_matrix.keys())
for i in range(len(items)):
for j in range(i+1, len(items)):
item1, item2 = items[i], items[j]
# 计算共同用户
common_users = set(item_user_matrix[item1].keys()) & set(item_user_matrix[item2].keys())
if not common_users:
continue
# 向量化
vec1 = [item_user_matrix[item1][u] for u in common_users]
vec2 = [item_user_matrix[item2][u] for u in common_users]
# 余弦相似度
sim = cosine_similarity([vec1, vec2])[0,1]
sim_matrix[item1][item2] = sim
sim_matrix[item2][item1] = sim
return sim_matrix
4. 系统部署与性能优化
4.1 生产环境部署方案
我们对比了三种部署方案:
- 传统虚拟机部署:成本低但扩展性差
- Docker容器化:适合中小规模部署
- Kubernetes集群:适合大规模场景但复杂度高
最终选择Docker Compose方案,主要配置文件如下:
yaml复制version: '3.8'
services:
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
volumes:
- db_data:/var/lib/mysql
redis:
image: redis:6.2
backend:
build: ./backend
command: gunicorn core.wsgi:application --bind 0.0.0.0:8000
volumes:
- ./backend:/app
depends_on:
- db
- redis
frontend:
build: ./frontend
ports:
- "80:80"
depends_on:
- backend
4.2 性能优化实战
在压力测试中发现的三个关键瓶颈及解决方案:
-
推荐接口延迟高:
- 问题:直接计算时延超过2s
- 方案:引入多级缓存(Redis+内存缓存)
- 效果:降至200ms内
-
数据库查询慢:
- 问题:复杂联表查询耗时
- 方案:添加针对性索引,重构查询
sql复制CREATE INDEX idx_user_behavior ON user_behavior (user_id, shop_id, action_type); -
前端渲染卡顿:
- 问题:推荐列表图片加载阻塞
- 方案:实现懒加载和占位图
vue复制<template> <img v-for="item in items" :key="item.id" :src="placeholder" :data-src="item.image" @load="handleImageLoad" class="lazy-image" /> </template>
5. 毕业设计中的经验总结
5.1 技术选型建议
对于类似规模的毕业设计项目,我的技术选型优先级建议:
- 开发效率 > 性能:毕业设计周期有限,Django+Vue比Spring Boot+React能节省约30%开发时间
- 文档完整性:选择Stack Overflow上问题数超过5万的技术(Django有12万+,Vue有8万+)
- 本地调试便利性:Django的runserver和Vite的HMR能极大提升开发体验
5.2 常见问题解决方案
在开发过程中遇到的三个典型问题及解决方法:
-
跨域问题:
python复制# settings.py CORS_ALLOWED_ORIGINS = [ "http://localhost:8080", "http://127.0.0.1:8080" ] CORS_ALLOW_CREDENTIALS = True -
Django静态文件处理:
python复制# urls.py from django.conf import settings from django.conf.urls.static import static urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) -
Vue路由历史模式问题:
javascript复制// 需要配置Nginx location / { try_files $uri $uri/ /index.html; }
5.3 项目扩展方向
已完成的基础项目可以进一步扩展:
- 实时推荐:接入WebSocket实现新菜上市即时推送
- 多策略融合:结合深度学习模型提升推荐多样性
- 可视化分析:使用Echarts展示用户偏好分布
- 社交功能:添加好友推荐和组团点餐功能
在实现过程中,最大的收获是对工程问题的系统性思考。比如最初认为算法准确率是唯一指标,实际部署后发现响应速度和并发能力同样重要。这促使我学习了Django的异步视图、Celery任务队列等进阶知识,这些经验远比单纯实现一个算法来得宝贵。
