import java.util.*;
public class CollaborativeFiltering {
// 用户-物品评分矩阵,使用Map表示
private Map<Integer, Map<Integer, Double>> userItemRatings;
public CollaborativeFiltering() {
this.userItemRatings = new HashMap<>();
}
// 添加用户对物品的评分
public void addUserRating(int userId, int itemId, double rating) {
userItemRatings.computeIfAbsent(userId, k -> new HashMap<>()).put(itemId, rating);
}
// 计算两个用户的相似度(使用余弦相似度)
private double cosineSimilarity(Map<Integer, Double> ratings1, Map<Integer, Double> ratings2) {
Set<Integer> commonItems = new HashSet<>(ratings1.keySet());
commonItems.retainAll(ratings2.keySet());
if (commonItems.isEmpty()) return 0.0;
double dotProduct = 0.0;
double normA = 0.0;
double normB = 0.0;
for (int item : commonItems) {
double rating1 = ratings1.get(item);
double rating2 = ratings2.get(item);
dotProduct += rating1 * rating2;
normA += Math.pow(rating1, 2);
normB += Math.pow(rating2, 2);
}
return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
}
// 获取与目标用户最相似的k个用户
public List<Map.Entry<Integer, Double>> getTopKSimilarUsers(int targetUserId, int k) {
Map<Integer, Double> similarities = new HashMap<>();
for (Map.Entry<Integer, Map<Integer, Double>> entry : userItemRatings.entrySet()) {
int userId = entry.getKey();
if (userId != targetUserId) {
double similarity = cosineSimilarity(userItemRatings.get(targetUserId), entry.getValue());
similarities.put(userId, similarity);
}
}
List<Map.Entry<Integer, Double>> sortedSimilarities = similarities.entrySet().stream()
.sorted((e1, e2) -> Double.compare(e2.getValue(), e1.getValue()))
.toList();
return sortedSimilarities.subList(0, Math.min(k, sortedSimilarities.size()));
}
// 预测目标用户对某个物品的评分
public double predictRating(int targetUserId, int targetItemId) {
List<Map.Entry<Integer, Double>> topKSimilarUsers = getTopKSimilarUsers(targetUserId, 5);
double weightedSum = 0.0;
double similaritySum = 0.0;
for (Map.Entry<Integer, Double> entry : topKSimilarUsers) {
int similarUserId = entry.getKey();
double similarity = entry.getValue();
if (userItemRatings.get(similarUserId).containsKey(targetItemId)) {
double rating = userItemRatings.get(similarUserId).get(targetItemId);
weightedSum += rating * similarity;
similaritySum += similarity;
}
}
return similaritySum == 0 ? 0.0 : weightedSum / similaritySum;
}
public static void main(String[] args) {
CollaborativeFiltering cf = new CollaborativeFiltering();
// 添加一些用户评分数据
cf.addUserRating(1, 101, 5.0);
cf.addUserRating(1, 102, 3.0);
cf.addUserRating(2, 101, 4.0);
cf.addUserRating(2, 102, 4.0);
cf.addUserRating(3, 101, 1.0);
cf.addUserRating(3, 102, 5.0);
// 预测用户1对物品103的评分
System.out.println("Predicted rating for user 1 on item 103: " + cf.predictRating(1, 103));
}
}
用户-物品评分矩阵:使用Map<Integer, Map<Integer, Double>>来存储用户对物品的评分。外层Map的键是用户ID,值是该用户对不同物品的评分。
添加用户评分:addUserRating方法用于向评分矩阵中添加用户对特定物品的评分。
计算相似度:cosineSimilarity方法使用余弦相似度来计算两个用户之间的相似度。余弦相似度通过计算两个用户在共同评分的物品上的评分向量的夹角来衡量它们的相似性。
获取最相似用户:getTopKSimilarUsers方法返回与目标用户最相似的前k个用户。它首先计算所有其他用户与目标用户的相似度,然后按相似度从高到低排序,并返回前k个用户。
预测评分:predictRating方法预测目标用户对某个物品的评分。它通过找到与目标用户最相似的几个用户,并根据这些用户的评分和相似度加权平均来预测目标用户的评分。
主函数:main方法中添加了一些示例数据,并演示了如何预测用户对某个物品的评分。
如果你需要更详细的解释或其他功能,请告诉我!
上一篇:java int转byte
下一篇:javaset转list集合
Laravel PHP 深圳智简公司。版权所有©2023-2043 LaravelPHP 粤ICP备2021048745号-3
Laravel 中文站