基于Python的网上厨房美食推荐系统 - 技术分享博客
📋 目录
🎯 项目概述
项目背景
随着生活节奏的加快,越来越多的人开始关注美食制作,但面对海量的菜谱信息,用户往往难以找到适合自己的菜谱。本项目旨在构建一个智能的美食推荐系统,通过个性化推荐算法,帮助用户快速找到心仪的菜谱。
项目目标
- 构建完整的菜谱管理和推荐系统
- 实现基于用户行为的个性化推荐
- 提供丰富的数据统计和可视化功能
- 支持用户社交互动功能
主要功能
- 🍳 菜谱管理:支持按类型和食材分类浏览菜谱
- ⭐ 智能推荐:基于协同过滤算法的个性化推荐
- 👥 用户系统:完整的用户注册、登录、个人中心功能
- 💬 社交互动:评论、收藏、关注等社交功能
- 📊 数据统计:丰富的统计分析和可视化展示
- 🔧 后台管理:完善的后台管理系统
项目源码
码界筑梦坊各大平台同名 欢迎咨询~
🛠️ 技术栈
后端技术
- Flask 2.3.3 - 轻量级Web框架
- SQLAlchemy 2.0.21 - ORM数据库操作
- Flask-SQLAlchemy 3.0.5 - Flask ORM扩展
- Flask-Login 0.6.3 - 用户认证管理
- Flask-Migrate 4.0.5 - 数据库迁移
- Flask-WTF 1.1.1 - 表单处理
- WTForms 3.0.1 - 表单验证
数据库
- MySQL - 主数据库
- SQLAlchemy - ORM框架
数据分析与机器学习
- NumPy 1.24.3 - 数值计算
- Pandas 2.0.3 - 数据分析
- Scikit-learn 1.3.0 - 机器学习算法
数据可视化
- Matplotlib 3.7.2 - 基础绘图
- Seaborn 0.12.2 - 统计图表
其他工具
- Pillow 10.0.0 - 图像处理
- Requests 2.31.0 - HTTP请求
- Python-dotenv 1.0.0 - 环境变量管理
💻 项目展示
🏗️ 系统架构
目录结构
网上厨房美食推荐系统/
├── app/ # 应用主目录
│ ├── __init__.py # 应用初始化
│ ├── models/ # 数据模型
│ │ ├── user.py # 用户模型
│ │ ├── recipe.py # 菜谱模型
│ │ ├── food.py # 食材模型
│ │ ├── category.py # 分类模型
│ │ ├── comment.py # 评论模型
│ │ ├── favorite.py # 收藏模型
│ │ └── ...
│ ├── routes/ # 路由控制器
│ │ ├── main.py # 主页路由
│ │ ├── auth.py # 认证路由
│ │ ├── user.py # 用户路由
│ │ ├── food.py # 食材路由
│ │ ├── recipe.py # 菜谱路由
│ │ ├── recommend.py # 推荐路由
│ │ ├── stats.py # 统计路由
│ │ └── admin.py # 管理路由
│ ├── templates/ # 模板文件
│ │ ├── base.html # 基础模板
│ │ ├── main/ # 主页模板
│ │ ├── auth/ # 认证模板
│ │ ├── user/ # 用户模板
│ │ ├── food/ # 食材模板
│ │ ├── recipe/ # 菜谱模板
│ │ ├── stats/ # 统计模板
│ │ └── admin/ # 管理模板
│ ├── static/ # 静态资源
│ │ ├── css/ # 样式文件
│ │ ├── js/ # JavaScript文件
│ │ └── images/ # 图片资源
│ ├── forms/ # 表单类
│ ├── services/ # 业务逻辑
│ ├── utils/ # 工具函数
│ └── config/ # 配置文件
├── data/ # 数据文件
├── migrations/ # 数据库迁移
├── uploads/ # 上传文件
├── requirements.txt # 依赖包
├── config.py # 配置文件
├── run.py # 启动文件
└── README.md # 项目说明
架构设计
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 前端界面 │ │ Flask应用 │ │ 数据库 │
│ (Templates) │◄──►│ (Routes) │◄──►│ (MySQL) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ 业务逻辑 │
│ (Services) │
└─────────────────┘
│
▼
┌─────────────────┐
│ 推荐算法 │
│ (ML/Numpy) │
└─────────────────┘
🔧 核心功能实现
1. 用户系统
python
# app/models/user.py
class User(UserMixin, db.Model):
"""用户模型"""
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(255), unique=True, nullable=False)
password = db.Column(db.String(255), nullable=False)
email = db.Column(db.String(255), unique=True, nullable=False)
avatar = db.Column(db.String(255), default='/static/images/default-avatar.png')
description = db.Column(db.Text)
is_admin = db.Column(db.Boolean, default=False)
last_login = db.Column(db.DateTime)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
# 关系定义
food_favorites = db.relationship('FoodFavorite', back_populates='user', lazy='dynamic')
recipe_favorites = db.relationship('RecipeFavorite', back_populates='user', lazy='dynamic')
def set_password(self, password):
"""设置密码"""
self.password = generate_password_hash(password)
def check_password(self, password):
"""验证密码"""
return check_password_hash(self.password, password)
2. 菜谱模型
python
# app/models/recipe.py
class Recipe(db.Model):
"""菜谱模型"""
__tablename__ = 'recipes'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(200), nullable=False, comment='菜谱标题')
description = db.Column(db.Text, comment='菜谱描述')
main_image = db.Column(db.String(500), comment='主图URL')
category_id = db.Column(db.Integer, db.ForeignKey('ingredient_categories.id'), nullable=False)
ingredients = db.Column(db.JSON, comment='食材列表')
steps = db.Column(db.JSON, comment='步骤列表')
collect_count = db.Column(db.Integer, default=0, comment='收藏数')
comment_count = db.Column(db.Integer, default=0, comment='评论数')
# 关联关系
category = db.relationship('IngredientCategory', back_populates='recipes', lazy='joined')
comments = db.relationship('RecipeComment', back_populates='recipe', lazy='dynamic')
favorites = db.relationship('RecipeFavorite', back_populates='recipe', lazy='dynamic')
3. 应用初始化
python
# app/__init__.py
def create_app(config_name='default'):
"""创建Flask应用"""
app = Flask(__name__)
# 加载配置
app.config.from_object(config[config_name])
config[config_name].init_app(app)
# 初始化扩展
db.init_app(app)
migrate.init_app(app, db)
login_manager.init_app(app)
# 注册蓝图
from app.routes import main, auth, user, food, recipe, recommend, stats, admin
app.register_blueprint(main.bp)
app.register_blueprint(auth.bp)
app.register_blueprint(user.bp)
app.register_blueprint(food.bp)
app.register_blueprint(recipe.bp)
app.register_blueprint(recommend.bp, url_prefix='/recommend')
app.register_blueprint(stats.bp)
app.register_blueprint(admin.bp)
return app
🗄️ 数据库设计
核心表结构
用户表 (users)
sql
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
avatar VARCHAR(255) DEFAULT '/static/images/default-avatar.png',
description TEXT,
is_admin BOOLEAN DEFAULT FALSE,
last_login DATETIME,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
菜谱表 (recipes)
sql
CREATE TABLE recipes (
id INT PRIMARY KEY AUTO_INCREMENT,
url VARCHAR(500) NOT NULL,
title VARCHAR(200) NOT NULL,
description TEXT,
main_image VARCHAR(500),
category_id INT NOT NULL,
author_name VARCHAR(100),
author_avatar VARCHAR(500),
ingredients JSON,
steps JSON,
collect_count INT DEFAULT 0,
comment_count INT DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (category_id) REFERENCES ingredient_categories(id)
);
收藏表 (recipe_favorites)
sql
CREATE TABLE recipe_favorites (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
recipe_id INT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id),
FOREIGN KEY (recipe_id) REFERENCES recipes(id),
UNIQUE KEY unique_user_recipe (user_id, recipe_id)
);
数据库关系图
users (用户表)
├── recipe_favorites (菜谱收藏)
├── food_favorites (食材收藏)
├── recipe_comments (菜谱评论)
├── food_comments (食材评论)
└── logs (用户日志)
recipes (菜谱表)
├── recipe_favorites (收藏关系)
├── recipe_comments (评论关系)
└── logs (浏览日志)
foods (食材表)
├── food_favorites (收藏关系)
└── food_comments (评论关系)
ingredient_categories (分类表)
└── recipes (菜谱分类)
🤖 推荐算法
协同过滤算法实现
python
# app/routes/recommend.py
def get_recipe_recommendations(user_id, limit=10):
"""获取菜谱推荐 - 基于协同过滤"""
try:
# 获取所有用户收藏
favorites = RecipeFavorite.query.all()
# 构建用户-菜谱矩阵
user_recipe_dict = defaultdict(set)
for fav in favorites:
user_recipe_dict[fav.user_id].add(fav.recipe_id)
# 获取当前用户的收藏
user_favorites = user_recipe_dict.get(user_id, set())
if not user_favorites:
return []
# 计算用户相似度 (Jaccard相似度)
user_similarities = {}
for other_user_id, other_favorites in user_recipe_dict.items():
if other_user_id == user_id:
continue
intersection = len(user_favorites & other_favorites)
union = len(user_favorites | other_favorites)
if union > 0:
similarity = intersection / union
user_similarities[other_user_id] = similarity
# 获取最相似的用户
similar_users = sorted(user_similarities.items(),
key=lambda x: x[1], reverse=True)[:5]
# 获取推荐菜谱
recommended_recipes = set()
for similar_user_id, _ in similar_users:
similar_user_favorites = user_recipe_dict[similar_user_id]
# 只推荐当前用户未收藏的菜谱
new_recipes = similar_user_favorites - user_favorites
recommended_recipes.update(new_recipes)
# 获取菜谱详情
recipes = Recipe.query.filter(Recipe.id.in_(recommended_recipes))\
.order_by(desc(Recipe.collect_count))\
.limit(limit)\
.all()
return recipes
except Exception as e:
logger.error(f"获取菜谱推荐失败: {str(e)}", exc_info=True)
return []
算法特点
- 协同过滤:基于用户行为的相似性推荐
- Jaccard相似度:计算用户收藏菜谱的相似度
- 冷启动处理:新用户无收藏时返回热门菜谱
- 实时更新:用户行为变化时推荐结果实时更新
📊 数据可视化
统计功能实现
python
# app/routes/stats.py
@bp.route('/api/stats/foods')
def food_stats():
"""食材统计数据"""
# 食材类型统计
food_types = db.session.query(
Food.food_type,
func.count(Food.id).label('count')
).group_by(Food.food_type).all()
# 收藏数TOP10食材
top_favorites = Food.query.order_by(Food.favorite_count.desc()).limit(10).all()
# 食材收藏趋势(最近7天)
seven_days_ago = datetime.now() - timedelta(days=7)
daily_favorites = db.session.query(
func.date(FoodFavorite.created_at).label('date'),
func.count(FoodFavorite.id).label('count')
).filter(FoodFavorite.created_at >= seven_days_ago)\
.group_by('date').order_by('date').all()
return jsonify({
'food_types': [{'type': t[0], 'count': t[1]} for t in food_types if t[0]],
'top_favorites': [{'title': f.title, 'count': f.favorite_count} for f in top_favorites],
'daily_favorites': [{'date': d[0].strftime('%m-%d'), 'count': d[1]} for d in daily_favorites]
})
可视化图表类型
- 饼图:食材类型分布、菜谱分类分布
- 柱状图:热门菜谱排行、用户活跃度
- 折线图:收藏趋势、用户注册趋势
- 散点图:菜谱热度分布
🚀 部署与优化
性能优化
-
数据库优化
- 建立合适的索引
- 使用连接查询减少查询次数
- 实现分页查询
-
缓存策略
- 热门菜谱缓存
- 用户推荐结果缓存
- 统计数据缓存
-
前端优化
- 图片懒加载
- 静态资源压缩
- 异步加载数据
部署方案
bash
# 安装依赖
pip install -r requirements.txt
# 初始化数据库
flask db init
flask db migrate
flask db upgrade
# 启动应用
python run.py
✨ 项目特色
1. 智能推荐
- 基于协同过滤的个性化推荐
- 支持冷启动处理
- 实时更新推荐结果
2. 丰富的数据分析
- 多维度数据统计
- 实时数据可视化
- 用户行为分析
3. 完整的用户系统
- 用户注册登录
- 个人中心管理
- 社交互动功能
4. 响应式设计
- 适配多种设备
- 现代化UI设计
- 良好的用户体验
📈 总结与展望
项目成果
- 完整的菜谱推荐系统:实现了从数据采集到推荐展示的完整流程
- 智能推荐算法:基于协同过滤的个性化推荐,提高了用户满意度
- 丰富的数据分析:多维度统计和可视化,为运营决策提供支持
- 良好的用户体验:响应式设计和现代化UI,提升了用户粘性
技术亮点
- Flask + SQLAlchemy:轻量级但功能强大的Web框架
- NumPy + Pandas:高效的数据处理和分析
- Scikit-learn:机器学习算法的应用
- 协同过滤算法:个性化推荐的核心技术
未来展望
- 算法优化:引入深度学习模型,提升推荐精度
- 功能扩展:增加菜谱评分、营养分析等功能
- 性能提升:引入Redis缓存,提升系统响应速度
- 移动端适配:开发移动端应用,提升用户体验
技术收获
通过本项目的开发,深入学习了:
- Flask Web开发框架的使用
- 数据库设计和ORM操作
- 机器学习算法在实际项目中的应用
- 数据可视化和统计分析
- 前后端分离开发模式
这个项目不仅是一个功能完整的美食推荐系统,更是对现代Web开发技术栈的全面实践,为后续的技术学习和项目开发奠定了坚实的基础。
本文档详细介绍了基于Python的网上厨房美食推荐系统的技术实现,包括系统架构、核心功能、推荐算法、数据可视化等各个方面。项目采用Flask + SQLAlchemy + NumPy + Pandas等技术栈,实现了完整的菜谱推荐和管理功能。
源码获取:[码界筑梦坊各平台同名]