Heim  >  Artikel  >  Java  >  So schreiben Sie eine auf einem Empfehlungssystem basierende soziale Netzwerkanwendung mit Java

So schreiben Sie eine auf einem Empfehlungssystem basierende soziale Netzwerkanwendung mit Java

WBOY
WBOYOriginal
2023-06-27 08:32:141149Durchsuche

In modernen sozialen Netzwerkanwendungen sind Empfehlungssysteme zu einer wesentlichen Funktion geworden. Ob es darum geht, Benutzern Freunde zu empfehlen, interessante Themen zu empfehlen, verwandte Produkte zu empfehlen oder wertvollere Inhalte zu empfehlen, Empfehlungssysteme können die Benutzererfahrung und Bindungsfähigkeit effektiv verbessern.

In diesem Artikel stellen wir vor, wie man mit Java eine auf einem Empfehlungssystem basierende Anwendung für soziale Netzwerke schreibt. Wir kombinieren tatsächlichen Code und detaillierte Schritte, um den Lesern zu helfen, ein grundlegendes Empfehlungssystem schnell zu verstehen und zu implementieren.

1. Datenerhebung und -verarbeitung

Bevor wir ein Empfehlungssystem implementieren, müssen wir eine große Datenmenge sammeln und verarbeiten. In sozialen Netzwerkanwendungen sind Benutzerinformationen, Beiträge, Kommentare, Likes und andere Daten wertvolle Datenquellen.

Um die Demonstration zu erleichtern, können wir einen virtuellen Open-Source-Datengenerator verwenden, um diese Daten zu generieren. Die spezifischen Schritte sind wie folgt:

  1. Laden Sie einen virtuellen Datengenerator herunter und installieren Sie ihn, wie z. B. Mockaroo (https://www.mockaroo.com/).
  2. Definieren Sie die Datensätze, die generiert werden müssen, einschließlich Benutzerinformationen, Beiträge, Kommentare usw.
  3. Daten generieren und in eine CSV-Datei exportieren.
  4. Verwenden Sie Java-Code, um die Daten in der CSV-Datei zu lesen und in der Datenbank zu speichern. Wir können gängige relationale Datenbanken wie MySQL und Oracle zum Speichern von Daten verwenden. Hier verwenden wir MySQL 8.0 als Datenbank zur Datenspeicherung.

2. Darstellung von Benutzern und Artikeln

Im Empfehlungssystem müssen wir Benutzer und Artikel in Vektor- oder Matrixform umwandeln, um ihre Ähnlichkeit zu berechnen oder Empfehlungen abzugeben. In Anwendungen für soziale Netzwerke können wir die folgenden Methoden verwenden, um Benutzer und Elemente darzustellen:

  1. Benutzervektor: Wir können Daten wie die Themen, denen der Benutzer folgt, veröffentlichte Beiträge, Freunde, mit denen er interagiert usw., verwenden, um die eines Benutzers darzustellen Vektor. Wenn beispielsweise ein Benutzer A den Themen Java, Python, JavaScript usw. folgt, „Wie man Java gut lernt“ und „Erste Schritte mit Java“ postet und mit den Benutzern B und C interagiert, dann können wir den folgenden Vektor verwenden um Benutzer A darzustellen:

Benutzer 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]

wobei die Vektorlänge 24 beträgt und jede Position ein Thema oder einen Beitrag darstellt. 1 bedeutet, dass Benutzer A dem Thema gefolgt ist oder den Beitrag veröffentlicht hat, und 0 bedeutet nicht.

  1. Elementvektor: Wir können die Tags, Inhalte, Kommentare und andere Daten jedes Beitrags verwenden, um den Vektor eines Beitrags darzustellen. Wenn ein Beitrag beispielsweise mit „Java, Programmierung“ getaggt ist und der Inhalt „Vier Vorschläge zum Erlernen der Java-Programmierung“ lautet und 10 Kommentare enthält, können wir den folgenden Vektor verwenden, um den Beitrag darzustellen:

Beitrag 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]

wo Die Vektorlänge beträgt 24 und jede Position repräsentiert eine Beschriftung oder statistische Daten. 1 bedeutet, dass der Beitrag das Tag oder den Inhalt enthält, 0 bedeutet, dass dies nicht der Fall ist.

3. Benutzerbasierte kollaborative Filterempfehlung

Benutzerbasierte kollaborative Filterung ist eine gängige Methode in Empfehlungssystemen. Sie empfiehlt Elemente basierend auf der Ähnlichkeit der Benutzerinteressen. Dabei nutzen wir nutzerbasierte kollaborative Filterung, um Nutzern passende Beiträge zu empfehlen. Die spezifischen Schritte sind wie folgt:

  1. Berechnen Sie die Ähnlichkeit zwischen Benutzern. Hier verwenden wir den Pearson-Korrelationskoeffizienten als Ähnlichkeitsmetrik.
  2. Wählen Sie K Benutzer aus, deren Interessen denen der Zielbenutzer am ähnlichsten sind.
  3. Wählen Sie für jeden Benutzer N Beiträge aus, die ihm gefallen, aber von den Zielbenutzern nicht gesehen wurden.
  4. Berechnen Sie für die ausgewählten N Beiträge den Empfehlungswert jedes Beitrags und sortieren Sie sie von hoch nach niedrig.
  5. Wählen Sie die Top-M-Beiträge mit den höchsten Punktzahlen als empfohlene Ergebnisse aus.

Das Folgende ist die Java-Code-Implementierung dieses Algorithmus:

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. Inhaltsbasierter Empfehlungsalgorithmus

Der inhaltsbasierte Empfehlungsalgorithmus ist eine weitere gängige Methode in Empfehlungssystemen. Er empfiehlt Artikel basierend auf der Ähnlichkeit von Artikelattributen. . Dabei nutzen wir einen inhaltsbasierten Empfehlungsalgorithmus, um Nutzern passende Beiträge zu empfehlen. Die spezifischen Schritte sind wie folgt:

  1. Wählen Sie für Zielbenutzer die Themen, Beiträge und anderen Inhalte aus, denen sie folgen.
  2. Berechnen Sie anhand dieser Inhalte die Ähnlichkeit jedes Beitrags mit den Interessen des Zielbenutzers.
  3. Wählen Sie die Top-N-Beiträge aus, die den Interessen des Zielbenutzers am ähnlichsten sind.
  4. Sortieren Sie nach Punktzahlen von hoch nach niedrig und wählen Sie die Top-M-Beiträge mit den höchsten Punktzahlen als empfohlene Ergebnisse aus.

Das Folgende ist die Java-Code-Implementierung des inhaltsbasierten Empfehlungsalgorithmus:

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. Integrieren Sie den Empfehlungsalgorithmus in die Anwendung.

Nach Abschluss der Implementierung der beiden oben genannten Empfehlungsalgorithmen können wir sie in die Anwendung integrieren . Die spezifischen Schritte sind wie folgt:

  1. Daten laden und in der Datenbank speichern. Wir können ORM-Frameworks wie Hibernate verwenden, um den Zugriff auf die Datenbank zu vereinfachen.
  2. Definieren Sie eine RESTful-API, die HTTP-Anfragen akzeptiert und Antworten im JSON-Format zurückgibt. Wir können Spring Framework verwenden, um RESTful-APIs zu erstellen und bereitzustellen.
  3. Implementieren Sie benutzerbasierte kollaborative Filterempfehlungen und inhaltsbasierte Empfehlungsalgorithmen und integrieren Sie diese in die RESTful-API.

Hier ist die Java-Code-Implementierung der Anwendung:

@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);
            }

Das obige ist der detaillierte Inhalt vonSo schreiben Sie eine auf einem Empfehlungssystem basierende soziale Netzwerkanwendung mit Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn