You need to enable JavaScript to run this app. Python中NumPy数组计算流程咨询:SVD相关操作原理解释
优惠活动
大模型
产品
解决方案
定价
更多

Python中NumPy数组计算流程咨询:SVD相关操作原理解释

基于NumPy SVD的协同过滤流程逐段拆解

1. unstack生成的user_item_train矩阵

  • 本质是长格式评分记录转换后的宽表矩阵:行索引为训练集内全部出现过的用户ID,列索引为训练集内全部出现过的物品ID,单元格对应用户给物品的实际评分,未交互的位置通常填充0
  • 核心对齐特性:矩阵的行、列顺序固定,后续所有矩阵操作、索引匹配完全依赖这个顺序,不存在自动排序或打乱
  • 常见生成逻辑等价于:train_ratings.pivot(index='user_id', columns='item_id', values='rating').fillna(0),和分组后unstack的输出结构完全一致

2. test_idx的实际定位

  • 这个列表不是全局的用户ID集合,是需要纳入测试评估的目标用户,在user_item_train矩阵行索引中对应的位置标记
  • 存储形式通常是[0, 3, 5, 12]这类整数位置值,代表这些行号对应的用户是测试目标

3. 测试用户匹配的布尔值生成

  • 常规实现代码:
# 提取user_item_train的行索引序列(即所有训练用户ID的有序排列)
train_user_seq = user_item_train.index
# 生成和矩阵行数等长的布尔掩码,标记每一行是否属于测试目标用户
user_mask = train_user_seq.isin(test_target_user_list)
  • 设计逻辑:后续SVD输出的用户隐向量是严格按照原矩阵行顺序逐行对应排列的,必须靠这个和矩阵长度完全对齐的布尔掩码定位目标用户在隐向量矩阵中的位置,避免直接用用户ID当索引导致的维度越界、匹配错位问题

4. np.linalg.svd(user_item_train, full_matrices=False)输出的u_train

  • 当参数设为full_matrices=False时,SVD输出的三个数组完全保留输入矩阵的行列顺序:
    • u_train:形状为(训练用户数, k),k为min(训练用户数, 训练物品数),每一行和user_item_train的行顺序一一对应,无任何打乱或重排
    • s:长度为k的一维数组,存储按降序排列的奇异值
    • vt:形状为(k, 训练物品数),每一列和user_item_train的列顺序一一对应
  • 设full_matrices=False的目的是裁剪冗余维度,降低计算量

5. 最后一步索引操作的底层逻辑

  • 这部分的核心是利用之前生成的、和SVD输出矩阵完全对齐的布尔掩码,抠出测试需要的子集,避免索引错位
  • 常见实现代码逐行解释:
# 用之前生成的行掩码,从u_train中抠出测试目标用户的隐向量
u_test = u_train[user_mask, :]
# 同理生成列掩码,标记测试涉及的物品位置,从vt矩阵中抠出对应物品的隐向量
item_mask = user_item_train.columns.isin(test_target_item_list)
vt_test = vt[:, item_mask]
# 最终计算预测评分:矩阵相乘后得到(测试用户数, 测试物品数)的预测评分矩阵
predicted_score = np.dot(np.dot(u_test, np.diag(s)), vt_test)
  • 常见困惑点解释:为什么不直接用test_idx做索引导入?因为test_idx如果是原始用户ID、物品ID的实际值,直接拿这个值当数组位置索引,大概率会因为ID数值远大于数组维度数触发越界报错;而布尔掩码是严格和矩阵行列长度对齐的,不管原始ID是什么取值,都能精准匹配到对应的矩阵位置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.09 10:06:04