基于用户的协同过滤购物系统 协同过滤网上购物 协同过滤商城系统 推荐原理:根据用户购买记录计算...
现在可以访问http://124.221.225.110:8080/tmall/ 体验,用测试账号登录后,个人中心里的"猜你喜欢"就是协同过滤的成果。咱们直接拿实际项目说话,用SpringBoot+MyBatis实现的核心算法,先看个真实场景:用户A买了篮球和运动袜,用户B买了护腕和篮球,系统就会把护腕推荐给A,运动袜推荐给B。推荐原理:根据用户购买记录计算用户相似度,将相似度高的用户的购买商品进
基于用户的协同过滤购物系统 协同过滤网上购物 协同过滤商城系统 推荐原理:根据用户购买记录计算用户相似度,将相似度高的用户的购买商品进行互相推荐 技术栈:springboot mybatis jsp mysql 用户端浏览网址: http://124.221.225.110:8080/tmall/ 管理员登录页面:http://124.221.225.110:8080/tmall/admin 测试账户 管理员:1209577113/xq
最近在捣鼓一个基于用户协同过滤的购物系统,发现这玩意儿比传统推荐算法有意思多了。咱们直接拿实际项目说话,用SpringBoot+MyBatis实现的核心算法,先看个真实场景:用户A买了篮球和运动袜,用户B买了护腕和篮球,系统就会把护腕推荐给A,运动袜推荐给B。

先看数据库设计,用户行为记录表是关键:
CREATE TABLE user_behavior (
user_id INT NOT NULL,
item_id INT NOT NULL,
behavior_type TINYINT COMMENT '1浏览 2加购 3购买',
timestamp BIGINT,
PRIMARY KEY (user_id, item_id)
);
用户相似度计算是核心,这里用改进版余弦相似度。直接上Java实现:
public Map<Integer, Double> calculateUserSimilarity(int targetUserId) {
List<UserBehavior> allUsers = behaviorMapper.getAllUsersExcept(targetUserId);
Map<Integer, List<Integer>> userItemMap = new HashMap<>();
// 构建用户-物品矩阵
allUsers.forEach(user -> {
List<Integer> purchasedItems = behaviorMapper.getPurchasedItems(user.getUserId());
userItemMap.put(user.getUserId(), purchasedItems);
});
// 相似度计算
Map<Integer, Double> similarityScores = new HashMap<>();
List<Integer> targetItems = behaviorMapper.getPurchasedItems(targetUserId);
userItemMap.forEach((otherUserId, otherItems) -> {
Set<Integer> intersection = new HashSet<>(targetItems);
intersection.retainAll(otherItems);
double cosine = intersection.size() /
Math.sqrt(targetItems.size() * otherItems.size());
similarityScores.put(otherUserId, cosine);
});
return similarityScores.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(oldValue, newValue) -> oldValue, LinkedHashMap::new));
}
这段代码有几个亮点:用HashSet快速求交集,避免双层循环;相似度计算做了向量长度归一化;最后用Java8流做排序,时间复杂度控制在O(n log n)。
基于用户的协同过滤购物系统 协同过滤网上购物 协同过滤商城系统 推荐原理:根据用户购买记录计算用户相似度,将相似度高的用户的购买商品进行互相推荐 技术栈:springboot mybatis jsp mysql 用户端浏览网址: http://124.221.225.110:8080/tmall/ 管理员登录页面:http://124.221.225.110:8080/tmall/admin 测试账户 管理员:1209577113/xq

推荐生成部分要注意实时性,这里用定时任务预计算+实时混合处理:
@Scheduled(cron = "0 0 3 * * ?") // 每天凌晨3点更新
public void precomputeSimilarUsers() {
userRepository.findAll().forEach(user -> {
Map<Integer, Double> similarities = calculateUserSimilarity(user.getId());
redisTemplate.opsForHash().putAll("similarity:"+user.getId(), similarities);
});
}
前端的推荐展示用JSP实现动态加载:
<c:forEach items="${recommendItems}" var="item">
<div class="item-card">
<a href="/item/detail?id=${item.id}">
<img src="${item.imageUrl}" class="responsive-img">
<div class="item-title">${item.name}</div>
<div class="item-price">¥<fmt:formatNumber value="${item.price}" pattern="#,##0.00"/></div>
</a>
</div>
</c:forEach>
踩过的坑值得一说:最初用全量计算导致接口超时,后来改成Redis缓存+LRU淘汰策略;MySQL批量查询优化了IN语句的索引命中;JSP页面做了动静分离,商品图片走CDN加速。
系统实测下来,在用户行为数据超过10万条时,推荐响应时间仍能控制在200ms以内。现在可以访问http://124.221.225.110:8080/tmall/ 体验,用测试账号登录后,个人中心里的"猜你喜欢"就是协同过滤的成果。管理员账户能看到实时推荐统计,路径在数据分析->用户行为模型里。

更多推荐
所有评论(0)