如何为LightFM推荐模型正确构建build_item_features物品特征?
错误核心原因
LightFM的Dataset的fit/fit_partial方法传入的item_features参数,不是用来声明特征列名的,是用来注册所有后续会用到的特征值全集的。你之前仅传入了['app_name','price']等列名,但是实际构建特征时传入的是Lost Summoner Kitty这类具体的特征值,这些值从未被注册到特征映射中,因此触发报错。
另外你代码中还有两处隐性错误:
- 构建多值特征(genre、specs)时嵌套了两层列表,会将整个拆分后的列表作为单个特征值传入,格式完全不匹配
- 特征没有做命名空间区分,不同列的相同值(比如价格列有个值叫"Action"和游戏类型列的"Action")会被识别为同一个特征,导致特征混淆
修正方案
第一步:预注册所有item特征值
你需要先将所有要用到的item特征统一格式化为特征名:特征值的字符串,去重后传给fit_partial完成注册:
# 收集所有item特征值用于注册 all_item_features = [] for _, row in games_data.iterrows(): # 单值特征处理 all_item_features.append(f"app_name:{row['app_name']}") all_item_features.append(f"price:{row['price']}") all_item_features.append(f"early_access:{row['early_access']}") all_item_features.append(f"release_year:{row['release_year']}") all_item_features.append(f"release_month:{row['release_month']}") # 多值特征(genre、specs)拆分处理 for g in row['genres'].split(','): all_item_features.append(f"genre:{g.strip()}") for s in row['specs'].split(','): all_item_features.append(f"spec:{s.strip()}") # 去重后注册所有item特征 dataset.fit_partial( items = games_data['id'], item_features = list(set(all_item_features)) )
第二步:按统一格式构建item特征
构建特征时,特征格式必须和注册时完全一致,同时将多值特征拆平,不要嵌套列表:
item_features = dataset.build_item_features( (( row['id'], [ f"app_name:{row['app_name']}", f"price:{row['price']}", f"early_access:{row['early_access']}", f"release_year:{row['release_year']}", f"release_month:{row['release_month']}", *[f"genre:{g.strip()}" for g in row['genres'].split(',')], *[f"spec:{s.strip()}" for s in row['specs'].split(',')] ] ) for _, row in games_data.iterrows()) )
提示:后续构建用户特征时也需要遵循同样的逻辑,先注册所有特征名:特征值格式的用户特征值,再按相同格式构建特征矩阵
内容的提问来源于stack exchange,提问作者user11619814
相关产品推荐
相关产品推荐

