Java

java如何实现协同过滤算法

小亿
87
2024-12-07 08:55:43
栏目: 编程语言

协同过滤(Collaborative Filtering,简称CF)是一种推荐系统算法,主要基于用户的历史行为(如评分、购买记录)来预测和推荐其他用户可能感兴趣的项目。在Java中实现协同过滤算法,可以分为以下几个步骤:

  1. 收集和预处理数据:收集用户对项目的评分数据,并进行预处理,如去除缺失值、归一化等。

  2. 计算相似度:根据用户的历史行为数据计算用户之间的相似度。常用的相似度计算方法有皮尔逊相关系数(Pearson Correlation Coefficient)、余弦相似度(Cosine Similarity)和杰卡德相似度(Jaccard Similarity)等。

  3. 生成推荐列表:根据相似度计算结果,为用户推荐与其相似度较高的其他用户喜欢的项目。

下面是一个简单的Java实现协同过滤算法的示例:

import java.util.*;

public class CollaborativeFiltering {
    // 用户-项目评分矩阵
    private Map<Integer, Map<Integer, Double>> userItemRatings;

    public CollaborativeFiltering() {
        userItemRatings = new HashMap<>();
    }

    // 添加用户评分数据
    public void addUserRating(int userId, int itemId, double rating) {
        userItemRatings.putIfAbsent(userId, new HashMap<>());
        userItemRatings.get(userId).put(itemId, rating);
    }

    // 计算用户相似度
    public Map<Integer, Double> calculateSimilarity(int userId) {
        List<Integer> similarUsers = new ArrayList<>();
        Map<Integer, Double> similarityScores = new HashMap<>();

        for (Map.Entry<Integer, Map<Integer, Double>> entry : userItemRatings.entrySet()) {
            if (entry.getKey() != userId) {
                int similarUserId = entry.getKey();
                double similarityScore = calculateSimilarityScore(userId, similarUserId);
                similarityScores.put(similarUserId, similarityScore);
                similarUsers.add(similarUserId);
            }
        }

        // 对相似度进行排序并返回前N个相似用户
        similarUsers.sort((u1, u2) -> similarityScores.get(u2) - similarityScores.get(u1));
        return Collections.singletonMap(similarUsers.get(0), similarityScores.get(similarUsers.get(0)));
    }

    // 计算用户相似度得分
    private double calculateSimilarityScore(int userId1, int userId2) {
        Map<Integer, Double> userItemRatings1 = userItemRatings.get(userId1);
        Map<Integer, Double> userItemRatings2 = userItemRatings.get(userId2);

        int commonItems = 0;
        double sumSimilarityScore = 0;

        for (Map.Entry<Integer, Double> entry : userItemRatings1.entrySet()) {
            if (userItemRatings2.containsKey(entry.getKey())) {
                commonItems++;
                sumSimilarityScore += entry.getValue() * userItemRatings2.get(entry.getKey());
            }
        }

        return commonItems > 0 ? sumSimilarityScore / Math.sqrt(userItemRatings1.size() * userItemRatings2.size()) : 0;
    }

    // 生成推荐列表
    public List<Integer> generateRecommendations(int userId, int topN) {
        Map<Integer, Double> similarityScores = calculateSimilarity(userId);
        PriorityQueue<Map.Entry<Integer, Double>> maxHeap = new PriorityQueue<>(
                (entry1, entry2) -> entry2.getValue().compareTo(entry1.getValue())
        );

        for (Map.Entry<Integer, Double> entry : similarityScores.entrySet()) {
            maxHeap.offer(entry);
            if (maxHeap.size() > topN) {
                maxHeap.poll();
            }
        }

        List<Integer> recommendations = new ArrayList<>();
        while (!maxHeap.isEmpty()) {
            recommendations.add(maxHeap.poll().getKey());
        }

        Collections.reverse(recommendations);
        return recommendations;
    }

    public static void main(String[] args) {
        CollaborativeFiltering cf = new CollaborativeFiltering();
        cf.addUserRating(1, 1, 5);
        cf.addUserRating(1, 2, 3);
        cf.addUserRating(2, 1, 4);
        cf.addUserRating(2, 2, 5);
        cf.addUserRating(3, 1, 1);
        cf.addUserRating(3, 2, 2);

        List<Integer> recommendations = cf.generateRecommendations(1, 2);
        System.out.println("Recommendations for user 1: " + recommendations);
    }
}

这个示例中,我们使用了一个简单的用户-项目评分矩阵来存储用户对项目的评分数据。calculateSimilarity方法用于计算用户之间的相似度,generateRecommendations方法根据相似度为用户生成推荐列表。在main方法中,我们添加了一些示例数据并生成了推荐列表。

0
看了该问题的人还看了