如何实现填充实际值而非1的Multi-hot Encoding,适配用户电影评分场景
原生MultiLabelBinarizer仅支持生成0/1的二值矩阵,不支持自定义填充值。你之前的赋值操作出错,是因为二值矩阵中1的位置按all_movieIds的全局排序排列,而np.concatenate(list_of_ratings)的顺序是每个用户内部的电影排列顺序,二者顺序不匹配导致赋值错位。
高效实现方案
以下实现基于numpy原生索引操作,时间复杂度仅和有效评分数量线性相关,性能远高于循环逐行赋值。
import numpy as np def multi_value_encode(user_movie_lists, user_rating_lists, all_movie_ids): # 构建电影ID到矩阵列索引的映射表 movie_to_col = {mid: idx for idx, mid in enumerate(all_movie_ids)} user_count = len(user_movie_lists) movie_count = len(all_movie_ids) # 初始化全0矩阵 user_matrix = np.zeros((user_count, movie_count), dtype=np.float32) # 构造扁平的行索引、列索引、评分数组 rows = [] cols = [] ratings = [] for user_idx, (movie_ids, ratings_per_user) in enumerate(zip(user_movie_lists, user_rating_lists)): for mid, rate in zip(movie_ids, ratings_per_user): rows.append(user_idx) cols.append(movie_to_col[mid]) ratings.append(rate) # 批量完成赋值,numpy原生操作效率极高 user_matrix[rows, cols] = ratings return user_matrix # 调用示例 user_matrix = multi_value_encode(lists_of_movieIds, list_of_ratings, all_movieIds)
高稀疏场景优化
如果用户和电影数量极大、矩阵稀疏度很高,可以用scipy稀疏矩阵存储,大幅降低内存占用:
from scipy.sparse import csr_matrix def multi_value_encode_sparse(user_movie_lists, user_rating_lists, all_movie_ids): movie_to_col = {mid: idx for idx, mid in enumerate(all_movie_ids)} user_count = len(user_movie_lists) movie_count = len(all_movie_ids) rows = [] cols = [] ratings = [] for user_idx, (movie_ids, ratings_per_user) in enumerate(zip(user_movie_lists, user_rating_lists)): for mid, rate in zip(movie_ids, ratings_per_user): rows.append(user_idx) cols.append(movie_to_col[mid]) ratings.append(rate) # 直接构造CSR格式稀疏矩阵 return csr_matrix((ratings, (rows, cols)), shape=(user_count, movie_count))
问题答疑
- 暂没有支持传入值参数的官方
MultiLabelBinarizer实现,你可以基于上述逻辑自行封装接口兼容的类。 - 上述实现本身就是推荐系统领域构造用户-物品评分矩阵的标准线性代数实现,不需要额外的复杂矩阵运算,性能已达最优。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

