当前位置: 首页 > news >正文

深入解析人工智能中的协同过滤算法及其在推荐系统中的应用与优化

CSDN


目录

  • 什么是协同过滤
  • 算法核心原理
    • 基本步骤
    • 相似度计算
    • 代码实现详解
      • 1.流程图
      • 2.创建基础的数据结构存储用户评分数据
      • 3.计算用户相似度
      • 4.获取相似用户
      • 5.推荐方法
  • 算法优化建议
    • 1. 数据预处理优化
      • 去除异常值和噪声数据
      • 进行数据标准化
      • 使用稀疏矩阵优化存储
    • 2. 相似度计算优化
      • 使用局部敏感哈希 (LSH) 加速相似度计算
      • 预计算并缓存用户相似度矩阵
      • 使用其他相似度度量方法(如皮尔逊相关系数)
    • 3. 推荐结果优化
      • 引入时间衰减因子
      • 考虑用户行为权重
      • 添加多样性考虑
  • 实际应用场景
    • 1. 电商推荐
    • 2. 内容平台
    • 3. 社交网络
  • 性能分析与评估
    • 1. 性能分析
      • 时间复杂度
    • 2. 评价指标
  • 与其他推荐算法的对比与结合
    • 1. 对比
      • 基于内容的推荐
    • 2. 结合
  • 使用示例
    • 预测结果
      • 用户评分数据
      • 计算用户 1 与其他用户的相似度:
        • 用户 1 和用户 2 的相似度
        • 用户 1 和用户 3 的相似度
        • 寻找相似用户
        • 生成推荐:
        • 最终推荐:
  • 总结

什么是协同过滤

协同过滤 (Collaborative Filtering,简称 CF) 是推荐系统中最经典、最常用的算法之一。其核心思想是:“物以类聚,人以群分”。具体来说,就是根据用户过去的行为、偏好,以及其他用户的相似行为,来预测用户可能感兴趣的内容。
协同过滤主要分为两大类:

  • 基于用户的协同过滤(User-Based
    CF):该方法是通过寻找与目标用户具有相似偏好的其他用户,将这些相似用户喜欢的物品推荐给目标用户。其假设是相似用户的偏好具有相似性,通过挖掘用户之间的相似性,可以利用相似用户的行为信息来填补目标用户的信息空白,进而生成推荐。
  • 基于物品的协同过滤(Item-Based
    CF):该方法侧重于物品之间的相似性,认为用户可能会喜欢那些与他们之前喜欢的物品相似的物品。通过分析物品之间的相似度,根据用户的历史喜好物品,为用户推荐与之相似的其他物品。

下图展示了使用协同过滤预测用户喜好的过程。通过分析其他用户的行为,最终目的是预测当前用户的偏好。在预测结果中,当前用户与第2和第3个用户在前两个问题上的行为相似,因此推测他也不喜欢看视频。
演示
可以得出结论:如果两个用户在过去的行为中表现出相似的偏好,那么他们未来的偏好也可能相似。

本文将重点介绍基于用户的协同过滤算法实现。

算法核心原理

基本步骤

  1. 收集用户行为数据(如评分、点击、购买等):
    • 这是算法的基础,数据的完整性和准确性对推荐结果有重要影响。用户行为数据可以从多种渠道收集,例如用户在电商平台上的购买记录、在视频网站上的观看记录、对产品的评分以及对文章的点赞和评论等。这些数据可以用矩阵的形式存储,行表示用户,列表示物品,矩阵中的元素表示用户对物品的行为度量,如评分。
  2. 计算用户之间的相似度:
    • 相似度的计算是关键步骤,它反映了用户之间偏好的相似程度。通过相似度计算,我们可以找出哪些用户与目标用户最为相似,从而利用他们的行为信息为目标用户提供推荐。
  3. 找到目标用户的相似用户群:
    • 这一步是根据计算出的相似度,选取与目标用户最相似的一批用户。相似用户的选择可以根据具体业务需求设定阈值或选取相似度排名靠前的用户,其数量也可根据实际情况调整。
  4. 根据相似用户的行为为目标用户生成推荐:
    • 一旦找到相似用户,我们可以观察他们的行为,找出他们喜欢但目标用户尚未与之交互的物品,将这些物品推荐给目标用户。推荐物品的选择和排序可以根据相似用户对这些物品的喜好程度以及与目标用户的相似度进行加权计算。

相似度计算

最常用的相似度计算方法是余弦相似度

similarity = cos ⁡ ( θ ) = A ⋅ B ∣ ∣ A ∣ ∣ ⋅ ∣ ∣ B ∣ ∣ \text{similarity} = \cos(\theta) = \frac{A \cdot B}{||A|| \cdot ||B||} similarity=cos(θ)=∣∣A∣∣∣∣B∣∣AB

余弦相似度的优点在于其可以有效地度量两个向量的相似性,并且对于向量的长度不敏感,只考虑向量的方向。在协同过滤中,向量通常表示用户对不同物品的评分或偏好,通过计算向量之间的夹角余弦来衡量用户之间的相似性。

代码实现详解

1.流程图

开始
创建 UserCF 类
初始化 userRatings 为 HashMap
添加用户评分 addUserRating
计算用户相似度 calculateSimilarity
获取两个用户的评分数据
找出共同评分物品
计算点积和模长
计算余弦相似度
判断是否有共同评分物品或模长为 0
相似度为 0
计算并存储相似度
获取相似用户 findSimilarUsers
计算目标用户与其他用户的相似度
存储相似度
按相似度降序排序并取前 N 个用户
生成推荐 recommendItems
获取相似用户列表
收集目标用户未评分物品
移除目标用户已评分物品
计算物品加权评分
计算加权评分和相似度总和
计算最终预测评分
按预测评分降序排序并取前 numItems 个物品
结束

2.创建基础的数据结构存储用户评分数据

首先,我们创建一个基础的数据结构来存储用户评分数据:
这里使用了 Map<Integer, Map<Integer, Double>> 的数据结构,外层的 Map 以用户 ID 为键,内层的 Map 以物品 ID 为键,存储用户对物品的评分。addUserRating 方法确保对于每个用户,我们可以方便地添加新的物品评分。

import java.util.*;public class UserCF {// 用户评分数据结构private Map<Integer, Map<Integer, Double>> userRatings;public UserCF() {userRatings = new HashMap<>();}// 添加用户评分public void addUserRating(int userId, int itemId, double rating) {userRatings.computeIfAbsent(userId, k -> new HashMap<>()).put(itemId, rating);}
}

3.计算用户相似度

接下来实现计算用户相似度的方法:
在 calculateSimilarity 方法中,首先获取两个用户的评分数据,找出他们共同评分的物品。然后计算这些共同评分物品的点积和各自的模长,最后计算余弦相似度。如果两个用户没有共同评分的物品,或者其中一个用户的评分向量的模长为 0,则认为他们的相似度为 0。

public class UserCF {//... 前面的代码省略/*** 计算两个用户之间的余弦相似度* @param user1 第一个用户的 ID* @param user2 第二个用户的 ID* @return 两个用户的余弦相似度,值范围为 [-1, 1],0 表示完全不相似*/private double calculateSimilarity(int user1, int user2) {// 获取两个用户的评分数据Map<Integer, Double> ratings1 = userRatings.get(user1);Map<Integer, Double> ratings2 = userRatings.get(user2);// 找到两个用户共同评分的物品Set<Integer> commonItems = new HashSet<>(ratings1.keySet());commonItems.retainAll(ratings2.keySet());// 如果没有共同评分的物品,返回相似度为 0if (commonItems.isEmpty()) {return 0.0;}// 计算点积、第一用户的评分向量的模长、第二用户的评分向量的模长double dotProduct = 0.0;double norm1 = 0.0;double norm2 = 0.0;// 遍历共同评分的物品for (Integer item : commonItems) {// 获取两个用户在该物品上的评分double r1 = ratings1.get(item);double r2 = ratings2.get(item);// 计算点积dotProduct += r1 * r2;// 计算第一用户评分向量的模长的平方norm1 += r1 * r1;// 计算第二用户评分向量的模长的平方norm2 += r2 * r2;}// 计算余弦相似度:点积除以两向量的模长乘积// 如果任一用户的评分向量模长为零(即该用户没有评分),返回相似度为 0if (norm1 == 0.0 || norm2 == 0.0) {return 0.0;}// 返回两个用户的余弦相似度return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));}
}

4.获取相似用户

实现获取相似用户的方法:
findSimilarUsers 方法会计算目标用户和其他所有用户的相似度,将结果存储在 similarities 映射中,然后使用 Java 8 的 Stream 流对相似度进行降序排序,最终选取前 n 个用户作为最相似用户。

public class UserCF {//... 前面的代码省略/*** 获取与目标用户最相似的 N 个用户* @param userId 目标用户的 ID* @param n 返回最相似的 N 个用户* @return 一个包含与目标用户最相似的 N 个用户 ID 的列表*/public List<Integer> findSimilarUsers(int userId, int n) {// 创建一个 Map 用于存储其他用户与目标用户的相似度Map<Integer, Double> similarities = new HashMap<>();// 计算目标用户与其他所有用户的相似度for (int otherUserId : userRatings.keySet()) {// 忽略与目标用户本身的相似度计算if (otherUserId != userId) {// 计算目标用户与其他用户的相似度double similarity = calculateSimilarity(userId, otherUserId);// 将计算出的相似度存储到 similarities 中similarities.put(otherUserId, similarity);}}// 按相似度降序排序,返回前 N 个用户return similarities.entrySet().stream()// 使用 Map.Entry 的值(相似度)进行降序排序.sorted(Map.Entry.<Integer, Double>comparingByValue().reversed())// 只取前 N 个最相似的用户.limit(n)// 提取排序后的用户 ID.map(Map.Entry::getKey)// 收集为一个列表.collect(Collectors.toList());}
}

5.推荐方法

最后实现推荐方法
在 recommendItems 方法中,首先找到相似用户,然后找出目标用户未评分的物品作为候选推荐物品。接着计算这些物品的加权评分,加权评分是相似用户对物品的评分乘以该用户与目标用户的相似度。最后,将每个物品的加权评分相加除以相似度之和得到预测评分,将预测评分排序并选取前 numItems 个物品作为推荐结果。

public class UserCF {//... 前面的代码省略/*** 为用户生成推荐* @param userId 目标用户的 ID* @param numUsers 使用的最相似用户数量* @param numItems 推荐的物品数量* @return 推荐的物品 ID 列表*/public List<Integer> recommendItems(int userId, int numUsers, int numItems) {// 获取与目标用户最相似的 N 个用户List<Integer> similarUsers = findSimilarUsers(userId, numUsers);// 收集目标用户未评分的物品Set<Integer> candidateItems = new HashSet<>();Set<Integer> userItems = userRatings.get(userId).keySet();// 遍历所有相似用户,收集他们评分过的物品for (int similarUser : similarUsers) {candidateItems.addAll(userRatings.get(similarUser).keySet());}// 移除目标用户已经评分过的物品candidateItems.removeAll(userItems);// 计算物品的加权评分Map<Integer, Double> itemScores = new HashMap<>();Map<Integer, Double> itemSimilaritySum = new HashMap<>();// 遍历所有相似用户,计算每个物品的加权评分和相似度总和for (int similarUser : similarUsers) {double similarity = calculateSimilarity(userId, similarUser);Map<Integer, Double> ratings = userRatings.get(similarUser);// 对每个候选物品,如果相似用户评分过该物品,则根据相似度加权评分for (int item : candidateItems) {if (ratings.containsKey(item)) {// 加权评分:评分 * 相似度itemScores.merge(item, ratings.get(item) * similarity, Double::sum);// 累加该物品的相似度总和itemSimilaritySum.merge(item, similarity, Double::sum);}}}// 计算最终预测评分并排序return itemScores.entrySet().stream()// 计算最终的推荐分数:物品的加权评分 / 物品的相似度总和.map(entry -> {int item = entry.getKey();double score = entry.getValue() / itemSimilaritySum.get(item);return Map.entry(item, score);})// 根据分数降序排序.sorted(Map.Entry.<Integer, Double>comparingByValue().reversed())// 取前 N 个推荐物品.limit(numItems)// 提取物品的 ID.map(Map.Entry::getKey)// 收集为推荐物品的列表并返回.collect(Collectors.toList());}
}

算法优化建议

1. 数据预处理优化

去除异常值和噪声数据

  • 异常值处理:对于评分数据或其他行为数据,常见的异常值如极端的评分或不合理的互动频次。可以通过 Z-score 或箱线图方法,首先检测数据集中每个用户评分或行为的偏离程度。对于 Z-score,大于 3 或小于 -3 的数据点通常视为异常值;箱线图则使用 IQR (Interquartile Range) 方法,即 Q3 + 1.5 * IQR 或 Q1 - 1.5 * IQR,数据超出此范围的值视为异常值。
  • 噪声数据去除:除了异常值,噪声数据(如误输入或系统性错误)也会影响模型准确性。可以结合领域知识,定义一些清洗规则(例如,去除评分为负数或超过最大评分值的数据)。此外,还可以通过聚类方法来检测和消除噪声。

进行数据标准化

  • 标准化方法:数据的尺度差异可能导致某些特征在计算相似度时占主导地位。因此,可以使用以下几种标准化方法:

    • Z-score 标准化:用于数据符合高斯分布的情况,将每个数据点减去均值并除以标准差,使数据均值为 0,标准差为 1。
    • Min-Max 标准化:将数据映射到 [0,1] 范围内。适用于数据的最小值和最大值已知的场景,确保数据不会受极端值的影响。

    对于稀疏数据,标准化操作需谨慎,避免破坏原有数据结构。

使用稀疏矩阵优化存储

  • 稀疏矩阵的优势:由于推荐系统的数据通常高度稀疏(例如用户对物品的评分数据),使用稀疏矩阵不仅可以减少内存消耗,还能提高计算效率。对于大规模推荐系统,可以使用专门的稀疏矩阵库(如 SciPy 的 sparse 模块或 Apache Spark 的 MLlib)来处理。
  • 稀疏矩阵存储策略:采用压缩存储格式(如 CSR 或 CSC 格式)进一步优化内存使用,并根据实际需求选择合适的存储形式。

2. 相似度计算优化

使用局部敏感哈希 (LSH) 加速相似度计算

  • LSH 的应用:当数据集很大时,计算用户或物品之间的相似度是一个计算密集型操作。LSH 通过将相似的对象映射到相同的哈希桶中,从而减少计算量,适合于高维稀疏数据的近似搜索。LSH 在降低计算复杂度的同时,仍能保持一定的相似度准确性,尤其适用于大规模推荐系统。

预计算并缓存用户相似度矩阵

  • 预计算的适用场景:对于静态数据集,用户相似度矩阵的计算是相对稳定的。可以定期(例如每日或每周)计算并缓存相似度矩阵,减少每次推荐时重复计算的时间成本。
  • 缓存策略:使用高效的缓存机制(如 Redis)来存储相似度矩阵,避免多次计算带来的性能瓶颈。

使用其他相似度度量方法(如皮尔逊相关系数)

  • 皮尔逊相关系数:皮尔逊相关系数是一种衡量线性相关性的常用方法,适用于评分数据之间的比较。在一些场景中,皮尔逊相关系数可以更准确地反映用户偏好的相似性,特别是考虑到用户评分的偏差时。例如,用户评分的倾向可能不同(如某些用户偏向高分),而皮尔逊相关系数可以消除这种偏差。
  • 余弦相似度与皮尔逊相关系数的比较:余弦相似度通常用于衡量两个向量的方向相似度,而皮尔逊相关系数则更多地关注评分的线性关系。两者可根据具体需求选择使用。

3. 推荐结果优化

引入时间衰减因子

  • 时间衰减因子:用户的兴趣随时间变化,因此应给最近的行为更多权重。可以通过引入时间衰减因子来模拟时间对用户行为的重要性,通常采用指数衰减(如 e^(-λt))或线性衰减模型来调整历史行为对推荐结果的影响。

考虑用户行为权重

  • 行为权重:不同类型的行为对推荐结果的影响不同。例如,购买行为可能比浏览行为更能反映用户的真实偏好。可以根据行为的类型或重要性为不同的行为分配不同的权重。权重的设定可以基于业务需求,结合用户行为分析的结果来优化推荐效果。

添加多样性考虑

  • 多样性控制:为避免推荐结果过于单一,可以在推荐系统中引入多样性考虑。例如,限制同一类别的物品推荐数量,或者采用基于多样性的算法(如 MMR)。MMR(Maximal Marginal Relevance)算法通过综合考虑物品的相关性和多样性,优化推荐结果的多样性。
  • 多样性度量:除了基于类别的多样性,还可以从内容、评分、物品特征等维度来增加推荐结果的多样性。例如,在推荐的电影中,可以增加不同类型、不同评分范围的电影。

实际应用场景

协同过滤算法在多个领域都有广泛应用:

1. 电商推荐

  • 商品推荐:根据用户的购买和浏览历史,利用协同过滤为用户推荐他们可能感兴趣的商品。通过分析用户的历史行为,算法可以发现潜在的兴趣关联,并为用户推送个性化的商品推荐。
  • 相关商品推荐:当用户查看某个商品时,推荐与之相似的商品。通过计算商品之间的相似度,协同过滤可以帮助用户发现类似的商品,从而提高用户的购物体验。
  • 购物车推荐:通过分析用户已添加至购物车的商品,推荐他们可能会添加的其他商品。该推荐旨在提高购买转化率,增加购物车中的商品数量。

2. 内容平台

  • 视频推荐:根据用户的观看记录和偏好,为用户推荐他们可能喜欢的视频。协同过滤通过分析用户观看的历史视频及其评分,找到与用户兴趣相符的视频内容,进行个性化推荐。
  • 音乐推荐:向用户推荐他们可能感兴趣的音乐,根据用户的收藏、播放历史等数据进行分析。例如,用户喜欢的歌手、音乐风格或相似的音乐类型,可以帮助推荐系统推送符合其喜好的歌曲。
  • 新闻推荐:根据用户的阅读习惯和偏好,为其推送相关的新闻文章。通过分析用户的历史阅读记录,协同过滤可以识别用户关注的主题或领域,并提供个性化的新闻内容。

3. 社交网络

  • 好友推荐:基于用户的社交关系和共同兴趣,推荐可能认识的新朋友。通过分析用户现有的社交网络,以及共同的兴趣和行为,协同过滤帮助平台为用户找到潜在的好友,促进社交互动。
  • 内容推荐:根据用户的兴趣、点赞、评论等行为,推荐可能感兴趣的帖子、动态等内容。该推荐不仅基于用户的历史行为,也可以通过分析社交网络中的互动,推送更贴近用户兴趣的内容。
  • 话题推荐:根据用户的话题参与情况,推荐他们可能感兴趣的新话题。协同过滤可以识别用户在不同话题中的互动频率,并根据这些兴趣点推荐新的讨论话题,提高用户参与度。

性能分析与评估

1. 性能分析

时间复杂度

  • 相似度计算的时间复杂度:计算相似度的时间复杂度取决于用户数量和物品数量,对于 n 个用户和 m 个物品,计算每对用户之间的相似度的时间复杂度为 O(n * m)。这是因为需要遍历每个用户对所有评分的物品,计算它们之间的相似度。在大规模数据集上,尤其当用户数和物品数都很大时,计算成本较高。

  • 推荐过程的时间复杂度:在推荐过程中,查找相似用户并计算推荐物品的时间复杂度也相对较高。具体来说,对于每个用户,需要查找与其相似的其他用户或物品,并基于这些相似用户的行为来预测推荐物品。随着数据集的增大,查找和计算的复杂度会迅速增加。因此,在大规模数据集上,性能优化至关重要。

2. 评价指标

  • 精确率(Precision):精确率衡量推荐结果中用户实际感兴趣的物品的比率。计算公式为:
    P r e c i s i o n = 推荐结果中用户实际喜欢的物品数 推荐结果的物品数量 Precision = \frac{推荐结果中用户实际喜欢的物品数}{推荐结果的物品数量} Precision=推荐结果的物品数量推荐结果中用户实际喜欢的物品数
    精确率高意味着推荐系统的推荐结果更为准确,用户能看到更多他们喜欢的物品。

  • 召回率(Recall):召回率衡量用户实际感兴趣的物品被推荐出来的比例。计算公式为:
    R e c a l l = 推荐结果中用户实际喜欢的物品数 用户实际喜欢的物品总数 Recall = \frac{推荐结果中用户实际喜欢的物品数}{用户实际喜欢的物品总数} Recall=用户实际喜欢的物品总数推荐结果中用户实际喜欢的物品数
    召回率高表示推荐系统能够覆盖更多用户感兴趣的物品,即尽可能少地遗漏用户潜在的喜好。

  • F1 Score:F1 Score 是精确率和召回率的调和平均值,综合考虑了准确率和召回率。它是一个衡量模型整体性能的重要指标,公式为:
    F 1 = 2 × P r e c i s i o n × R e c a l l P r e c i s i o n + R e c a l l F1 = 2 \times \frac{Precision \times Recall}{Precision + Recall} F1=2×Precision+RecallPrecision×Recall
    F1 Score 较高表示模型在推荐中既能够准确推荐物品,又能够覆盖更多用户可能感兴趣的物品。

通过精确率、召回率和 F1 Score 的综合评估,能够更全面地衡量推荐系统的性能和效果。

与其他推荐算法的对比与结合

1. 对比

基于内容的推荐

  • 协同过滤 vs 基于内容的推荐

    • 协同过滤:依赖于用户行为数据,通过计算用户之间或物品之间的相似性进行推荐。推荐的依据是用户的历史行为数据,如评分、购买记录等。
    • 基于内容的推荐:依据物品的属性(如类别、标签、描述等)和用户的偏好特征进行推荐,不依赖用户的历史行为。这种方法基于物品的内容信息进行推荐,通常用于物品之间的相似度计算。
  • 冷启动问题

    • 协同过滤:在面对新用户或新物品时,可能会遇到冷启动问题,因为系统缺乏足够的用户行为数据来进行推荐。
    • 基于内容的推荐:可以缓解冷启动问题。对于新物品,可以通过物品的属性进行推荐;对于新用户,可以根据用户的初始偏好特征来进行推荐,无需过多依赖历史行为数据。

2. 结合

  • 混合推荐系统:将协同过滤和基于内容的推荐结合起来,形成一个混合推荐系统,可以充分利用两者的优点:
    • 初步推荐和筛选:先使用协同过滤为用户生成初步推荐,再使用基于内容的推荐对推荐结果进行筛选和调整。这种方法能够提高推荐结果的多样性和准确性,同时避免协同过滤因冷启动问题带来的不足。
    • 新用户推荐:对于新用户,可以首先使用基于内容的推荐进行初步推荐,根据用户的偏好特征来选择推荐的物品。随着用户的行为数据逐步积累,可以逐渐引入协同过滤进行更个性化的推荐,提升推荐的精度和个性化程度。

通过结合协同过滤和基于内容的推荐,能够更好地解决冷启动问题,并提高推荐系统的准确性和多样性。

使用示例

public class Example {public static void main(String[] args) {UserCF cf = new UserCF();// 添加用户评分数据cf.addUserRating(1, 1, 5.0);cf.addUserRating(1, 2, 3.0);cf.addUserRating(1, 3, 4.0);cf.addUserRating(2, 1, 3.0);cf.addUserRating(2, 2, 4.0);cf.addUserRating(3, 1, 4.0);cf.addUserRating(3, 3, 5.0);// 为用户 1 生成推荐List<Integer> recommendations = cf.recommendItems(1, 2, 5);System.out.println("Recommended items: " + recommendations);}
}

预测结果

用户评分数据

用户 ID物品 1 评分物品 2 评分物品 3 评分
15.03.04.0
23.04.0-
34.0-5.0
  • 用户 1 对物品 1 评分为 5.0,对物品 2 评分为 3.0,对物品 3 评分为 4.0。
  • 用户 2 对物品 1 评分为3.0,对物品 2 评分为 4.0。
  • 用户 3 对物品 1 评分为 4.0,对物品 3 评分为 5.0。

计算用户 1 与其他用户的相似度:

用户 1 和用户 2 的相似度
  • 共同评分物品为物品 1 和物品 2。
  • 对于物品 1:用户 1 评分为 5.0,用户 2 评分为 3.0。
  • 对于物品 2:用户 1 评分为 3.0,用户 2 评分为 4.0。
  • 计算点积: ( 5.0 × 3.0 ) + ( 3.0 × 4.0 ) = 15.0 + 12.0 = 27.0 (5.0 \times 3.0) + (3.0 \times 4.0) = 15.0 + 12.0 = 27.0 (5.0×3.0)+(3.0×4.0)=15.0+12.0=27.0
  • 计算用户 1 的范数: ( 5.0 × 5.0 ) + ( 3.0 × 3.0 ) = 25.0 + 9.0 = 34.0 \sqrt{(5.0 \times 5.0) + (3.0 \times 3.0)} = \sqrt{25.0 + 9.0} = \sqrt{34.0} (5.0×5.0)+(3.0×3.0) =25.0+9.0 =34.0
  • 计算用户 2 的范数:
    ( 3.0 × 3.0 ) + ( 4.0 × 4.0 ) = 9.0 + 16.0 = 25.0 \sqrt{(3.0 \times 3.0) + (4.0 \times 4.0)} = \sqrt{9.0 + 16.0} = \sqrt{25.0} (3.0×3.0)+(4.0×4.0) =9.0+16.0 =25.0
  • 相似度:
    27.0 ( 34.0 × 25.0 ) ≈ 0.93 \frac{27.0}{(\sqrt{34.0} \times \sqrt{25.0})} \approx 0.93 (34.0 ×25.0 )27.00.93
用户 1 和用户 3 的相似度
  • 共同评分物品为物品 1 和物品 3。

  • 对于物品 1:用户 1 评分为 5.0,用户 3 评分为 4.0。

  • 对于物品 3:用户 1 评分为 4.0,用户 3 评分为 5.0。

  • 计算点积:
    ( 5.0 × 4.0 ) + ( 4.0 × 5.0 ) = 20.0 + 20.0 = 40.0 (5.0 \times 4.0) + (4.0 \times 5.0) = 20.0 + 20.0 = 40.0 (5.0×4.0)+(4.0×5.0)=20.0+20.0=40.0

  • 计算用户 1 的范数:
    ( 5.0 × 5.0 ) + ( 4.0 × 4.0 ) = 25.0 + 16.0 = 41.0 \sqrt{(5.0 \times 5.0) + (4.0 \times 4.0)} = \sqrt{25.0 + 16.0} = \sqrt{41.0} (5.0×5.0)+(4.0×4.0) =25.0+16.0 =41.0

  • 计算用户 3 的范数:
    ( 4.0 × 4.0 ) + ( 5.0 × 5.0 ) = 16.0 + 25.0 = 41.0 \sqrt{(4.0 \times 4.0) + (5.0 \times 5.0)} = \sqrt{16.0 + 25.0} = \sqrt{41.0} (4.0×4.0)+(5.0×5.0) =16.0+25.0 =41.0

  • 相似度:
    40.0 ( 41.0 × 41.0 ) ≈ 0.98 \frac{40.0}{(\sqrt{41.0} \times \sqrt{41.0})} \approx 0.98 (41.0 ×41.0 )40.00.98

寻找相似用户
  • 由于 findSimilarUsers(1, 2) 要求找到用户 1 的最相似的 2 个用户,根据上述计算,用户 3 比用户 2 更相似,所以相似用户是用户 3 和用户
生成推荐:
  • 目标用户 1 已评分物品为 1、2、3。
  • 相似用户 2 的物品为 1、2,相似用户 3 的物品为 1、3。
  • 候选推荐物品为物品 2(来自用户 2)和物品 3(来自用户 3)。
  • 计算物品 2 的加权分数:
    • 对于用户 2 与用户 1 的相似度约为 0.93,用户 2 对物品 2 的评分为 4.0,加权分数约为0.93*4.0=3.72。
  • 计算物品 3 的加权分数:
    • 对于用户 3 与用户 1 的相似度约为 0.98,用户 3 对物品 3 的评分为 5.0,加权分数约为0.98*5.0=4.9。
最终推荐:
  • 最终会根据加权分数排序并选取前 5 个物品作为推荐。这里只有物品 2 和物品 3 作为候选,排序后物品 3 排在前面,因为其加权分数更高。

由于用户 1 已对物品 2 和物品 3 有评分,在实际代码运行中,需要排除这些已评分物品。

总结

协同过滤是推荐系统中的经典算法,因其简单、高效和广泛的应用而广受欢迎。

一、核心特点

  • 实现简便:协同过滤通过存储用户评分数据、计算用户之间的相似度并基于相似用户的行为进行推荐,整个过程容易理解,代码简洁易于实现。
  • 推荐效果显著:该算法基于用户历史行为来挖掘相似性,已在电商、社交网络、内容平台等多个领域成功应用,有效提升个性化推荐的准确性,进而提高用户参与度和业务转化率。

二、优化要点

  • 数据预处理:针对数据进行清洗和标准化,去除异常值,利用稀疏矩阵存储技术提高存储效率。
  • 相似度计算:采用优化方法,如局部敏感哈希(LSH)、预计算缓存和不同度量方法(如余弦相似度、皮尔逊相关系数等)来提升计算效率和准确度。
  • 推荐结果优化:引入时间衰减因子、行为权重、多样性控制等策略,以提高推荐系统的质量和用户体验。

三、实际应用

  • 广泛的应用场景:协同过滤在电商、社交平台、内容推荐等各类场景中都有广泛应用,能够有效满足用户的个性化需求。
  • 性能优化:在处理大规模数据时,考虑算法的时间复杂度是至关重要的。通过准确率、召回率和F1 Score等指标来评估推荐效果。
  • 与其他算法结合:协同过滤可与基于内容的推荐算法结合,以解决冷启动问题并进一步提升推荐的准确性和覆盖度。

总结:协同过滤作为推荐系统的基础算法,凭借其简单、高效的特点被广泛应用。为了应对大数据和复杂业务场景,结合其他算法进行优化和创新,将进一步提升协同过滤在个性化推荐中的效果和应用价值。

相关文章:

深入解析人工智能中的协同过滤算法及其在推荐系统中的应用与优化

目录 什么是协同过滤算法核心原理基本步骤相似度计算代码实现详解1.流程图2.创建基础的数据结构存储用户评分数据3.计算用户相似度4.获取相似用户5.推荐方法 算法优化建议1. 数据预处理优化去除异常值和噪声数据进行数据标准化使用稀疏矩阵优化存储 2. 相似度计算优化使用局部敏…...

电梯系统的UML文档04

这个版本的类图是直接从4.2节中用例图的描述得来的&#xff0c;这个视图中的类覆盖了系统所有的功能。我们用电梯类和电梯控制器类&#xff08;ElevatorControl&#xff09;移动或停止电梯&#xff1b;用门类开门或关门&#xff1b;用指示器类让乘客知道电梯的位置和方向&#…...

《自动驾驶与机器人中的SLAM技术》ch4:预积分学

目录 1 预积分的定义 2 预积分的测量模型 ( 预积分的测量值可由 IMU 的测量值积分得到 ) 2.1 旋转部分 2.2 速度部分 2.3 平移部分 2.4 将预积分测量和误差式代回最初的定义式 3 预积分的噪声模型和协方差矩阵 3.1 旋转部分 3.2 速度部分 3.3 平移部分 3.4 噪声项合并 4 零偏的…...

海量数据的处理

一般来说都是针对数据量特别大&#xff0c;内存有限制的。 第一类&#xff1a;topk问题 比如&#xff0c;在海量数据中找前50大的数据怎么办&#xff1f; 方法一&#xff1a;使用小顶堆&#xff0c;用小顶堆维护这50个元素&#xff0c;当有新元素到来时&#xff0c;直接与堆…...

Python人脸识别库DeepFace使用教程及源码解析

目录 一、DeepFace介绍 1、人脸库设计 2、DeepFace.find 3、DeepFace.verify 4、DeepFace.analyze 5、DeepFace.extract_faces 6、DeepFace.represent 7、DeepFace.stream 二、DeepFace二次开发 1、开发活体检测API 2、模型权重持久化 三、总结 一、DeepFace介绍 …...

Nacos:使用PgSQL数据源

数据源插件开源仓库地址&#xff1a;nacos-datasource-extend-plugins 一、PostgreSQL数据库安装 1、本文使用Docker进行数据库的安装&#xff0c;使用docker命令拉取的PG14版本的数据库&#xff1a; docker pull postgres:14.6 2、创建PG容器并启动&#xff0c;映射了5432…...

基于Python的多元医疗知识图谱构建与应用研究(下)

五、基于医疗知识图谱的医疗知识图谱程序构建 5.1 数据层构建 5.1.1 数据源选择与获取 在构建基于医疗知识图谱的医疗知识图谱数据层时,数据源的选择与获取至关重要。数据源的质量和丰富度直接决定了知识图谱的可靠性和实用性。医学文献是重要的数据源之一,包括学术期刊论…...

JAVA:Spring Boot 实现责任链模式处理订单流程的技术指南

1、简述 在复杂的业务系统中&#xff0c;订单流程往往需要一系列的操作&#xff0c;比如验证订单、检查库存、处理支付、更新订单状态等。责任链模式&#xff08;Chain of Responsibility&#xff09;可以帮助我们将这些处理步骤分开&#xff0c;并且以链式方式处理每一个操作…...

SpringBoot多级配置文件

1.问题先导 有这样的场景&#xff0c;我们开发完毕后需要测试人员进行测试&#xff0c;由于测试环境和开发环境的很多配置都不相同&#xff0c;所以测试人员在运 行我们的工程时需要临时修改很多配置&#xff0c;如下 java –jar springboot.jar –-spring.profiles.activete…...

阿里云安装mikrotik7配置内网互通

阿里云近期推出了200M不限量机器&#xff0c;对于没有公网接入的中小企业可以借助这个机器对多地分支机构进行内网互通。目前已经有很多机构用这个搞跨云k8s,跨云集群了。 mikrotik作为一个商用的软件&#xff0c;操作性比一些开源的软件好用不少。 本文使用的网段为172.16.1…...

std::forward实现原理与应用场景

std::forward 是 C11 引入的一个函数模板&#xff0c;用于实现完美转发&#xff08;Perfect Forwarding&#xff09;。它的核心作用是根据传入的参数&#xff0c;决定将参数以左值引用还是右值引用的方式进行转发&#xff0c;从而保持参数的原始值类别。 实现原理 template&l…...

TiDB 在市面上的热门应用领域

TiDB 在市面上的热门应用领域 TiDB 作为一款分布式数据库&#xff0c;凭借其高可扩展性和强一致性&#xff0c;逐渐成为多个行业和领域的热门选择。那么&#xff0c;TiDB 在市面上主要应用在哪些领域呢&#xff1f;今天我们来看看 TiDB 在几个热门领域的应用场景。 1. 互联网…...

“深入浅出”系列之C++:(11)推荐一些C++的开源项目

1. SQLiteCpp - 简单易用的Sqlite C封装库 仓库地址&#xff1a;https://github.com/SRombauts/SQLiteCpp 简介&#xff1a;SQLiteCpp是一个对Sqlite数据库进行C封装的开源库&#xff0c;代码行数约2,500行。它提供了简洁易用的接口&#xff0c;使得在C项目中操作Sqlite数据库…...

高等数学学习笔记 ☞ 定积分的积分方法

1. 定积分的换元积分法 1. 换元积分公式&#xff1a;设函数在闭区间上连续&#xff0c;令&#xff0c;若满足&#xff1a; ①&#xff1a;当时&#xff0c;&#xff1b;当时&#xff0c;。 此时的大小关系不一定&#xff0c;但与最好对应着写&#xff0c;否则就要留意变号的问…...

KVA教程-插件开发

“如果结果不如你所愿&#xff0c;就在尘埃落定前奋力一搏。”——《夏目友人帐》 “有些事不是看到了希望才去坚持&#xff0c;而是因为坚持才会看到希望。”——《十宗罪》 “维持现状意味着空耗你的努力和生命。”——纪伯伦 KVA 技术教程 * 插件开发 简介 插件开发是KVA&a…...

AI守护煤矿安全生产:基于视频智能的煤矿管理系统架构解析

前言 本文我将介绍我和我的团队自主研发设计的一款AI产品的成果展示——“基于视频AI识别技术的煤矿安全生产管理系统”。 这款产品是目前我在创业阶段和几位矿业大学的博士共同从架构设计、开发到交付的全过程中首次在博客频道发布, 我之前一直想写但没有机会来整理这套系统的…...

AI编程工具横向评测--Cloudstudio塑造完全态的jupyter notebook助力数据分析应用开发

AI编程工具横向评测–Cloudstudio塑造完全态的jupyter notebook助力数据分析应用开发 数据分析类应用的开发&#xff0c;指的是首先进行数据分析&#xff0c;比如统计学分析、机器学习模型的构建等&#xff0c;然后将分析的流程开发成数据分析类的工具&#xff0c;或者将数据分…...

04JavaWeb——Maven-SpringBootWeb入门

Maven 课程内容 初识Maven Maven概述 Maven模型介绍 Maven仓库介绍 Maven安装与配置 IDEA集成Maven 依赖管理 01. Maven课程介绍 1.1 课程安排 学习完前端Web开发技术后&#xff0c;我们即将开始学习后端Web开发技术。做为一名Java开发工程师&#xff0c;后端Web开发…...

ThreeJS能力演示——界面点选交互能力

1、支持界面点选 点选模型整体思路是&#xff1a;根据camera位置作为起始点&#xff0c;叠加鼠标相对位置作为偏置&#xff0c;摄像头方向作为射线方向。 根据射线方向中的遇到的3D物体列表&#xff0c;第一个遇到的物体作为被点选的物体。 // 鼠标事件处理let selectedObjec…...

Linux:常用命令--文件与目录操作

ls命令 功能&#xff1a;&#xff08;list&#xff09;列出当前目录的文件信息 语法&#xff1a;ls [-l -h -a] [参数] 参数&#xff1a;被查看的文件夹&#xff0c;不提供参数&#xff0c;表示查看当前工作目录-l&#xff0c;以列表形式查看每个文件的属性&#xff0c;包含…...

Node.js NativeAddon 构建工具:node-gyp 安装与配置完全指南

Node.js NativeAddon 构建工具&#xff1a;node-gyp 安装与配置完全指南 node-gyp Node.js native addon build tool [这里是图片001] 项目地址: https://gitcode.com/gh_mirrors/no/node-gyp 项目基础介绍及主要编程语言 Node.js NativeAddon 构建工具&#xff08;node-gyp…...

docker运行Java项目,Kaptcha因为字体缺失没法显示验证码图片

2015工作至今&#xff0c;10年资深全栈工程师&#xff0c;CTO&#xff0c;擅长带团队、攻克各种技术难题、研发各类软件产品&#xff0c;我的代码态度&#xff1a;代码虐我千百遍&#xff0c;我待代码如初恋&#xff0c;我的工作态度&#xff1a;极致&#xff0c;责任&#xff…...

C++otlv4连接sql serveer使用记录(注意点)

C使用otlv4在做插入时&#xff0c;有一些设计的坑需要注意 插入数据&#xff1a; 当要给表中插入单个字符时&#xff0c;数据库表设计使用varchar(1)是合理的&#xff0c;但是otlv4一直报错char。 后续查很久才知道&#xff0c;otlv4所写的绑定的字符数组的长度应该实际数组…...

[思考记录]认知和思考

在以前&#xff0c;具备一定的技能和经验就能轻易找到自己的一席之地。但在AI时代下&#xff0c;这些东西很容易就被抹平&#xff0c;那么我们的竞争力又在哪里&#xff1f;“认知和思考”是一个方向&#xff0c;帮助我们能去应对复杂情境、帮我们更容易去看到真相。 1.很多时…...

前端开发Web

Ajax 概念:Asynchronous JavaScriptAnd XML&#xff0c;异步的JavaScript和XML 作用: 数据交换:通过Ajax可以给服务器发送请求&#xff0c;并获取服务器响应的数据。 异步交互:可以在不重新加载整个页面的情况下&#xff0c;与服务器交换数据并更新部分网页的…...

【C++提高篇】—— C++泛型编程之模板基本语法和使用的详解

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、模板的概念二、函数模板2.1 函数模板的使用2.2 函数模板注意事项2.3 普通函数与函数模板的区别2.4 普通函数与函数模板的调用规则2.5 模板的局限性 三、类模…...

WPS计算机二级•高效操作技巧

听说这里是目录哦 斜线表头 展示项目名称&#x1f34b;‍&#x1f7e9;横排转竖排&#x1f350;批量删除表格空白行&#x1f348;方法一方法二建辅助列找空值 能量站&#x1f61a; 斜线表头 展示项目名称&#x1f34b;‍&#x1f7e9; 选中单元格&#xff0c;单击右键➡️“设…...

【Maui】视图界面与数据模型绑定

文章目录 前言一、问题描述二、解决方案三、软件开发&#xff08;源码&#xff09;3.1 创建模型3.2 视图界面3.3 控制器逻辑层 四、项目展示 前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架&#xff0c;用于使用 C# 和 XAML 创建本机移动和桌面应用。 使用 .NET MAUI&…...

vue3-sfc-loader 加载远程.vue文件(sfc)案例

注意事项 style标签如果增加了lang比如&#xff1a;lang“scss”&#xff0c;需要提供scss-loader的处理器&#xff0c;这个暂时没研究&#xff0c;我的处理方式是将动态模版的css放在了全局打包暂时还没有测试&#xff0c;后面测试了会同步更新 安装vue3-sfc-loader npm inst…...

Hadoop美食推荐系统 爬虫1.8w+数据 协同过滤余弦函数推荐美食 Springboot Vue Element-UI前后端分离

Hadoop美食推荐系统 爬虫1.8w数据 协同过滤余弦函数推荐美食 Springboot Vue Element-UI前后端分离 【Hadoop项目】 1. data.csv上传到hadoop集群环境 2. data.csv数据清洗 3.MapReducer数据汇总处理, 将Reducer的结果数据保存到本地Mysql数据库中 4. SpringbootEchartsMySQL 显…...

使用Linux驱动程序的fasync(文件异步通知机制)向用户空间发送SIGIO信号的学习记录

前言 本文学习使用Linux驱动程序的fasync(文件异步通知机制)向用户空间发送SIGIO信号。 fasync(文件异步通知机制)名字的来历 fasync 是 “file asynchronous” 的缩写&#xff0c;意思是 文件异步通知。 这里的文件是指文件结构体struct file *file &#xff0c;关于文件结…...

面试经验分享-回忆版某小公司

说说你项目中数据仓库是怎么分层的&#xff0c;为什么要分层&#xff1f; 首先是ODS层&#xff0c;连接数据源和数据仓库&#xff0c;数据会进行简单的ETL操作&#xff0c;数据来源通常是业务数据库&#xff0c;用户日志文件或者来自消息队列的数据等 中间是核心的数据仓库层&a…...

【算法学习笔记】35:扩展欧几里得算法求解线性同余方程

线性同余方程问题 线程同余方程问题是指 a x ≡ b ( m o d m ) ax \equiv b~(mod~m) ax≡b (mod m)&#xff0c;给定 a a a、 b b b和 m m m&#xff0c;找到一个整数 x x x使得该方程成立&#xff0c;即使得 a x m o d m b ax~mod~mb ax mod mb&#xff0c;随便返回任何一个…...

ent.SetDatabaseDefaults()

在 AutoCAD 的 .NET API 中&#xff0c;ent.SetDatabaseDefaults() 这句代码通常用于将一个实体&#xff08;Entity&#xff09;对象的属性设置为与其所在的数据库&#xff08;Database&#xff09;的默认设置相匹配。这意味着&#xff0c;该实体将采用数据库级别的默认颜色、图…...

使用docker部署tomcat服务器和mysql数据库

使用docker部署tomcat服务器 1、拉去tomcat镜像 [rootlocalhost yum.repos.d]# sudo docker pull docker.io/tomcat:9 9: Pulling from library/tomcat de44b265507a: Pull complete 4c2afd91a87d: Pull complete 89e9bbcfa697: Pull complete 11be3e613582: Pull complet…...

Jenkins 启动

废话 这一阵子感觉空虚&#xff0c;心里空捞捞的&#xff0c;总想找点事情做&#xff0c;即使这是一件微小的事情&#xff0c;空余时间除了骑车、打球&#xff0c;偶尔朋友聚会 … 还能干什么呢&#xff1f; 当独自一人时&#xff0c;究竟可以做点什么&#xff0c;填补这空虚…...

Elasticsearch(ES)基础查询语法的使用

1. Match Query (全文检索查询) 用于执行全文检索&#xff0c;适合搜索文本字段。 { “query”: { “match”: { “field”: “value” } } } match_phrase&#xff1a;精确匹配短语&#xff0c;适合用于短语搜索。 { “query”: { “match_phrase”: { “field”: “text” }…...

SpringCloud系列教程:微服务的未来(十四)网关登录校验、自定义过滤器GlobalFilter、GatawayFilter

前言 在微服务架构中&#xff0c;API 网关扮演着至关重要的角色&#xff0c;负责路由请求、执行安全验证、流量控制等任务。Spring Cloud Gateway 作为一个强大的网关解决方案&#xff0c;提供了灵活的方式来实现这些功能。 本篇博客将重点介绍如何在 Spring Cloud Gateway 中…...

Android Studio:Linux环境下安装与配置

更多内容&#xff1a;XiaoJ的知识星球 Android Studio&#xff1a;Linux环境下安装与配置 1.安装JDK2.安装Android Studio2.1 获取安装包2.2 安装&#xff08;1&#xff09;配置环境变量&#xff1a;&#xff08;2&#xff09;运行安装&#xff1a;&#xff08;3&#xff09;配…...

使用AI生成金融时间序列数据:解决股市场的数据稀缺问题并提升信噪比

“GENERATIVE MODELS FOR FINANCIAL TIME SERIES DATA: ENHANCING SIGNAL-TO-NOISE RATIO AND ADDRESSING DATA SCARCITY IN A-SHARE MARKET” 论文地址&#xff1a;https://arxiv.org/pdf/2501.00063 摘要 金融领域面临的数据稀缺与低信噪比问题&#xff0c;限制了深度学习在…...

【银河麒麟高级服务器操作系统】业务访问慢网卡丢包现象分析及处理过程

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;product.kylinos.cn 开发者专区&#xff1a;developer.kylinos.cn 文档中心&#xff1a;document.kylinos.cn 交流论坛&#xff1a;forum.kylinos.cn 服务器环境以及配置 【内核版本…...

如何将数据库字符集改为中文,让今后所有的数据库都支持中文

最后一行有我自己的my.ini文件 数据库输入中文数据时会变为乱码&#xff0c; 这个时候&#xff0c;我们为每个数据库设置字符集&#xff0c;太过于麻烦&#xff0c;为数据库单独设置重启后又会消失 Set character_set_database’utf8’; Set character_set_server’utf8’; …...

Linux-C/C++--深入探究文件 I/O (下)(文件共享、原子操作与竞争冒险、系统调用、截断文件)

经过上一章内容的学习&#xff0c;了解了 Linux 下空洞文件的概念&#xff1b;open 函数的 O_APPEND 和 O_TRUNC 标志&#xff1b;多次打开同一文件&#xff1b;复制文件描述符&#xff1b;等内容 本章将会接着探究文件IO&#xff0c;讨论如下主题内容。  文件共享介绍&…...

Linux Bash 中使用重定向运算符的 5 种方法

注&#xff1a;机翻&#xff0c;未校。 Five ways to use redirect operators in Bash Posted: January 22, 2021 | by Damon Garn Redirect operators are a basic but essential part of working at the Bash command line. See how to safely redirect input and output t…...

opengrok_windows_环境搭建

目录 软件列表 软件安装 工程索引 ​编辑 工程部署 问题列表 软件列表 软件名下载地址用途JDKhttps://download.java.net/openjdk/jdk16/ri/openjdk-1636_windows-x64_bin.zipindex 使用java工具tomcathttps://dlcdn.apache.org/tomcat/tomcat-9/v9.0.98/bin/apache-tom…...

【无法下载github文件】虚拟机下ubuntu无法拉取github文件

修改hosts来进行解决。 步骤一&#xff1a;打开hosts文件 sudo vim /etc/hosts步骤二&#xff1a;查询 github.com的ip地址 https://sites.ipaddress.com/github.com/#ipinfo将github.com的ip地址添加到hosts文件末尾&#xff0c;如下所示。 140.82.114.3 github.com步骤三…...

python——句柄

一、概念 句柄指的是操作系统为了标识和访问对象而提供的一个标识符&#xff0c;在操作系统中&#xff0c;每个对象都有一个唯一的句柄&#xff0c;通过句柄可以访问对象的属性和方法。例如文件、进程、窗口等都有句柄。在编程中&#xff0c;可以通过句柄来操作这些对象&#x…...

.Net Core微服务入门系列(一)——项目搭建

系列文章目录 1、.Net Core微服务入门系列&#xff08;一&#xff09;——项目搭建 2、.Net Core微服务入门全纪录&#xff08;二&#xff09;——Consul-服务注册与发现&#xff08;上&#xff09; 3、.Net Core微服务入门全纪录&#xff08;三&#xff09;——Consul-服务注…...

Net Core微服务入门全纪录(三)——Consul-服务注册与发现(下)

系列文章目录 1、.Net Core微服务入门系列&#xff08;一&#xff09;——项目搭建 2、.Net Core微服务入门全纪录&#xff08;二&#xff09;——Consul-服务注册与发现&#xff08;上&#xff09; 3、.Net Core微服务入门全纪录&#xff08;三&#xff09;——Consul-服务注…...

[苍穹外卖] 1-项目介绍及环境搭建

项目介绍 定位&#xff1a;专门为餐饮企业&#xff08;餐厅、饭店&#xff09;定制的一款软件产品 功能架构&#xff1a; 管理端 - 外卖商家使用 用户端 - 点餐用户使用 技术栈&#xff1a; 开发环境的搭建 整体结构&#xff1a; 前端环境 前端工程基于 nginx 运行 - Ngi…...