|
|
package com.example.entity;
|
|
|
|
|
|
import cn.hutool.core.collection.CollectionUtil;
|
|
|
|
|
|
import java.util.Collections;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
// 功能:基于用户的协同过滤推荐算法
|
|
|
|
|
|
public class UserCF {
|
|
|
|
|
|
/**
|
|
|
* 方法描述: 推荐商品id列表
|
|
|
* 基于用户的协同过滤算法,找到与当前用户最相似的用户,推荐相似用户喜欢而当前用户未看过的商品
|
|
|
* @param userId 当前用户ID
|
|
|
* @param list 用户商品评分数据列表
|
|
|
* @return {@link List<Integer>} 推荐的商品ID列表
|
|
|
*/
|
|
|
public static List<Integer> recommend(Integer userId, List<RelateDTO> list) {
|
|
|
// 按用户ID分组,构建用户-商品评分映射
|
|
|
Map<Integer, List<RelateDTO>> userMap = list.stream().collect(Collectors.groupingBy(RelateDTO::getUseId));
|
|
|
|
|
|
// 获取其他用户与当前用户的相似度关系值
|
|
|
Map<Integer, Double> userDisMap = CoreMath.computeNeighbor(userId, userMap, 0);
|
|
|
|
|
|
// 如果没有找到相似用户,返回空列表
|
|
|
if (CollectionUtil.isEmpty(userDisMap)) {
|
|
|
return Collections.emptyList();
|
|
|
}
|
|
|
|
|
|
// 获取相似度最高的用户(关系最近的用户)
|
|
|
double maxValue = Collections.max(userDisMap.values());
|
|
|
Set<Integer> userIds = userDisMap.entrySet().stream()
|
|
|
.filter(e -> e.getValue() == maxValue)
|
|
|
.map(Map.Entry::getKey)
|
|
|
.collect(Collectors.toSet());
|
|
|
|
|
|
// 取任意一个相似度最高的用户
|
|
|
Integer nearestUserId = userIds.stream().findAny().orElse(null);
|
|
|
if (nearestUserId == null) {
|
|
|
return Collections.emptyList();
|
|
|
}
|
|
|
|
|
|
// 获取最近邻用户看过的商品列表
|
|
|
List<Integer> neighborItems = userMap.get(nearestUserId).stream()
|
|
|
.map(RelateDTO::getGoodsId)
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
// 获取当前用户看过的商品列表
|
|
|
List<Integer> userItems = userMap.get(userId).stream()
|
|
|
.map(RelateDTO::getGoodsId)
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
// 找到最近邻用户看过但当前用户没看过的商品(差集)
|
|
|
neighborItems.removeAll(userItems);
|
|
|
return neighborItems;
|
|
|
}
|
|
|
} |