1. 项目概述:基于协同过滤的智能饮食规划系统
这个项目是我去年带队开发的一个微信小程序应用,核心目标是通过算法帮助用户实现科学减脂。市面上大多数饮食类App要么是固定食谱,要么需要人工配置,而我们采用协同过滤算法实现了真正的个性化推荐。简单来说,系统会像营养师一样,根据你的身体数据和饮食偏好,每天给出不同的菜谱建议。
技术栈选择上,我们采用微信小程序作为前端载体(用户使用门槛最低),后端用Spring Boot构建微服务,算法层用Python实现协同过滤模型,数据存储使用MySQL+Redis组合。特别要说明的是,这个项目不是简单的"推荐系统+饮食"的拼接,我们在算法层做了大量适配改造:
- 传统协同过滤只考虑用户评分,我们引入了热量差、营养均衡等健康因子
- 物品相似度计算时,除了常规的共现分析,还加入了食材属性(GI值、蛋白质含量等)
- 开发了动态权重机制,用户执行效果越好,健康因子的权重会逐步提高
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心算法设计解析
2.1 混合协同过滤模型架构
系统采用用户协同过滤(UserCF)和物品协同过滤(ItemCF)的混合模式,这是经过AB测试验证的最优方案。具体实现上有个关键设计:早餐推荐以ItemCF为主(考虑食材搭配),正餐推荐以UserCF为主(考虑用餐习惯)。
算法流程如下:
- 用户注册时填写基础信息(年龄、性别、BMI等)和目标(如月减3kg)
- 系统计算每日建议摄入热量 = 基础代谢率 × 活动系数 - 500kcal(安全减脂阈值)
- 初始化推荐时采用基于内容的过滤(Content-based),建立用户初始画像
- 随着使用记录积累,逐步过渡到协同过滤模式
2.2 相似度计算优化
传统余弦相似度在饮食领域存在明显不足,我们改进的计算公式包含三个维度:
code复制sim(u,v) = α*评分相似度 + β*身体特征相似度 + γ*饮食目标相似度
其中:
- 评分相似度:用户对共同食物的打分差异
- 身体特征相似度:BMI差、基础代谢率比等
- 饮食目标相似度:减脂/增肌/维持等目标的匹配度
参数设置经验:
- 新用户:α=0.3, β=0.5, γ=0.2(侧重客观条件)
- 老用户:α=0.6, β=0.2, γ=0.2(侧重主观偏好)
3. 系统实现关键点
3.1 数据层设计
数据库主要包含以下几张核心表:
| 表名 | 字段示例 | 说明 |
|---|---|---|
| user_profile | age, gender, height, weight, target_weight | 用户画像基础 |
| food_nutrition | food_id, calories, protein, fat, carbs, gi_value | 食物营养库 |
| user_behavior | user_id, food_id, rating, meal_type, timestamp | 用户行为日志 |
| similarity_matrix | user1, user2, similarity_score | 用户相似度预计算 |
特别要注意的是user_behavior表的设计:
- rating不仅包含显式评分(1-5星),还包含隐式反馈(食用次数、剩餐量等)
- meal_type字段区分早/午/晚餐,这是实现分时段推荐的关键
3.2 推荐服务实现
核心Java代码逻辑(简化版):
java复制// 协同过滤服务类
@Service
public class DietRecommendService {
@Autowired
private UserBehaviorMapper behaviorMapper;
public List<Food> recommend(String userId, MealType mealType) {
// 1. 获取用户画像
UserProfile user = getUserProfile(userId);
// 2. 根据用餐类型选择算法侧重
double itemCFWeight = mealType == MealType.BREAKFAST ? 0.7 : 0.3;
// 3. 并行计算两种推荐结果
CompletableFuture<List<Food>> userCF = CompletableFuture.supplyAsync(
() -> userCFRecommend(userId, mealType));
CompletableFuture<List<Food>> itemCF = CompletableFuture.supplyAsync(
() -> itemCFRecommend(userId, mealType));
// 4. 合并结果
return mergeRecommendations(
userCF.get(),
itemCF.get(),
itemCFWeight);
}
private List<Food> userCFRecommend(String userId, MealType type) {
// 实现用户协同过滤逻辑
}
private List<Food> itemCFRecommend(String userId, MealType type) {
// 实现物品协同过滤逻辑
}
}
3.3 微信小程序前端优化
在小程序端我们解决了几个关键问题:
- 加载性能:采用分页加载推荐结果,首屏只显示3个选项
- 交互设计:开发了独特的"摇一摇换菜"功能,解决推荐不满意的问题
- 数据同步:利用微信云开发实现离线记录,网络恢复后自动同步
4. 踩坑实录与解决方案
4.1 冷启动问题
初期新用户推荐质量很差,我们通过以下方案改善:
- 构建了包含200+基础食谱的默认库
- 开发了"快速测评"功能(10道选择题建立初始画像)
- 引入社交属性,允许查看相似用户的公开食谱
4.2 数据稀疏性
用户-食物评分矩阵非常稀疏(平均填充度<5%),我们采用的解决方案:
- 使用SVD++算法进行矩阵分解
- 对没有评分记录的食物,用营养属性计算替代相似度
- 设计激励体系鼓励用户评分(如积分兑换会员)
4.3 实时性挑战
传统协同过滤需要定期全量更新相似度矩阵,我们改进的方案:
- 采用增量更新策略,每晚只计算新增用户/行为
- 对核心用户(日活>3次)实行实时微调
- 使用Redis缓存最近7天的热门食物组合
5. 效果评估与优化方向
经过3个月AB测试,关键指标对比如下:
| 指标 | 传统食谱App | 本系统 |
|---|---|---|
| 7日留存率 | 28% | 63% |
| 目标达成率 | 41% | 79% |
| 平均使用时长 | 2.1分钟 | 8.7分钟 |
未来优化方向:
- 结合LSTM模型预测饮食偏好变化
- 增加图像识别功能(拍照记录饮食)
- 开发家庭版推荐模式(协调多人需求)
这个项目给我的最大启示是:技术方案必须贴合实际场景。我们迭代了5个版本才找到算法参数的最佳平衡点,核心就是要在个性化与科学性之间找到最佳结合点。对于想尝试类似项目的开发者,建议先从小的饮食类别(如早餐)做起,逐步扩展推荐维度。
