You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求Python中基于Yelp评论数据集高效构建推荐系统评分矩阵的方法

高效构建Python推荐系统评分矩阵(MongoDB数据源优化方案)

我来帮你彻底优化这个评分矩阵的构建流程——原代码的核心问题在于频繁的数据库IO和低效的线性查找/去重,这在数据量稍大时会导致性能急剧下降。下面是针对性的优化思路和完整实现代码:

核心优化策略

  • 批量查询替代零散IO:把多次循环调用的find/find_one换成2次批量查询,一次性拉取所有需要的数据到内存处理,彻底减少数据库交互次数。
  • 哈希映射提速定位:用字典存储user_id到行索引、business_id到列索引的映射,实现O(1)时间复杂度的位置定位,替代原代码中O(n)的线性判断。
  • 集合自动去重:用Python集合处理用户ID去重,比列表的if x not in list判断效率提升数倍。
  • 批量文件写入:用字符串拼接整行内容后一次性写入,减少磁盘IO次数。

完整优化代码

from pymongo import MongoClient

# 假设你已经初始化了MongoDB连接和集合
client = MongoClient("your_mongodb_connection_string")
db = client["your_database_name"]
colBisnis = db["business"]  # 对应原代码中的商家集合
colReview = db["review"]    # 对应原代码中的评论集合

def get_business_ids_by_city(city_name):
    """批量获取目标城市的所有去重商家ID"""
    # 使用MongoDB的distinct方法直接返回去重结果,无需手动循环判断
    return colBisnis.distinct("_id", {"city": city_name})

def get_reviews_and_users(business_ids):
    """批量获取目标商家的所有评论,并生成用户ID列表和评分映射表"""
    # 用$in批量查询所有目标商家的评论,避免循环逐个查询
    reviews = list(colReview.find({"business_id": {"$in": business_ids}}))
    
    # 用集合自动去重用户ID,效率远高于列表判断
    user_ids = list({review["user_id"] for review in reviews})
    
    # 构建(user_id, business_id) -> stars的映射字典,方便快速查找评分
    review_map = {(review["user_id"], review["business_id"]): review["stars"] 
                  for review in reviews}
    
    return user_ids, review_map

def build_rating_matrix(business_ids, user_ids, review_map):
    """构建评分矩阵并写入文件"""
    # 创建商家ID到列索引的映射
    biz_to_idx = {biz: idx for idx, biz in enumerate(business_ids)}
    # 创建用户ID到行索引的映射
    user_to_idx = {user: idx for idx, user in enumerate(user_ids)}
    
    # 初始化全0矩阵:行数=用户数,列数=商家数
    matrix = [[0] * len(business_ids) for _ in range(len(user_ids))]
    
    # 批量填充评分:直接通过映射定位矩阵位置,无需查询数据库
    for (user_id, biz_id), stars in review_map.items():
        row_idx = user_to_idx[user_id]
        col_idx = biz_to_idx[biz_id]
        matrix[row_idx][col_idx] = stars
    
    # 批量写入文件:用join拼接整行,减少磁盘IO次数
    with open("rating_matrix.txt", "w") as f:
        for row in matrix:
            # 把每行的数字转为字符串,用|连接,末尾补|并换行
            line = "|".join(map(str, row)) + "|\n"
            f.write(line)

def build_city_table(city_name):
    """整合所有步骤,构建目标城市的评分矩阵"""
    # 步骤1:获取目标城市的商家ID列表
    business_ids = get_business_ids_by_city(city_name)
    if not business_ids:
        print(f"未找到{city_name}的商家数据")
        return
    
    # 步骤2:获取评论数据和用户ID列表
    user_ids, review_map = get_reviews_and_users(business_ids)
    if not user_ids:
        print(f"{city_name}的商家暂无评论数据")
        return
    
    # 步骤3:构建并写入矩阵
    build_rating_matrix(business_ids, user_ids, review_map)
    print(f"{city_name}的评分矩阵已成功生成!")

# 执行示例
city_name_var = 'Pointe-Aux-Trembles'
build_city_table(city_name_var)

性能提升说明

  • 数据库查询次数:原代码的查询次数为用户数×商家数 + 商家数 + 用户数,优化后仅为2次,彻底消除了最耗时的IO瓶颈。
  • 去重效率:集合去重的时间复杂度是O(n),而原代码的列表判断去重是O(n²),数据量越大提升越明显。
  • 矩阵填充效率:哈希映射定位的时间复杂度是O(1),替代原代码的O(1)数据库查询(但数据库查询的实际开销远高于内存操作)。

内容的提问来源于stack exchange,提问作者Andre Hrs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 13:57:38