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

能否使用Surprise无需重新训练即可实时预测新用户的评分?

问题解答

原理可行性结论

需求在原理上完全可行。
基于矩阵分解的SVD推荐模型训练完成后,核心得到三类固定参数:全局评分均值、所有已纳入训练的物品偏置、所有已纳入训练的物品隐向量。新用户提交少量评分后,只需要固定上述已经训练好的物品侧参数,仅针对新用户的用户偏置、用户隐向量做极小量的优化求解即可,不需要重新训练整个模型的全部参数,计算成本极低,可以做到实时响应。

Surprise库原生支持情况

Surprise官方没有直接提供新用户增量适配的接口,原生的predict方法遇到不在训练集的新用户时,会默认把用户偏置、用户隐向量设为0,最终给出的预测值仅为全局均值加对应物品的偏置,完全没有用到新用户提交的个性化评分数据,达不到个性化推荐的要求。
但你可以直接调用训练好的SVD模型的公开参数,手动实现新用户参数的求解逻辑,实现成本很低,具体实现方案如下:

手动实现代码示例

首先你训练好的SVD模型可以直接取出所有需要的固定参数:

from surprise import SVD, Dataset, Reader
import numpy as np

# 你的原有训练逻辑
data = Dataset.load_from_df(your_df, Reader(rating_scale=(1,5)))
trainset = data.build_full_trainset()
svd = SVD(verbose=True, n_epochs=10, reg_all=0.02)
svd.fit(trainset)

# 取出模型固定参数
mu = svd.mu
bi = svd.bi
qi = svd.qi
reg_bu = svd.reg_bu
reg_pu = svd.reg_pu
n_factors = svd.n_factors
lr = svd.lr_all

然后拿到新用户的评分数据后,求解新用户的个性化参数:

def get_new_user_params(new_user_ratings):
    # new_user_ratings 格式:[(原始物品id, 评分), ...]
    rated_iids = []
    ratings = []
    for raw_iid, r in new_user_ratings:
        # 过滤掉训练集中不存在的物品
        if trainset.knows_item(raw_iid):
            inner_iid = trainset.to_inner_iid(raw_iid)
            rated_iids.append(inner_iid)
            ratings.append(r)
    if not rated_iids:
        # 新用户没有任何有效评分,返回默认值
        return 0, np.zeros(n_factors)
    
    rated_iids = np.array(rated_iids)
    ratings = np.array(ratings)
    
    # 初始化新用户参数
    bu_new = 0.0
    pu_new = np.random.normal(0, 0.1, n_factors)
    
    # 少量梯度迭代即可收敛,迭代20次完全足够
    for _ in range(20):
        error = ratings - (mu + bu_new + bi[rated_iids] + pu_new @ qi[rated_iids].T)
        # 更新用户偏置
        bu_new += lr * (np.sum(error) - reg_bu * bu_new)
        # 更新用户隐向量
        pu_new += lr * (error @ qi[rated_iids] - reg_pu * pu_new)
    
    return bu_new, pu_new

最后就可以用求解得到的参数做预测、生成推荐:

def predict_new_user(bu_new, pu_new, raw_iid):
    if not trainset.knows_item(raw_iid):
        # 物品不在训练集,返回全局均值
        return mu
    inner_iid = trainset.to_inner_iid(raw_iid)
    pred = mu + bu_new + bi[inner_iid] + pu_new @ qi[inner_iid].T
    # 截断到你的评分区间,示例为1-5分
    return max(1, min(5, pred))

注意事项

  • 新用户的有效评分数量建议不低于3个,求解得到的用户隐向量会更准确,推荐效果更好
  • 训练集不存在的冷启动物品,这个方案也无法给出个性化预测,需要单独处理物品冷启动的逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:15:03