请用Java代码实现经典的协同过滤算法(包含基于用户的,与基于商品的协同过滤)推荐使用皮尔逊相似度
时间: 2023-10-20 21:24:53 浏览: 85
基于用户的协同过滤算法:
```
import java.util.*;
public class UserBasedCollaborativeFiltering {
private Map<Integer, Map<Integer, Double>> ratings;
private Map<Integer, Map<Integer, Double>> similarityMatrix;
public UserBasedCollaborativeFiltering(Map<Integer, Map<Integer, Double>> ratings) {
this.ratings = ratings;
this.similarityMatrix = new HashMap<>();
}
public void computeSimilarityMatrix() {
for (int userId1 : ratings.keySet()) {
for (int userId2 : ratings.keySet()) {
if (userId1 != userId2) {
double similarity = computeSimilarity(userId1, userId2);
Map<Integer, Double> userSimilarities = similarityMatrix.getOrDefault(userId1, new HashMap<>());
userSimilarities.put(userId2, similarity);
similarityMatrix.put(userId1, userSimilarities);
}
}
}
}
private double computeSimilarity(int userId1, int userId2) {
Set<Integer> commonItems = new HashSet<>(ratings.get(userId1).keySet());
commonItems.retainAll(ratings.get(userId2).keySet());
if (commonItems.size() == 0) {
return 0;
}
double sum1 = 0, sum2 = 0, sum3 = 0;
for (int itemId : commonItems) {
double rating1 = ratings.get(userId1).get(itemId);
double rating2 = ratings.get(userId2).get(itemId);
sum1 += rating1 * rating2;
sum2 += rating1 * rating1;
sum3 += rating2 * rating2;
}
return sum1 / (Math.sqrt(sum2) * Math.sqrt(sum3));
}
public List<Integer> recommendItems(int userId, int numRecommendations) {
Map<Integer, Double> predictedRatings = new HashMap<>();
Map<Integer, Double> similarities = similarityMatrix.get(userId);
for (int userId2 : similarities.keySet()) {
if (userId2 != userId) {
Map<Integer, Double> ratings2 = ratings.get(userId2);
double similarity = similarities.get(userId2);
for (int itemId : ratings2.keySet()) {
if (!ratings.get(userId).containsKey(itemId)) {
double rating2 = ratings2.get(itemId);
double predictedRating = predictedRatings.getOrDefault(itemId, 0.0);
predictedRating += rating2 * similarity;
predictedRatings.put(itemId, predictedRating);
}
}
}
}
List<Integer> recommendations = new ArrayList<>(predictedRatings.keySet());
recommendations.sort((itemId1, itemId2) -> Double.compare(predictedRatings.get(itemId2), predictedRatings.get(itemId1)));
return recommendations.subList(0, Math.min(numRecommendations, recommendations.size()));
}
}
```
基于商品的协同过滤算法:
```
import java.util.*;
public class ItemBasedCollaborativeFiltering {
private Map<Integer, Map<Integer, Double>> ratings;
private Map<Integer, Map<Integer, Double>> similarityMatrix;
public ItemBasedCollaborativeFiltering(Map<Integer, Map<Integer, Double>> ratings) {
this.ratings = ratings;
this.similarityMatrix = new HashMap<>();
}
public void computeSimilarityMatrix() {
for (int itemId1 : ratings.values().iterator().next().keySet()) {
for (int itemId2 : ratings.values().iterator().next().keySet()) {
if (itemId1 != itemId2) {
double similarity = computeSimilarity(itemId1, itemId2);
Map<Integer, Double> itemSimilarities = similarityMatrix.getOrDefault(itemId1, new HashMap<>());
itemSimilarities.put(itemId2, similarity);
similarityMatrix.put(itemId1, itemSimilarities);
}
}
}
}
private double computeSimilarity(int itemId1, int itemId2) {
Set<Integer> commonUsers = new HashSet<>(ratings.keySet());
commonUsers.retainAll(ratings.keySet());
if (commonUsers.size() == 0) {
return 0;
}
double sum1 = 0, sum2 = 0, sum3 = 0;
for (int userId : commonUsers) {
double rating1 = ratings.get(userId).getOrDefault(itemId1, 0.0);
double rating2 = ratings.get(userId).getOrDefault(itemId2, 0.0);
sum1 += rating1 * rating2;
sum2 += rating1 * rating1;
sum3 += rating2 * rating2;
}
return sum1 / (Math.sqrt(sum2) * Math.sqrt(sum3));
}
public List<Integer> recommendItems(int userId, int numRecommendations) {
Map<Integer, Double> predictedRatings = new HashMap<>();
for (int itemId : ratings.values().iterator().next().keySet()) {
if (!ratings.get(userId).containsKey(itemId)) {
double predictedRating = 0;
double sumSimilarities = 0;
for (int itemId2 : ratings.get(userId).keySet()) {
double rating2 = ratings.get(userId).get(itemId2);
double similarity = similarityMatrix.get(itemId).getOrDefault(itemId2, 0.0);
predictedRating += rating2 * similarity;
sumSimilarities += similarity;
}
if (sumSimilarities > 0) {
predictedRating /= sumSimilarities;
predictedRatings.put(itemId, predictedRating);
}
}
}
List<Integer> recommendations = new ArrayList<>(predictedRatings.keySet());
recommendations.sort((itemId1, itemId2) -> Double.compare(predictedRatings.get(itemId2), predictedRatings.get(itemId1)));
return recommendations.subList(0, Math.min(numRecommendations, recommendations.size()));
}
}
```
阅读全文