Surprise API使用问题:如何将额外特征加载到Surprise数据集中
Surprise库导入DataFrame附加特征的实现方案
首先明确核心前提:Surprise库原生定位为传统协同过滤算法实现工具,默认仅支持用户ID、物品ID、评分三类输入,没有官方原生的附加特征传入接口,可通过以下三种方案实现需求:
方案1:继承
AlgoBase自定义算法扩展(最灵活,推荐)
核心逻辑是将标准三列数据按Surprise原有流程构建数据集,单独维护附加特征的映射表,在自定义的拟合、预测逻辑中引入附加特征计算:- 从原始DataFrame中拆分出用户特征映射、物品特征映射,以ID为键存储特征向量
- 仅将用户ID、物品ID、评分三列传入
load_from_df完成数据集构建 - 继承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
相关产品推荐
相关产品推荐

