Python 如何使用lightgbm实现学习排名?

Python 如何使用lightgbm实现学习排名?,python,rank,lightgbm,Python,Rank,Lightgbm,我正在尝试使用lightgbm设置学习排名,我有以下数据集,其中包含基于查询的用户交互: df = pd.DataFrame({'QueryID': [1, 1, 1, 2, 2, 2], 'ItemID': [1, 2, 3, 1, 2, 3], 'Position': [1, 2 , 3, 1, 2, 3], 'Interaction': ['CLICK', 'VIEW',

我正在尝试使用
lightgbm
设置学习排名,我有以下数据集,其中包含基于查询的用户交互:

df = pd.DataFrame({'QueryID': [1, 1, 1, 2, 2, 2], 
                   'ItemID': [1, 2, 3, 1, 2, 3], 
                   'Position': [1, 2 , 3, 1, 2, 3], 
                   'Interaction': ['CLICK', 'VIEW', 'BOOK', 'BOOK', 'CLICK', 'VIEW']})

问题是如何正确设置用于培训的数据集?文档中提到使用Dataset.set_group(),但在将此数据转换为组之前,不清楚如何使用。

。您必须创建一个分数变量,即因变量,然后生成训练和测试文件。 最重要的是,您需要为train和test创建两个组文件(查找使用相同qid(即QueryID)的次数)

阅读本文以获取更多参考资料:

  • 下面是我回答另一个问题时给出的一般性示例:()

  • 如果要避免复制答案,请让我知道,我可以删除它


下面是我如何使用LightGBM LambdaRank的

首先,我们导入一些库并定义数据集

将numpy导入为np
作为pd进口熊猫
导入lightgbm
df=pd.DataFrame({
“查询id”:[i代表范围(100)中的i代表范围(10)中的j],
“var1”:np.random.random(大小=(1000,),
“var2”:np.random.random(大小=(1000,),
“var3”:np.random.random(大小=(1000,),
“相关性”:列表(np.随机排列([0,0,0,0,0,0,0,0,1])*100
})
以下是数据帧:

     query_id      var1      var2      var3  relevance
0           0  0.624776  0.191463  0.598358          0
1           0  0.258280  0.658307  0.148386          0
2           0  0.893683  0.059482  0.340426          0
3           0  0.879514  0.526022  0.712648          1
4           0  0.188580  0.279471  0.062942          0
..        ...       ...       ...       ...        ...
995        99  0.509672  0.552873  0.166913          0
996        99  0.244307  0.356738  0.925570          0
997        99  0.827925  0.827747  0.695029          1
998        99  0.476761  0.390823  0.670150          0
999        99  0.241392  0.944994  0.671594          0

[1000 rows x 5 columns]
这个数据集的结构很重要。在学习对任务进行排序时,您可能需要处理一组查询。在这里,我定义了一个1000行的数据集,包含100个查询,每个查询10行。这些查询也可以是可变长度的

现在对于每个查询,我们都有一些变量,并且我们也得到了相关性。我在这里使用了数字0和1,所以对于每个查询(一组10行),我想创建一个模型,为相关性为1的2行分配更高的相关性

无论如何,我们将继续LightGBM的设置。我将数据集分为训练集和验证集,但您可以做任何您想做的事情。我建议在培训期间至少使用一个验证集

train_df=df[:800]#前80%
验证_df=df[800:]#剩余20%
qids\u train=train\u df.groupby(“query\u id”)[“query\u id”].count().to\u numpy()
X_列=列方向下降([“查询id”,“相关性”],轴=1)
y_train=train_df[“相关性”]
qids\u validation=validation\u df.groupby(“查询id”)[“查询id”].count().to_numpy()
X_validation=validation_df.drop([“查询id”,“相关性”],axis=1)
y_validation=validation_df[“相关性”]
现在这可能就是你被困的地方。我们为每个数据帧创建这3个向量/矩阵。
X\u列
是独立变量的集合,因此是模型的输入数据
y_train
是您的因变量,即您试图预测/排序的内容。最后,
qids\u train
是您的查询ID。它们看起来像这样:

array([10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
       10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
       10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
       10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
       10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10])
这也是
X\u列车

         var1      var2      var3
0    0.624776  0.191463  0.598358
1    0.258280  0.658307  0.148386
2    0.893683  0.059482  0.340426
3    0.879514  0.526022  0.712648
4    0.188580  0.279471  0.062942
..        ...       ...       ...
795  0.014315  0.302233  0.255395
796  0.247962  0.871073  0.838955
797  0.605306  0.396659  0.940086
798  0.904734  0.623580  0.577026
799  0.745451  0.951092  0.861373

[800 rows x 3 columns]
0      0
1      0
2      0
3      1
4      0
      ..
795    0
796    0
797    1
798    0
799    0
Name: relevance, Length: 800, dtype: int64
这是你们的列车:

         var1      var2      var3
0    0.624776  0.191463  0.598358
1    0.258280  0.658307  0.148386
2    0.893683  0.059482  0.340426
3    0.879514  0.526022  0.712648
4    0.188580  0.279471  0.062942
..        ...       ...       ...
795  0.014315  0.302233  0.255395
796  0.247962  0.871073  0.838955
797  0.605306  0.396659  0.940086
798  0.904734  0.623580  0.577026
799  0.745451  0.951092  0.861373

[800 rows x 3 columns]
0      0
1      0
2      0
3      1
4      0
      ..
795    0
796    0
797    1
798    0
799    0
Name: relevance, Length: 800, dtype: int64
请注意,它们都是数据帧,LightGBM支持它们,但numpy阵列也可以工作

如您所见,它们指示每个查询的长度。如果您的查询长度可变,那么此列表中的数字也会不同。在我的示例中,所有查询的长度都相同

我们对验证集执行完全相同的操作,然后准备开始LightGBM模型设置和培训。我使用SKlearn API,因为我熟悉它

model=lightgbm.LGBMRanker(
目标=“lambdarank”,
metric=“ndcg”,
)
我在这里只使用最少量的参数。请随意查看LightGBM文档并使用更多参数,它是一个非常强大的库。 为了开始训练过程,我们在模型上调用fit函数。这里我们指定我们想要的NDCG@5,并希望函数每10次迭代打印一次结果

model.fit(
X=X_列车,
y=y_列车,
组=qids_列车,
eval_set=[(X_验证,y_验证)],
评估组=[qids\U验证],
在=10时进行评估,
详细=10,
)
开始培训并打印:

[10]    valid_0's ndcg@10: 0.562929
[20]    valid_0's ndcg@10: 0.55375
[30]    valid_0's ndcg@10: 0.538355
[40]    valid_0's ndcg@10: 0.548532
[50]    valid_0's ndcg@10: 0.549039
[60]    valid_0's ndcg@10: 0.546288
[70]    valid_0's ndcg@10: 0.547836
[80]    valid_0's ndcg@10: 0.552541
[90]    valid_0's ndcg@10: 0.551994
[100]   valid_0's ndcg@10: 0.542401

我希望我能用这个简单的例子充分说明这个过程。如果您还有任何问题,请告诉我。

您好,您能把问题说清楚一点吗?
Position
是您的目标吗?或者你是想得到一个解决方案,比如亚马逊用来提出有趣的东西?那更像是协同过滤。嗨!不幸的是,您共享的文章没有提供有关数据集外观的更多信息。