LightFM混合推荐系统报错TypeError: unhashable type: 'numpy.ndarray'求助
解决LightFM推荐系统中的TypeError: unhashable type: 'numpy.ndarray'错误
问题根源
你遇到的错误是因为直接用numpy数组去索引字典导致的:
dataset.mapping()[2]返回的是字典(结构为{原始ItemID: 内部索引}),不是数组scores.argsort()[::-1]得到的是物品内部索引的排序数组,用数组索引字典会触发"不可哈希类型numpy.ndarray"的错误
另外代码里还有个潜在bug:data[data['UserId'] == user_id]['Item']中的列名Item和数据加载时的ItemId不匹配,会引发KeyError。
修复后的完整代码
import pandas as pd from lightfm import LightFM from lightfm.data import Dataset as DS import numpy as np # Load data from a CSV file data = pd.read_csv('my_data.csv') # Create a dataset object datasetfm = DS() # Fit the dataset with data datasetfm.fit(users=data['UserId'], items=data['ItemId']) # Build the interaction matrix (interactions, weights) = datasetfm.build_interactions([(row['UserId'], row['ItemId'], row['Weight']) for index, row in data.iterrows()]) # Create the model model = LightFM(loss='warp') # Train the model model.fit(interactions, epochs=30, num_threads=2) # function to get recommendations for a user def get_recommendations(user_id, model, dataset, data): n_users, n_items = dataset.interactions_shape() # 获取用户、物品的原始ID与内部索引的映射字典 user_id_map = dataset.mapping()[0] item_id_map = dataset.mapping()[2] # 创建反向映射:把内部索引转成原始物品ID idx_to_item_id = {v: k for k, v in item_id_map.items()} # 获取用户已经交互过的物品(修正列名,和数据集保持一致) known_positives = data[data['UserId'] == user_id]['ItemId'].tolist() # 获取用户对应的内部索引 user_internal_id = user_id_map[user_id] # 预测所有物品的推荐得分 scores = model.predict(user_internal_id, np.arange(n_items)) # 按得分降序排列物品内部索引,再转成原始物品ID top_item_indices = scores.argsort()[::-1] top_items = [idx_to_item_id[idx] for idx in top_item_indices] # 过滤掉用户已经交互过的物品,返回前10个推荐 recommendations = [item for item in top_items if item not in known_positives] return recommendations[:10] # Usage user_id = 1 # 要获取推荐的用户ID recommendations = get_recommendations(user_id, model, datasetfm, data) print(recommendations)
核心修复说明
- 新增
idx_to_item_id反向映射字典:解决LightFM内部索引和原始物品ID的转换问题,避免用数组索引字典 - 修正列名错误:把
['Item']改成['ItemId'],和数据集中的列名对应 - 明确用户内部索引的获取:
user_internal_id = user_id_map[user_id],避免字典索引的混淆 - 遍历排序后的内部索引:通过反向映射得到原始物品ID,替代原来错误的数组索引字典方式
内容的提问来源于stack exchange,提问作者samesame
相关产品推荐
相关产品推荐

