首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Lightgbm排名示例

Lightgbm排名示例
EN

Stack Overflow用户
提问于 2020-06-24 13:16:37
回答 1查看 2.4K关注 0票数 9

对于如何使用lightgbm训练排名模型,有谁能与数据共享一个最小的例子吗?最好是使用Scikit-精益api?我正在挣扎的是如何传递标签数据。我的数据是页面印象,如下所示:

代码语言:javascript
复制
X:
user1, feature1, ...
user2, feature1, ...

y:
user1, page1, 10 impressions
user1, page2, 6 impressions
user2, page1, 9 impressions

到目前为止我想我已经弄明白了

  • 我的训练数据的长度必须是y(3)的长度:每一行(用户,页面)组。
  • -klearn api (标准api中的set_group())中的参数group是长度set(user_ids)的列表,其中每个条目都是这个用户访问过的不同页面的数量。在上面的例子中,thaat是(2,1)。此列表的和将等于我的训练集的长度。

但是如何给出对于user1来说,page1被访问的频率比page2更多的信息呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-20 13:26:24

下面是我如何使用LightGBM LambdaRank的方法。

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

代码语言:javascript
复制
import numpy as np
import pandas as pd
import lightgbm

df = pd.DataFrame({
    "query_id":[i for i in range(100) for j in range(10)],
    "var1":np.random.random(size=(1000,)),
    "var2":np.random.random(size=(1000,)),
    "var3":np.random.random(size=(1000,)),
    "relevance":list(np.random.permutation([0,0,0,0,0, 0,0,0,1,1]))*100
})

这是数据文件:

代码语言:javascript
复制
     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设置。我将数据集分为训练集和验证集,但您可以任意操作。我建议在培训期间至少使用一个验证集。

代码语言:javascript
复制
train_df = df[:800]  # first 80%
validation_df = df[800:]  # remaining 20%

qids_train = train_df.groupby("query_id")["query_id"].count().to_numpy()
X_train = train_df.drop(["query_id", "relevance"], axis=1)
y_train = train_df["relevance"]

qids_validation = validation_df.groupby("query_id")["query_id"].count().to_numpy()
X_validation = validation_df.drop(["query_id", "relevance"], axis=1)
y_validation = validation_df["relevance"]

这可能就是你被困住的地方。我们为每个数据创建这3个向量/矩阵。X_train是索引变量的集合,因此是模型的输入数据。y_train是你的因变量,是你试图预测/排名的变量。最后,qids_train是查询ids。它们看起来是这样的:

代码语言:javascript
复制
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_train

代码语言:javascript
复制
         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]

这是y_train

代码语言:javascript
复制
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,因为我熟悉这个API。

代码语言:javascript
复制
model = lightgbm.LGBMRanker(
    objective="lambdarank",
    metric="ndcg",
)

这里我只使用极小的参数量。可以随意查看LightGBM文档并使用更多的参数,这是一个非常强大的库。为了开始训练过程,我们在模型上调用fit函数。在这里,我们指定要使用NDCG@10,并希望该函数每10次迭代一次就打印结果。

代码语言:javascript
复制
model.fit(
    X=X_train,
    y=y_train,
    group=qids_train,
    eval_set=[(X_validation, y_validation)],
    eval_group=[qids_validation],
    eval_at=10,
    verbose=10,
)

开始培训并打印:

代码语言:javascript
复制
[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

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

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62555987

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档