Maison >Java >javaDidacticiel >Comment écrire une application de réseau social basée sur un système de recommandation à l'aide de Java

Comment écrire une application de réseau social basée sur un système de recommandation à l'aide de Java

WBOY
WBOYoriginal
2023-06-27 08:32:141194parcourir

Dans les applications de réseaux sociaux modernes, les systèmes de recommandation sont devenus une fonction essentielle. Qu'il s'agisse de recommander des amis aux utilisateurs, de recommander des sujets d'intérêt, de recommander des produits connexes ou de recommander du contenu plus précieux, les systèmes de recommandation peuvent améliorer efficacement l'expérience utilisateur et la fidélité.

Dans cet article, nous présenterons comment écrire une application de réseau social basée sur un système de recommandation utilisant Java. Nous combinerons le code réel et les étapes détaillées pour aider les lecteurs à comprendre et à mettre en œuvre rapidement un système de recommandation de base.

1. Collecte et traitement des données

Avant de mettre en œuvre un système de recommandation, nous devons collecter et traiter une grande quantité de données. Dans les applications de réseaux sociaux, les informations sur les utilisateurs, les publications, les commentaires, les likes et autres données sont autant de sources de données précieuses.

Pour faciliter la démonstration, nous pouvons utiliser un générateur de données virtuelles open source pour générer ces données. Les étapes spécifiques sont les suivantes :

  1. Téléchargez et installez un générateur de données virtuelles, tel que Mockaroo (https://www.mockaroo.com/).
  2. Définissez l'ensemble de données qui doit être généré, y compris les informations sur les utilisateurs, les publications, les commentaires, etc.
  3. Générez des données et exportez-les vers un fichier CSV.
  4. Utilisez le code Java pour lire les données du fichier CSV et les stocker dans la base de données. Nous pouvons utiliser des bases de données relationnelles populaires telles que MySQL et Oracle pour stocker des données. Ici, nous utilisons MySQL 8.0 comme base de données pour le stockage des données.

2. Représentation des utilisateurs et des éléments

Dans le système de recommandation, nous devons convertir les utilisateurs et les éléments sous forme vectorielle ou matricielle pour faciliter le calcul de leur similarité ou recommandation. Dans les applications de réseaux sociaux, nous pouvons utiliser les méthodes suivantes pour représenter les utilisateurs et les éléments :

  1. Vecteur d'utilisateur : nous pouvons utiliser les sujets que les utilisateurs suivent, les publications qu'ils publient, les amis avec lesquels ils interagissent, etc. . Un vecteur de données pour représenter un utilisateur. Par exemple, si un utilisateur A suit les sujets Java, Python, JavaScript, etc., publie "Comment bien apprendre Java" et "Démarrer avec Java" et interagit avec les utilisateurs B et C, alors nous pouvons utiliser le vecteur suivant pour représenter l'utilisateur A :

User A = [1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1 , 1, 1, 0, 0, 0, 1, 0, 0, 1]

Parmi eux, la longueur du vecteur est de 24 et chaque position représente un sujet ou un message. 1 signifie que l'utilisateur A a suivi le sujet ou publié la publication, et 0 signifie non.

  1. Vecteur d'article : Nous pouvons utiliser les balises, le contenu, les commentaires et autres données de chaque publication pour représenter le vecteur d'une publication. Par exemple, si une publication est étiquetée « Java, programmation » et que le contenu est « Quatre suggestions pour apprendre la programmation Java » et comporte 10 commentaires, alors nous pouvons utiliser le vecteur suivant pour représenter la publication :

Post A = [1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0]

Parmi eux, la longueur du vecteur est de 24 et chaque position représente une étiquette ou des données statistiques. 1 signifie que la publication contient la balise ou le contenu, 0 signifie que ce n'est pas le cas.

3. Recommandation de filtrage collaboratif basée sur l'utilisateur

Le filtrage collaboratif basé sur l'utilisateur est une méthode courante dans les systèmes de recommandation. Il recommande des éléments en fonction de la similitude des intérêts des utilisateurs. Ici, nous utilisons un filtrage collaboratif basé sur les utilisateurs pour recommander des publications appropriées aux utilisateurs. Les étapes spécifiques sont les suivantes :

  1. Calculer la similarité entre les utilisateurs. Ici, nous utilisons le coefficient de corrélation de Pearson comme métrique de similarité.
  2. Sélectionnez K utilisateurs présentant la similitude d'intérêt la plus élevée avec l'utilisateur cible.
  3. Pour chaque utilisateur, sélectionnez N publications qu'il aime mais qui n'ont pas été vues par l'utilisateur cible.
  4. Pour les N publications sélectionnées, calculez le score de recommandation de chaque publication et triez-les du haut au bas.
  5. Sélectionnez les meilleurs messages M avec les scores les plus élevés comme résultats recommandés.

Ce qui suit est l'implémentation du code Java de l'algorithme :

public class CollaborativeFiltering {

    /**
     * 计算用户间的皮尔逊相关系数
     * @param user1 用户1
     * @param user2 用户2
     * @param data 数据集
     * @return 皮尔逊相关系数
     */
    public double pearsonCorrelation(Map<Integer, Double> user1, Map<Integer, Double> user2,
                                      Map<Integer, Map<Integer, Double>> data) {
        double sum1 = 0, sum2 = 0, sum1Sq = 0, sum2Sq = 0, pSum = 0;
        int n = 0;
        for (int item : user1.keySet()) {
            if (user2.containsKey(item)) {
                sum1 += user1.get(item);
                sum2 += user2.get(item);
                sum1Sq += Math.pow(user1.get(item), 2);
                sum2Sq += Math.pow(user2.get(item), 2);
                pSum += user1.get(item) * user2.get(item);
                n++;
            }
        }
        if (n == 0)
            return 0;
        double num = pSum - (sum1 * sum2 / n);
        double den = Math.sqrt((sum1Sq - Math.pow(sum1, 2) / n) *
                (sum2Sq - Math.pow(sum2, 2) / n));
        if (den == 0)
            return 0;
        return num / den;
    }

    /**
     * 基于用户的协同过滤推荐算法
     * @param data 数据集
     * @param userId 目标用户 ID
     * @param K 最相似的 K 个用户
     * @param N 推荐的 N 个帖子
     * @return 推荐的帖子 ID 列表
     */
    public List<Integer> userBasedCollaborativeFiltering(Map<Integer, Map<Integer, Double>> data,
                                                          int userId, int K, int N) {
        Map<Integer, Double> targetUser = data.get(userId); // 目标用户
        List<Map.Entry<Integer, Double>> similarUsers = new ArrayList<>(); // 与目标用户兴趣相似的用户
        for (Map.Entry<Integer, Map<Integer, Double>> entry: data.entrySet()) {
            int id = entry.getKey();
            if (id == userId)
                continue;
            double sim = pearsonCorrelation(targetUser, entry.getValue(), data); // 计算皮尔逊相关系数
            if (sim > 0)
                similarUsers.add(new AbstractMap.SimpleEntry<>(id, sim));
        }
        Collections.sort(similarUsers, (a, b) -> b.getValue().compareTo(a.getValue())); // 按相似度从高到低排序
        List<Integer> itemIds = new ArrayList<>();
        for (int i = 0; i < K && i < similarUsers.size(); i++) {
            Map.Entry<Integer, Double> entry = similarUsers.get(i);
            int userId2 = entry.getKey();
            Map<Integer, Double> user2 = data.get(userId2);
            for (int itemId: user2.keySet()) {
                if (!targetUser.containsKey(itemId)) { // 如果目标用户没看过该帖子
                    itemIds.add(itemId);
                }
            }
        }
        Map<Integer, Double> scores = new HashMap<>();
        for (int itemId: itemIds) {
            double score = 0;
            int count = 0;
            for (Map.Entry<Integer, Double> entry: similarUsers) {
                int userId2 = entry.getKey();
                Map<Integer, Double> user2 = data.get(userId2);
                if (user2.containsKey(itemId)) { // 如果用户 2 看过该帖子
                    score += entry.getValue() * user2.get(itemId);
                    count++;
                    if (count == N)
                        break;
                }
            }
            scores.put(itemId, score);
        }
        List<Integer> pickedItemIds = new ArrayList<>();
        scores.entrySet().stream().sorted((a, b) -> b.getValue().compareTo(a.getValue()))
                .limit(N).forEach(entry -> pickedItemIds.add(entry.getKey())); // 按得分从高到低排序并选出前N个
        return pickedItemIds;
    }
}

4. Algorithme de recommandation basé sur le contenu

Basé sur le contenu L'algorithme de recommandation est une autre méthode courante dans les systèmes de recommandation, qui recommande des éléments en fonction de la similarité des attributs des éléments. Ici, nous utilisons un algorithme de recommandation basé sur le contenu pour recommander des publications appropriées aux utilisateurs. Les étapes spécifiques sont les suivantes :

  1. Pour les utilisateurs cibles, sélectionnez les sujets qu'ils suivent, les publications et autres contenus.
  2. Sur la base de ces contenus, la similitude de chaque publication avec les intérêts de l'utilisateur cible est calculée.
  3. Sélectionnez les N publications les plus similaires aux intérêts de l'utilisateur cible.
  4. Triez par score de haut en bas et sélectionnez les meilleurs messages M avec les scores les plus élevés comme résultats recommandés.

Ce qui suit est l'implémentation du code Java de l'algorithme de recommandation basé sur le contenu :

public class ContentBasedRecommendation {

    /**
     * 计算两个向量的余弦相似度
     * @param v1 向量1
     * @param v2 向量2
     * @return 余弦相似度
     */
    public double cosineSimilarity(double[] v1, double[] v2) {
        double dotProduct = 0;
        double norma = 0;
        double normb = 0;
        for (int i = 0; i < v1.length; i++) {
            dotProduct += v1[i] * v2[i];
            norma += Math.pow(v1[i], 2);
            normb += Math.pow(v2[i], 2);
        }
        if (norma == 0 || normb == 0)
            return 0;
        return dotProduct / (Math.sqrt(norma) * Math.sqrt(normb));
    }

    /**
     * 基于内容的推荐算法
     * @param data 数据集
     * @param userId 目标用户 ID
     * @param N 推荐的 N 个帖子
     * @return 推荐的帖子 ID 列表
     */
    public List<Integer> contentBasedRecommendation(Map<Integer, Map<Integer, Double>> data,
                                                     int userId, int N) {
        Map<Integer, Double> targetUser = data.get(userId); // 目标用户
        int[] pickedItems = new int[data.size()];
        double[][] itemFeatures = new double[pickedItems.length][24]; // 物品特征矩阵
        for (Map.Entry<Integer, Map<Integer, Double>> entry: data.entrySet()) {
            int itemId = entry.getKey();
            Map<Integer, Double> item = entry.getValue();
            double[] feature = new double[24];
            for (int i = 0; i < feature.length; i++) {
                if (item.containsKey(i+1)) {
                    feature[i] = item.get(i+1);
                } else {
                    feature[i] = 0;
                }
            }
            itemFeatures[itemId-1] = feature; // 物品 ID 从 1 开始,需要减一
        }
        for (int itemId: targetUser.keySet()) {
            pickedItems[itemId-1] = 1; // 物品 ID 从 1 开始,需要减一
        }
        double[] similarities = new double[pickedItems.length];
        for (int i = 0; i < similarities.length; i++) {
            if (pickedItems[i] == 0) {
                similarities[i] = cosineSimilarity(targetUser.values().stream().mapToDouble(Double::doubleValue).toArray(), itemFeatures[i]);
            }
        }
        List<Integer> itemIds = new ArrayList<>();
        while (itemIds.size() < N) {
            int maxIndex = -1;
            for (int i = 0; i < similarities.length; i++) {
                if (pickedItems[i] == 0 && (maxIndex == -1 || similarities[i] > similarities[maxIndex])) {
                    maxIndex = i;
                }
            }
            if (maxIndex == -1 || similarities[maxIndex] < 0) {
                break; // 找不到更多相似的物品了
            }
            itemIds.add(maxIndex + 1); // 物品 ID 从 1 开始,需要加一
            pickedItems[maxIndex] = 1;
        }
        Map<Integer, Double> scores = new HashMap<>();
        for (int itemId: itemIds) {
            double[] features = itemFeatures[itemId-1]; // 物品 ID 从 1 开始,需要减一
            double score = cosineSimilarity(targetUser.values().stream().mapToDouble(Double::doubleValue).toArray(), features);
            scores.put(itemId, score);
        }
        List<Integer> pickedItemIds = new ArrayList<>();
        scores.entrySet().stream().sorted((a, b) -> b.getValue().compareTo(a.getValue()))
                .limit(N).forEach(entry -> pickedItemIds.add(entry.getKey())); // 按得分从高到低排序并选出前N个
        return pickedItemIds;
    }
}

5 Intégrez l'algorithme de recommandation dans l'application

#. 🎜🎜#In Après avoir terminé la mise en œuvre des deux algorithmes de recommandation ci-dessus, nous pouvons les intégrer dans l'application. Les étapes spécifiques sont les suivantes :

    Chargez les données et stockez-les dans la base de données. Nous pouvons utiliser des frameworks ORM tels que Hibernate pour simplifier l'opération d'accès à la base de données.
  1. Définissez une API RESTful qui accepte les requêtes HTTP et renvoie les réponses au format JSON. Nous pouvons utiliser Spring Framework pour créer et déployer des API RESTful.
  2. Implémentez des algorithmes de recommandation de filtrage collaboratif basés sur l'utilisateur et de recommandation basée sur le contenu et intégrez-les dans l'API RESTful.
Ce qui suit est l'implémentation du code Java de l'application :

@RestController
@RequestMapping("/recommendation")
public class RecommendationController {

    private CollaborativeFiltering collaborativeFiltering = new CollaborativeFiltering();
    private ContentBasedRecommendation contentBasedRecommendation = new ContentBasedRecommendation();

    @Autowired
    private UserService userService;

    @GetMapping("/userbased/{userId}")
    public List<Integer> userBasedRecommendation(@PathVariable Integer userId) {
        List<User> allUsers = userService.getAllUsers();
        Map<Integer, Map<Integer, Double>> data = new HashMap<>();
        for (User user: allUsers) {
            Map<Integer, Double> userVector = new HashMap<>();
            List<Topic> followedTopics = user.getFollowedTopics();
            for (Topic topic: followedTopics) {
                userVector.put(topic.getId(), 1.0);
            }
            List<Post> posts = user.getPosts();
            for (Post post: posts) {
                userVector.put(post.getId() + 1000, 1.0);
            }
            List<Comment> comments = user.getComments();
            for (Comment comment: comments) {
                userVector.put(comment.getId() + 2000, 1.0);
            }
            List<Like> likes = user.getLikes();
            for (Like like: likes) {
                userVector.put(like.getId() + 3000, 1.0);
            }
            data.put(user.getId(), userVector);
        }
        List<Integer> itemIds = collaborativeFiltering.userBasedCollaborativeFiltering(data, userId, 5, 10);
        return itemIds;
    }

    @GetMapping("/contentbased/{userId}")
    public List<Integer> contentBasedRecommendation(@PathVariable Integer userId) {
        List<User> allUsers = userService.getAllUsers();
        Map<Integer, Map<Integer, Double>> data = new HashMap<>();
        for (User user: allUsers) {
            Map<Integer, Double> userVector = new HashMap<>();
            List<Topic> followedTopics = user.getFollowedTopics();
            for (Topic topic: followedTopics) {
                userVector.put(topic.getId(), 1.0);
            }
            List<Post> posts = user.getPosts();
            for (Post post: posts) {
                userVector.put(post.getId() + 1000, 1.0);
            }
            List<Comment> comments = user.getComments();
            for (Comment comment: comments) {
                userVector.put(comment.getId() + 2000, 1.0);
            }
            List<Like> likes = user.getLikes();
            for (Like like: likes) {
                userVector.put(like.getId() + 3000, 1.0);
            }

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn