毕业设计实战:基于协同过滤算法的个性化智能体育商品推荐系统设计与实现全攻略
在开发“基于协同过滤算法的个性化智能体育商品推荐系统”毕业设计时,曾因“推荐算法与商品库存数据脱节”踩过关键坑——初期未设计清晰的用户行为记录机制和推荐算法联动,导致用户浏览、购买、收藏等行为数据未能有效参与推荐计算、推荐结果中包含已售罄商品、冷启动用户无法获得有效推荐,耗费5天重构推荐模块、引入用户行为权重机制和冷启动推荐策略才解决问题📝。基于此次实战经验,本文精简拆解核心开发流程,附避坑要点与实操细节,为同类毕设提供可落地的实施参考。
一、需求分析:聚焦推荐+商品双核心,避免功能冗余
部分同学易陷入“功能堆砌”误区,比如我曾耗时4天开发“体育赛事直播”模块,最终因偏离“商品推荐、用户行为采集、个性化推荐、订单管理”核心需求被导师要求删减。明确“用户浏览/购买/收藏商品→采集行为数据→协同过滤算法计算相似度→生成个性化推荐→用户下单购买”的业务闭环,是降低返工率的关键。
1. 核心角色与功能(精简版)
| 角色 | 核心功能 |
|---|---|
| 管理员 | 用户管理、商品分类管理、商品信息管理、交流论坛管理、留言板管理、订单管理、系统管理 |
| 用户 | 注册登录、商品浏览/搜索/收藏/评论/购买、查看个性化推荐、交流论坛互动、留言反馈、个人中心 |
2. 需求避坑要点
- 拒绝空想调研:邀请20名体育爱好者和5名商家模拟“用户浏览商品→收藏/购买→系统采集行为→推荐相似商品→用户下单”完整流程,基于“用户需要个性化推荐和库存提示”需求,增设“推荐理由说明”和“库存预警”模块,实用性远大于冗余的“体育赛事直播”;
- 明确约束条件:提前规定“商品编号自动生成(格式:TY+年月日+序号)”“用户行为数据(浏览、收藏、购买)权重不同”“推荐商品需过滤已售罄商品”“冷启动用户采用热门推荐策略”,为系统实现提供明确依据。
二、技术选型:稳定框架+协同过滤算法,新手可上手
前期曾尝试引入Redis缓存用户行为数据,因数据一致性难保证且学习成本高,调试耗时3天。最终确定“成熟框架+基于用户的协同过滤算法”组合:
| 技术工具 | 选型理由 | 避坑提醒 |
|---|---|---|
| Spring Boot 2.x + MyBatis-Plus | 快速开发,简化配置,高效实现CRUD和业务逻辑,声明式事务管理方便 | 事务注解@Transactional记得在Service层添加;用户行为记录和推荐计算异步处理 |
| Vue 2.x + ElementUI | 组件丰富,快速构建前后台界面,表格和表单组件好用 | 推荐商品卡片式展示;行为数据用标签记录 |
| MySQL 5.7 | 存储用户、商品、订单、行为等核心业务数据 | 行为权重字段用Integer类型;推荐结果缓存表设计 |
| 协同过滤算法 | 基于用户的协同过滤,实现个性化推荐 | 算法复杂度需优化;离线计算与实时推荐结合 |
三、数据库设计:业务关联清晰,支撑用户-商品-行为-推荐闭环
数据库设计直接影响推荐算法效果。前期因未设计“用户行为权重表”和“推荐结果缓存表”,导致算法计算效率低、推荐结果不稳定。
1. 核心表结构(精选12张表)
- 管理员表(users):id、username、password(MD5加密)、role、addtime;
- 用户表(yonghu):id、yonghuzhanghao(用户账号)、mima(密码)、yonghuxingming(用户姓名)、touxiang(头像)、xingbie(性别)、nianling(年龄)、shouji(手机)、money(余额)、addtime;
- 商品分类表(shangpinfenlei):id、shangpinfenlei(商品分类)、addtime;
- 商品信息表(shangpinxinxi):id、shangpinbianhao(商品编号)、shangpinmingcheng(商品名称)、shangpinfenlei(商品分类)、fengmian(封面)、guige(规格)、onelimittimes(单限)、alllimittimes(库存)、price(价格)、clicktime、addtime;
- 用户行为表(yonghuxingwei):id、yonghuzhanghao(用户账号)、shangpinid(商品id)、xingweileixing(行为类型:1浏览/2收藏/3购买)、xingweiquanzhong(行为权重)、xingweishijian(行为时间)、addtime;
- 购物车表(cart):id、tablename(商品表名)、userid(用户id)、goodid(商品id)、goodname(商品名称)、picture(图片)、buynumber(购买数量)、price(单价)、addtime;
- 订单表(orders):id、orderid(订单编号)、tablename(商品表名)、userid(用户id)、goodid(商品id)、goodname(商品名称)、picture(图片)、buynumber(购买数量)、price(价格)、total(总价格)、status(订单状态)、address(地址)、tel(电话)、consignee(收货人)、addtime;
- 地址表(address):id、userid(用户id)、address(地址)、name(收货人)、phone(电话)、isdefault(是否默认地址)、addtime;
- 收藏表(shoucang):id、userid、refid、tablename、name、picture、type(收藏类型)、addtime;
- 推荐结果缓存表(tuijiancache):id、yonghuzhanghao(用户账号)、tuijianshangpinids(推荐商品ID列表,JSON格式)、jisuanriqi(计算日期)、addtime;
- 交流论坛表(jiaoliuluntan):id、title(帖子标题)、content(帖子内容)、parentid、userid、username、avatarurl、isdone、addtime;
- 留言板表(liuyanban):id、userid、username、avatarurl、content、cpicture、reply、rpicture、addtime。
2. 关键业务SQL示例
示例SQL(查询用户行为数据用于推荐计算):
-- 查询用户对商品的偏好评分(行为加权)
SELECT
yonghuzhanghao,
shangpinid,
SUM(xingweiquanzhong) as score
FROM yonghuxingwei
GROUP BY yonghuzhanghao, shangpinid
ORDER BY yonghuzhanghao, score DESC
关键避坑:用户行为权重建议:浏览=1分,收藏=3分,购买=5分;推荐计算时需过滤已售罄商品;冷启动用户采用热门商品推荐。
四、核心功能实现:8大模块满足答辩需求
无需复杂功能,优先完成以下8个核心模块,其中协同过滤推荐算法是答辩重点。
1. 用户管理(基础模块)
- 核心逻辑:用户注册登录、个人信息维护、余额管理;
- 页面设计:注册登录界面;个人中心显示头像、姓名、手机、余额;
- 代码要点(用户注册):
public void addYonghu(Yonghu user) {
// 校验账号是否重复
LambdaQueryWrapper<Yonghu> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Yonghu::getYonghuzhanghao, user.getYonghuzhanghao());
if (yonghuMapper.selectCount(wrapper) > 0) {
throw new RuntimeException("账号已存在");
}
user.setMoney(0f);
user.setAddtime(new Date());
yonghuMapper.insert(user);
}
2. 商品信息管理(核心资源模块)
- 核心逻辑:管理员发布商品(名称、分类、规格、价格、库存)→用户浏览、搜索、收藏、购买;
- 页面设计:商品卡片式展示,显示名称、图片、价格、库存;详情页展示完整信息;
- 代码要点(商品发布与库存管理):
@Transactional
public void addShangpinxinxi(Shangpinxinxi product) {
// 生成商品编号
String bianhao = "TY" + new SimpleDateFormat("yyyyMMdd").format(new Date())
+ String.format("%04d", new Random().nextInt(10000));
product.setShangpinbianhao(bianhao);
product.setAddtime(new Date());
shangpinxinxiMapper.insert(product);
log.info("管理员发布了商品:{}", product.getShangpinmingcheng());
}
// 库存扣减
public void reduceStock(Long productId, int quantity) {
Shangpinxinxi product = shangpinxinxiMapper.selectById(productId);
if (product.getAlllimittimes() < quantity) {
throw new RuntimeException("库存不足");
}
product.setAlllimittimes(product.getAlllimittimes() - quantity);
shangpinxinxiMapper.updateById(product);
}
3. 用户行为采集(推荐数据基础)
- 核心逻辑:用户浏览、收藏、购买商品时自动记录行为数据→计算行为权重;
- 页面设计:后台不可见,前端自动采集;
- 代码要点(行为记录与权重计算):
@Async // 异步记录,不影响主流程
public void recordUserAction(String userAccount, Long productId, int actionType) {
// 行为权重映射:1浏览=1,2收藏=3,3购买=5
int weight = getActionWeight(actionType);
Yonghuxingwei record = new Yonghuxingwei();
record.setYonghuzhanghao(userAccount);
record.setShangpinid(productId);
record.setXingweileixing(actionType);
record.setXingweiquanzhong(weight);
record.setXingweishijian(new Date());
record.setAddtime(new Date());
yonghuxingweiMapper.insert(record);
// 触发推荐更新(异步)
updateRecommendationForUser(userAccount);
}
private int getActionWeight(int actionType) {
switch(actionType) {
case 1: return 1; // 浏览
case 2: return 3; // 收藏
case 3: return 5; // 购买
default: return 0;
}
}
4. 协同过滤推荐算法(核心算法模块)
- 核心逻辑:基于用户行为计算用户相似度→为当前用户推荐相似用户喜欢的商品;
- 页面设计:首页个性化推荐板块;商品详情页“猜你喜欢”;
- 代码要点(协同过滤算法实现):
@Service
public class CollaborativeFilteringService {
@Autowired
private YonghuxingweiMapper yonghuxingweiMapper;
@Autowired
private ShangpinxinxiMapper shangpinxinxiMapper;
@Autowired
private TuijiancacheMapper tuijiancacheMapper;
/**
* 为用户生成个性化推荐
* @param userAccount 用户账号
* @param limit 推荐数量
* @return 推荐商品列表
*/
public List<Shangpinxinxi> getRecommendations(String userAccount, int limit) {
// 1. 检查缓存(每天计算一次)
Tuijiancache cache = tuijiancacheMapper.selectOne(
new LambdaQueryWrapper<Tuijiancache>()
.eq(Tuijiancache::getYonghuzhanghao, userAccount)
.eq(Tuijiancache::getJisuanriqi, getTodayDate())
);
if (cache != null) {
List<Long> ids = parseIds(cache.getTuijianshangpinids());
return shangpinxinxiMapper.selectBatchIds(ids);
}
// 2. 获取所有用户对商品的偏好评分
List<UserPreference> allPreferences = getAllUserPreferences();
// 3. 获取当前用户的偏好
List<UserPreference> currentUserPrefs = getCurrentUserPreferences(userAccount);
// 4. 如果没有行为数据(冷启动),返回热门商品
if (currentUserPrefs.isEmpty()) {
return getHotProducts(limit);
}
// 5. 计算其他用户与当前用户的相似度
Map<Long, Double> similarityScores = new HashMap<>();
Map<Long, List<UserPreference>> userPrefMap = groupByUser(allPreferences);
for (Map.Entry<Long, List<UserPreference>> entry : userPrefMap.entrySet()) {
Long userId = entry.getKey();
if (userId.equals(userAccount)) continue;
double similarity = calculateSimilarity(currentUserPrefs, entry.getValue());
similarityScores.put(userId, similarity);
}
// 6. 获取相似度最高的K个用户
List<Long> similarUsers = similarityScores.entrySet().stream()
.sorted((a, b) -> Double.compare(b.getValue(), a.getValue()))
.limit(10)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
// 7. 收集相似用户喜欢的商品(排除当前用户已交互过的)
Set<Long> interactedProducts = currentUserPrefs.stream()
.map(UserPreference::getProductId)
.collect(Collectors.toSet());
Map<Long, Double> productScores = new HashMap<>();
for (Long similarUser : similarUsers) {
List<UserPreference> prefs = userPrefMap.get(similarUser);
double simScore = similarityScores.get(similarUser);
for (UserPreference pref : prefs) {
if (!interactedProducts.contains(pref.getProductId())) {
productScores.merge(pref.getProductId(),
pref.getScore() * simScore, Double::sum);
}
}
}
// 8. 获取推荐商品(过滤库存不足的)
List<Long> recommendedIds = productScores.entrySet().stream()
.sorted((a, b) -> Double.compare(b.getValue(), a.getValue()))
.limit(limit)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
// 9. 过滤已售罄商品
recommendedIds = recommendedIds.stream()
.filter(id -> {
Shangpinxinxi product = shangpinxinxiMapper.selectById(id);
return product != null && product.getAlllimittimes() > 0;
})
.collect(Collectors.toList());
// 10. 缓存推荐结果
cacheRecommendation(userAccount, recommendedIds);
return shangpinxinxiMapper.selectBatchIds(recommendedIds);
}
/**
* 计算用户相似度(余弦相似度)
*/
private double calculateSimilarity(List<UserPreference> prefs1, List<UserPreference> prefs2) {
Map<Long, Double> map1 = prefs1.stream()
.collect(Collectors.toMap(UserPreference::getProductId, UserPreference::getScore));
Map<Long, Double> map2 = prefs2.stream()
.collect(Collectors.toMap(UserPreference::getProductId, UserPreference::getScore));
Set<Long> commonProducts = new HashSet<>(map1.keySet());
commonProducts.retainAll(map2.keySet());
if (commonProducts.isEmpty()) return 0;
double dotProduct = 0.0;
double norm1 = 0.0;
double norm2 = 0.0;
for (Long productId : commonProducts) {
double score1 = map1.get(productId);
double score2 = map2.get(productId);
dotProduct += score1 * score2;
norm1 += score1 * score1;
norm2 += score2 * score2;
}
if (norm1 == 0 || norm2 == 0) return 0;
return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
}
/**
* 冷启动:热门商品推荐(基于购买量)
*/
private List<Shangpinxinxi> getHotProducts(int limit) {
// 按订单数量统计热门商品
// 简化实现:按点击量排序
return shangpinxinxiMapper.selectList(
new LambdaQueryWrapper<Shangpinxinxi>()
.gt(Shangpinxinxi::getAlllimittimes, 0)
.orderByDesc(Shangpinxinxi::getClicktime)
.last("limit " + limit)
);
}
}
5. 购物车与订单管理(交易闭环)
- 核心逻辑:用户加购→下单→支付→库存扣减;
- 页面设计:购物车列表、订单列表、支付界面;
- 代码要点:与推荐系统联动,购买行为触发行为记录更新。
6. 交流论坛管理(社区互动)
- 核心逻辑:用户发帖交流运动心得→管理员审核;
- 页面设计:论坛列表、帖子详情、楼中楼回复;
- 代码要点:帖子支持富文本;敏感词过滤。
7. 留言板管理(反馈模块)
- 核心逻辑:用户留言反馈→管理员回复;
- 页面设计:留言板显示留言内容、图片、管理员回复;
- 代码要点:支持留言图片上传。
8. 订单超时自动取消(定时任务)
@Component
public class OrderTimeoutTask {
@Scheduled(cron = "0 */5 * * * ?") // 每5分钟执行一次
@Transactional
public void cancelTimeoutOrders() {
// 查询超过30分钟未支付的订单
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, -30);
Date timeout = calendar.getTime();
List<Orders> timeoutOrders = ordersMapper.selectList(
new LambdaQueryWrapper<Orders>()
.eq(Orders::getStatus, "未支付")
.lt(Orders::getAddtime, timeout)
.groupBy(Orders::getOrderid)
);
Set<String> orderIds = timeoutOrders.stream()
.map(Orders::getOrderid)
.collect(Collectors.toSet());
for (String orderId : orderIds) {
cancelOrder(orderId);
log.info("订单 {} 超时自动取消", orderId);
}
}
}
五、推荐系统特色功能设计(关键加分项)
个性化智能体育商品推荐系统的核心在于“协同过滤算法+用户行为采集”,以下是实测有效的设计方案:
1. 用户行为-推荐-购买全流程追溯
| 环节 | 记录内容 | 可追溯信息 |
|---|---|---|
| 用户浏览 | 浏览商品、浏览时间 | 看了什么、什么时候看的 |
| 用户收藏 | 收藏商品、收藏时间 | 收藏了什么 |
| 用户购买 | 购买商品、购买数量 | 买了什么、买了多少 |
| 偏好计算 | 商品评分(加权) | 对什么商品偏好高 |
| 相似用户 | 相似度分数、相似用户列表 | 和谁相似 |
| 推荐结果 | 推荐商品、推荐理由 | 推荐了什么、为什么推荐 |
2. 用户偏好评分计算
-- 计算用户对商品的偏好评分(行为加权)
SELECT
u.yonghuzhanghao,
u.shangpinid,
SUM(u.xingweiquanzhong) as preference_score,
COUNT(CASE WHEN u.xingweileixing = 1 THEN 1 END) as view_count,
COUNT(CASE WHEN u.xingweileixing = 2 THEN 1 END) as collect_count,
COUNT(CASE WHEN u.xingweileixing = 3 THEN 1 END) as buy_count
FROM yonghuxingwei u
GROUP BY u.yonghuzhanghao, u.shangpinid
ORDER BY preference_score DESC
3. 热门商品统计
-- 统计热门商品(基于购买量和收藏量)
SELECT
s.*,
COUNT(DISTINCT o.id) as order_count,
COUNT(DISTINCT c.id) as collect_count,
(COUNT(DISTINCT o.id) * 0.6 + COUNT(DISTINCT c.id) * 0.4) as hot_score
FROM shangpinxinxi s
LEFT JOIN orders o ON s.id = o.goodid AND o.status = '已完成'
LEFT JOIN shoucang c ON s.id = c.refid AND c.type = '1'
WHERE s.alllimittimes > 0
GROUP BY s.id
ORDER BY hot_score DESC
LIMIT 10
六、测试与答辩:流程演示为主,突出推荐闭环
1. 核心测试用例
| 测试场景 | 操作步骤 | 预期结果 |
|---|---|---|
| 行为采集测试 | 用户浏览/收藏/购买商品 | 行为记录正确保存;权重正确 |
| 推荐算法测试 | 用户A购买商品X→用户B与A相似 | 用户B获得商品X推荐 |
| 冷启动推荐 | 新用户无行为数据 | 推荐热门商品 |
| 库存过滤 | 推荐商品售罄 | 推荐结果中不出现售罄商品 |
| 订单支付流程 | 用户下单→支付→库存扣减 | 订单生成;库存减少 |
2. 答辩准备技巧
- 演示流程:分角色演示(管理员端 + 用户端)→ 用户A浏览/收藏/购买体育商品(行为采集)→ 用户B注册登录(与A相似)→ 用户B首页查看个性化推荐(展示推荐结果)→ 用户B购买推荐商品 → 订单支付 → 展示完整的用户行为采集-协同过滤推荐-购买闭环;
- 业务讲解:准备一页PPT展示系统功能结构图(图4-1),说明每个模块的作用和推荐算法原理;
- 技术亮点:重点讲解协同过滤算法实现、用户行为权重计算、冷启动推荐策略;
- 突出问题解决:讲清“如何保证推荐准确性”(基于用户行为+相似度计算)、“冷启动用户怎么办”(热门商品推荐)、“推荐商品已售罄怎么办”(过滤机制);提前预判“为什么要设计用户行为权重”,回答“不同行为反映不同的偏好程度,提高推荐准确性”。
结语
本文核心是“聚焦用户行为-协同过滤-个性化推荐核心业务、实现智能推荐闭环、设计完整的体育商品推荐系统”。毕设无需复杂系统,把商品管理+用户行为采集+协同过滤算法+个性化推荐的业务逻辑讲透、实现一个可运行的个性化智能体育商品推荐系统、展示完整的推荐购买闭环,即可成为答辩亮点。
若需完整项目源码(带详细注释)、测试数据SQL脚本、协同过滤算法完整代码,可在评论区留言“SpringBoot体育商品推荐系统”获取;开发中遇问题(如算法优化、冷启动策略、行为权重设置),也可留言咨询~ 祝毕设顺利!🎉