3

tl;dr:与 Yelp 数据集一起制作推荐系统,但遇到测试交互矩阵和训练交互矩阵共享 68 个交互。这将导致不正确的评估,请检查您的数据拆分。运行以下 LightFM 代码时出错。

test_auc = auc_score(model,
                    test,
                    #train_interactions=train, #Unable to run with this line uncommented
                    item_features=sparse_features_matrix,
                    num_threads=NUM_THREADS).mean()
print('Hybrid test set AUC: %s' % test_auc)

全文:使用 Yelp 数据集构建推荐系统。

取消示例文档 ( https://making.lyst.com/lightfm/docs/examples/hybrid_crossvalidated.html ) 中提供的代码,用于混合协作过滤。

我按以下方式运行我的代码:

from sklearn.model_selection import train_test_split
from lightfm import LightFM
from scipy import sparse
from lightfm.evaluation import auc_score

train, test = train_test_split(sparse_Rating_Matrix, test_size=0.25,random_state=4)
# Set the number of threads; you can increase this
# if you have more physical cores available.
NUM_THREADS = 2
NUM_COMPONENTS = 100
NUM_EPOCHS = 3
ITEM_ALPHA = 1e-6

# Define a new model instance
model = LightFM(loss='warp',
                item_alpha=ITEM_ALPHA,
                no_components=NUM_COMPONENTS)

# Fit the hybrid model. Note that this time, we pass
# in the item features matrix.
model = model.fit(train,
                item_features=sparse_features_matrix,
                epochs=NUM_EPOCHS,
                num_threads=NUM_THREADS)

# Don't forget the pass in the item features again!
train_auc = auc_score(model,
                      train,
                      item_features=sparse_features_matrix,
                      num_threads=NUM_THREADS).mean()
print('Hybrid training set AUC: %s' % train_auc)

test_auc = auc_score(model,
                    test,
                    #train_interactions=train, # Unable to run with this line uncommented
                    item_features=sparse_features_matrix,
                    num_threads=NUM_THREADS).mean()
print('Hybrid test set AUC: %s' % test_auc)

我有两个问题:

1) 运行有问题的行未注释 (train_interactions=train) 最初产生不一致的形状

通过以下方法解决:“测试”数据集由以下代码块修改,在其下方附加一个零块,直到尺寸与我的火车数据集的尺寸匹配(根据此建议:https ://github.com /lyst/lightfm/issues/369):

#Add X users to Test so that the number of rows in Train match Test
N = train.shape[0] #Rows in Train set
n,m = test.shape #Rows & columns in Test set

z = np.zeros([(N-n),m]) #Create the necessary rows of zeros with m columns
test = test.todense() #Temporarily convert Test into a numpy array
test = np.vstack((test,z)) #Vertically stack Test on top of the blank users
test = sparse.csr_matrix(test) #Convert back to sparse

2)形状问题解决后,我尝试实现“train_interactions=train”

但遇到测试交互矩阵和训练交互矩阵共享 68 个交互。这将导致不正确的评估,请检查您的数据拆分。

而且我不确定如何解决第二个问题。有什么想法吗?

详细信息:
-“sparse_features_matrix”是 {items x categories} 的稀疏矩阵,其中如果一个项目是“Italian”和“Pizza”,那么“Italian”和“Pizza”的类别对于该项目的行将具有值“1” ...“0”别处。
-“sparse_Rating_Matrix”是{users x items}的稀疏矩阵,包含用户对餐厅(项目)的评分值。

2020 年 4 月 8日更新:
LightFM 有一个完整的 Database() 类对象,您应该使用它在模型评估之前准备数据集。我发现了一篇很棒的 github 帖子 ( https://github.com/lyst/lightfm/issues/494 ),其中用户 Med-ELOMARI 对一个小型测试数据集进行了惊人的演练。

当我通过这种方法准备数据时,我能够添加我想要建模的 user_features(例如:User_1592 喜欢“泰国”、“墨西哥”、“寿司”美食)。

根据 Turbo 的评论,我使用 LightFM 的 random_train_test_split 方法(最初是通过 sklearn 的 train_test_split 方法拆分我的数据)并使用新的训练/测试集和正确(据我所知)准备好的模型运行 auc_score 我仍然遇到同样的错误代码:

输入:

%%time
(train,test) = random_train_test_split(lightfm_interactions,test_percentage=0.25) #LightFM's method to split
# Don't forget the pass in the item features again!
train_auc = auc_score(model_users,
                      train,
                      user_features=lightfm_user_features_list,
                      num_threads=NUM_THREADS).mean()
print('User_feature training set AUC: %s' % train_auc)

test_auc = auc_score(model_users,
                    test,
                    #train_interactions=train, #Still can't get this to function
                    user_features=lightfm_user_features_list,
                    num_threads=NUM_THREADS).mean()
print('User_feature test set AUC: %s' % test_auc)

如果使用“train_interactions=train”,则输出:

ValueError: Test interactions matrix and train interactions matrix share 435 interactions. This will cause incorrect evaluation, check your data split.

然而,好消息是——通过从 sklearn 的 train_test_split 切换到 LightFM 的 random_train_test_split,我的模型的 AUC 分数在训练时从 0.49 变为 0.96。所以我想如果可以的话,坚持使用 LightFM 的方法很重要!

4

1 回答 1

2

LightFM 提供了一种拆分数据集的方法,你看过了吗?有了它,它可能会奏效。 https://making.lyst.com/lightfm/docs/cross_validation.html

于 2020-04-07T15:35:54.700 回答