java UserCF改进后的代码 举例说明
时间: 2024-05-13 21:16:48 浏览: 71
以下是一个简单的基于用户协同过滤(UserCF)算法的改进版Java代码示例:
```java
public class UserCFImproved {
private Map<Integer, Map<Integer, Double>> userRating; // 用户评分矩阵
private Map<Integer, Set<Integer>> userRelate; // 用户之间的关联矩阵
private Map<Integer, Double> userAvgRating; // 用户平均评分
public UserCFImproved(Map<Integer, Map<Integer, Double>> userRating) {
this.userRating = userRating;
this.userRelate = new HashMap<>();
this.userAvgRating = new HashMap<>();
generateUserRelate();
generateUserAvgRating();
}
// 生成用户之间的关联矩阵
private void generateUserRelate() {
for (Integer user1 : userRating.keySet()) {
for (Integer user2 : userRating.keySet()) {
if (user1.equals(user2)) {
continue; // 相同用户不做处理
}
double similarity = calculateUserSimilarity(user1, user2);
if (similarity > 0) {
if (!userRelate.containsKey(user1)) {
userRelate.put(user1, new HashSet<>());
}
userRelate.get(user1).add(user2);
}
}
}
}
// 计算用户之间的相似度
private double calculateUserSimilarity(int user1, int user2) {
Set<Integer> commonItems = new HashSet<>(userRating.get(user1).keySet());
commonItems.retainAll(userRating.get(user2).keySet()); // 求交集
if (commonItems.isEmpty()) {
return 0; // 没有共同评分的物品,相似度为0
}
double sum1 = 0, sum2 = 0, sum3 = 0;
for (int item : commonItems) {
double rating1 = userRating.get(user1).get(item);
double rating2 = userRating.get(user2).get(item);
sum1 += rating1 * rating2;
sum2 += rating1 * rating1;
sum3 += rating2 * rating2;
}
return sum1 / (Math.sqrt(sum2) * Math.sqrt(sum3));
}
// 生成用户平均评分
private void generateUserAvgRating() {
for (int user : userRating.keySet()) {
double sum = 0;
int count = 0;
for (double rating : userRating.get(user).values()) {
sum += rating;
count++;
}
userAvgRating.put(user, sum / count);
}
}
// 预测用户对物品的评分
public double predictRating(int user, int item) {
double numerator = 0, denominator = 0;
if (!userRelate.containsKey(user)) {
return userAvgRating.get(user); // 没有相关用户,返回用户平均评分
}
for (int relatedUser : userRelate.get(user)) {
if (userRating.get(relatedUser).containsKey(item)) {
double similarity = calculateUserSimilarity(user, relatedUser);
numerator += similarity * (userRating.get(relatedUser).get(item) - userAvgRating.get(relatedUser));
denominator += similarity;
}
}
if (denominator == 0) {
return userAvgRating.get(user); // 没有相关用户对该物品评分,返回用户平均评分
}
return userAvgRating.get(user) + numerator / denominator;
}
}
```
这个改进版的UserCF算法主要做了以下几个方面的改进:
1. 生成用户之间的关联矩阵时,只考虑相似度大于0的用户,避免计算不必要的相似度,提高了算法效率;
2. 生成用户平均评分时,只考虑用户对物品的真实评分,避免了评分数据的偏差;
3. 在预测用户对物品的评分时,考虑了用户对物品的平均评分和相关用户的相似度,避免了仅仅考虑相似用户的情况下得到的预测结果过于极端或不准确的情况。
阅读全文