基于用户的协同过滤算法代码java
时间: 2023-10-20 08:18:02 浏览: 87
以下是一个简单的基于用户的协同过滤算法的 Java 代码示例:
```java
public class UserBasedCF {
private Map<Integer, Map<Integer, Double>> userItemRatingMatrix; // 用户-物品评分矩阵
private Map<Integer, List<Integer>> userItemMap; // 用户-物品列表映射
private Map<Integer, Double> userAverageRatingMap; // 用户平均评分映射
public UserBasedCF(Map<Integer, Map<Integer, Double>> userItemRatingMatrix) {
this.userItemRatingMatrix = userItemRatingMatrix;
this.userItemMap = new HashMap<>();
this.userAverageRatingMap = new HashMap<>();
initialize();
}
// 初始化用户-物品列表映射和用户平均评分映射
private void initialize() {
for (Map.Entry<Integer, Map<Integer, Double>> entry : userItemRatingMatrix.entrySet()) {
int userId = entry.getKey();
Map<Integer, Double> itemRatingMap = entry.getValue();
double sum = 0.0;
for (Map.Entry<Integer, Double> itemRatingEntry : itemRatingMap.entrySet()) {
int itemId = itemRatingEntry.getKey();
double rating = itemRatingEntry.getValue();
sum += rating;
if (userItemMap.containsKey(userId)) {
userItemMap.get(userId).add(itemId);
} else {
List<Integer> itemList = new ArrayList<>();
itemList.add(itemId);
userItemMap.put(userId, itemList);
}
}
userAverageRatingMap.put(userId, sum / itemRatingMap.size());
}
}
// 计算两个用户之间的皮尔逊相关系数
private double pearsonCorrelation(int userId1, int userId2) {
List<Integer> commonItemList = getCommonItems(userId1, userId2);
if (commonItemList.isEmpty()) {
return 0.0;
}
double sum1 = 0.0, sum2 = 0.0, sum1Sq = 0.0, sum2Sq = 0.0, pSum = 0.0;
for (int itemId : commonItemList) {
double rating1 = userItemRatingMatrix.get(userId1).get(itemId);
double rating2 = userItemRatingMatrix.get(userId2).get(itemId);
sum1 += rating1;
sum2 += rating2;
sum1Sq += Math.pow(rating1, 2);
sum2Sq += Math.pow(rating2, 2);
pSum += rating1 * rating2;
}
int n = commonItemList.size();
double numerator = pSum - (sum1 * sum2 / n);
double denominator = Math.sqrt((sum1Sq - Math.pow(sum1, 2) / n) * (sum2Sq - Math.pow(sum2, 2) / n));
if (denominator == 0.0) {
return 0.0;
}
return numerator / denominator;
}
// 获取两个用户共同评分的物品列表
private List<Integer> getCommonItems(int userId1, int userId2) {
List<Integer> itemList1 = userItemMap.get(userId1);
List<Integer> itemList2 = userItemMap.get(userId2);
List<Integer> commonItemList = new ArrayList<>(itemList1);
commonItemList.retainAll(itemList2);
return commonItemList;
}
// 获取与指定用户最相似的前K个用户
private List<Integer> getTopKSimilarUsers(int userId, int k) {
Map<Integer, Double> similarityMap = new HashMap<>();
for (int otherUserId : userItemMap.keySet()) {
if (otherUserId != userId) {
double similarity = pearsonCorrelation(userId, otherUserId);
similarityMap.put(otherUserId, similarity);
}
}
List<Integer> similarUserList = new ArrayList<>(similarityMap.keySet());
Collections.sort(similarUserList, new Comparator<Integer>() {
@Override
public int compare(Integer userId1, Integer userId2) {
return Double.compare(similarityMap.get(userId2), similarityMap.get(userId1));
}
});
return similarUserList.subList(0, Math.min(k, similarUserList.size()));
}
// 预测指定用户对指定物品的评分
public double predict(int userId, int itemId, int k) {
List<Integer> similarUserList = getTopKSimilarUsers(userId, k);
double numerator = 0.0, denominator = 0.0;
for (int otherUserId : similarUserList) {
if (userItemRatingMatrix.get(otherUserId).containsKey(itemId)) {
double similarity = pearsonCorrelation(userId, otherUserId);
double rating = userItemRatingMatrix.get(otherUserId).get(itemId);
double averageRating = userAverageRatingMap.get(otherUserId);
numerator += similarity * (rating - averageRating);
denominator += Math.abs(similarity);
}
}
if (denominator == 0.0) {
return userAverageRatingMap.get(userId);
}
return userAverageRatingMap.get(userId) + numerator / denominator;
}
}
```
使用示例:
```java
Map<Integer, Map<Integer, Double>> userItemRatingMatrix = new HashMap<>();
// 假设有4个用户和5个物品,评分矩阵如下:
// 1 2 3 0 0
// 4 5 0 0 0
// 0 3 0 5 0
// 0 0 4 0 5
userItemRatingMatrix.put(1, new HashMap<Integer, Double>() {{
put(1, 1.0);
put(2, 2.0);
put(3, 3.0);
}});
userItemRatingMatrix.put(2, new HashMap<Integer, Double>() {{
put(1, 4.0);
put(2, 5.0);
}});
userItemRatingMatrix.put(3, new HashMap<Integer, Double>() {{
put(2, 3.0);
put(4, 5.0);
}});
userItemRatingMatrix.put(4, new HashMap<Integer, Double>() {{
put(3, 4.0);
put(5, 5.0);
}});
UserBasedCF userBasedCF = new UserBasedCF(userItemRatingMatrix);
double predictedRating = userBasedCF.predict(1, 4, 2); // 预测用户1对物品4的评分,使用最相似的2个用户
System.out.println(predictedRating); // 输出预测评分
```
阅读全文