基于用户的协同过滤算法(JAVA实现)
时间: 2023-10-20 15:19:11 浏览: 126
好的,基于用户的协同过滤算法是一种常用的推荐算法。下面是一个简单的JAVA实现:
首先,我们需要定义一个User类,用来存储用户信息和用户对物品的评分:
```java
public class User {
private String name;
private Map<String, Double> ratings; // 物品评分
public User(String name) {
this.name = name;
this.ratings = new HashMap<>();
}
public String getName() {
return name;
}
public Map<String, Double> getRatings() {
return ratings;
}
public void addRating(String itemId, double rating) {
ratings.put(itemId, rating);
}
public double getRating(String itemId) {
return ratings.getOrDefault(itemId, 0.0);
}
}
```
然后,我们需要定义一个UserCF类,用来实现基于用户的协同过滤算法:
```java
public class UserCF {
private List<User> users;
public UserCF(List<User> users) {
this.users = users;
}
/**
* 计算用户相似度
*/
private double sim(User user1, User user2) {
Set<String> commonItems = new HashSet<>(user1.getRatings().keySet());
commonItems.retainAll(user2.getRatings().keySet()); // 获取两个用户共同评分的物品
if (commonItems.size() == 0) {
return 0;
}
double sum1 = 0, sum2 = 0, sum3 = 0;
for (String itemId : commonItems) {
double rating1 = user1.getRating(itemId);
double rating2 = user2.getRating(itemId);
sum1 += rating1 * rating1;
sum2 += rating2 * rating2;
sum3 += rating1 * rating2;
}
return sum3 / (Math.sqrt(sum1) * Math.sqrt(sum2));
}
/**
* 获取与指定用户相似度最高的k个用户
*/
private List<User> topKSimilarUsers(User user, int k) {
List<User> similarUsers = new ArrayList<>(users);
similarUsers.remove(user); // 移除当前用户
similarUsers.sort(Comparator.comparingDouble(u -> -sim(user, u))); // 按相似度从高到低排序
return similarUsers.subList(0, Math.min(k, similarUsers.size())); // 返回前k个用户
}
/**
* 基于用户的协同过滤推荐算法
*/
public List<String> recommend(User user, int k) {
List<User> similarUsers = topKSimilarUsers(user, k);
Set<String> items = new HashSet<>();
for (User u : similarUsers) {
items.addAll(u.getRatings().keySet());
}
items.removeAll(user.getRatings().keySet()); // 移除当前用户已评分的物品
Map<String, Double> scores = new HashMap<>();
for (String itemId : items) {
double sum = 0;
double simSum = 0;
for (User u : similarUsers) {
double rating = u.getRating(itemId);
if (rating > 0) {
double s = sim(user, u);
sum += s * rating;
simSum += s;
}
}
if (simSum > 0) {
scores.put(itemId, sum / simSum);
}
}
List<String> recommendedItems = new ArrayList<>(scores.keySet());
recommendedItems.sort(Comparator.comparingDouble(scores::get).reversed()); // 按得分从高到低排序
return recommendedItems;
}
}
```
最后,我们可以使用如下代码来测试该算法:
```java
public class Test {
public static void main(String[] args) {
List<User> users = new ArrayList<>();
User user1 = new User("user1");
user1.addRating("item1", 3.0);
user1.addRating("item2", 4.0);
user1.addRating("item3", 2.0);
User user2 = new User("user2");
user2.addRating("item1", 4.0);
user2.addRating("item3", 3.0);
user2.addRating("item4", 2.0);
User user3 = new User("user3");
user3.addRating("item2", 3.0);
user3.addRating("item3", 4.0);
user3.addRating("item4", 2.0);
users.add(user1);
users.add(user2);
users.add(user3);
UserCF userCF = new UserCF(users);
User user = new User("user");
user.addRating("item1", 5.0);
user.addRating("item3", 1.0);
List<String> recommendedItems = userCF.recommend(user, 2);
System.out.println(recommendedItems);
}
}
```
输出结果为:[item2, item4],表示推荐给用户的物品为item2和item4。
阅读全文