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

Surprise API使用问题:如何将额外特征加载到Surprise数据集中

Surprise库导入DataFrame附加特征的实现方案

首先明确核心前提:Surprise库原生定位为传统协同过滤算法实现工具,默认仅支持用户ID、物品ID、评分三类输入,没有官方原生的附加特征传入接口,可通过以下三种方案实现需求:

  • 方案1:继承AlgoBase自定义算法扩展(最灵活,推荐)
    核心逻辑是将标准三列数据按Surprise原有流程构建数据集,单独维护附加特征的映射表,在自定义的拟合、预测逻辑中引入附加特征计算:

    1. 从原始DataFrame中拆分出用户特征映射、物品特征映射,以ID为键存储特征向量
    2. 仅将用户ID、物品ID、评分三列传入load_from_df完成数据集构建
    3. 继承Surprise的AlgoBase基类,重写fit方法训练特征权重,重写estimate方法在预测时叠加附加特征的影响
      参考实现代码如下:
    from surprise import AlgoBase, Dataset, Reader
    import pandas as pd
    
    # 示例原始数据(含附加特征user_age、item_category)
    df = pd.DataFrame({
        "user_id": [1,1,2,2],
        "item_id": [1,2,1,2],
        "rating": [5,3,4,2],
        "user_age": [25,25,30,30],
        "item_category": [0,1,0,1]
    })
    
    # 单独维护附加特征映射表
    user_feature_map = df.set_index("user_id")["user_age"].to_dict()
    item_feature_map = df.set_index("item_id")["item_category"].to_dict()
    
    # 构建Surprise标准数据集
    reader = Reader(rating_scale=(1,5))
    data = Dataset.load_from_df(df[["user_id", "item_id", "rating"]], reader)
    trainset = data.build_full_trainset()
    
    # 自定义带附加特征的算法
    class FeatureAugmentedAlgo(AlgoBase):
        def __init__(self, base_algo=None):
            super().__init__()
            # 可传入原生Surprise算法作为基础预测器
            self.base_algo = base_algo
            # 可自定义特征权重训练逻辑
            self.age_weight = 0.03
            self.cat_weight = 0.45
    
        def fit(self, trainset):
            super().fit(trainset)
            if self.base_algo:
                self.base_algo.fit(trainset)
            # 此处可添加附加特征的权重训练逻辑
            return self
    
        def estimate(self, u, i):
            # 转换Surprise内部编码为原始ID
            raw_uid = self.trainset.to_raw_uid(u)
            raw_iid = self.trainset.to_raw_iid(i)
            # 基础协同过滤预测得分
            base_score = self.base_algo.estimate(u, i) if self.base_algo else self.trainset.global_mean
            # 叠加附加特征影响
            age_effect = user_feature_map[raw_uid] * self.age_weight
            category_effect = item_feature_map[raw_iid] * self.cat_weight
            return base_score + age_effect + category_effect
    
    # 调用示例
    algo = FeatureAugmentedAlgo()
    algo.fit(trainset)
    print(algo.predict(1, 2).est)
    
  • 方案2:特征编码融合到ID中(轻量场景快速实现)
    如果附加特征为低基数离散特征,可直接将特征编码拼接到用户ID/物品ID中,比如用户ID为1、性别为男,拼接为1_male,直接使用拼接后的ID作为新的用户/物品ID传入load_from_df即可,无需修改算法逻辑。缺点是会提升ID稀疏性,仅适合特征数量少、特征基数低的场景。

  • 方案3:替换为支持附加特征的推荐库(复杂场景推荐)
    如果需要大量使用用户、物品、上下文附加特征,更推荐使用原生支持特征融合的推荐算法库,无需二次开发即可实现协同过滤+附加特征的训练,比改造Surprise的开发成本更低、效果更稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 07:45:04