Lightgbm排名示例
Lightgbm ranking example
任何人都可以分享一个关于如何使用 lightgbm 训练排名模型的最小数据示例吗?最好使用 Scikit-Lean api?我苦苦挣扎的是如何传递标签数据。我的数据是页面展示次数,如下所示:
X:
user1, feature1, ...
user2, feature1, ...
y:
user1, page1, 10 impressions
user1, page2, 6 impressions
user2, page1, 9 impressions
到目前为止我想我已经明白了
- 我的训练数据的长度必须是上面 y (3) 的长度:每个(用户,页面)组一行。
- scikit-klearn api中的参数
group
(标准api中的set_group()
)是一个长度为set(user_ids)
的列表,其中每个条目是该用户访问过的不同页面的数量。在上面的示例中,thaat 将是 (2, 1)。此列表的总和将等于我的训练集的长度。
但是如何给出user1的page1比page2访问次数多的信息呢?
下面是我如何使用 LightGBM LambdaRank。
首先我们导入一些库并定义我们的数据集
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
})
这是数据框:
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 的设置。我将数据集拆分为训练集和验证集,但你可以随心所欲。我建议在训练期间至少使用 1 个验证集。
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 个 vectors/matrices。 X_train
是独立变量的集合,因此是模型的输入数据。 y_train
是你的因变量,你正在尝试 predict/rank。最后,qids_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_train
:
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
:
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
请注意,它们都是 pandas 数据帧,LightGBM 支持它们,但是 numpy 数组也可以。
如您所见,它们表示每个查询的长度。如果您的查询长度可变,那么此列表中的数字也会不同。在我的示例中,所有查询的长度都相同。
我们对验证集做完全相同的事情,然后我们准备开始 LightGBM 模型设置和训练。我使用 SKlearn API 因为我熟悉它。
model = lightgbm.LGBMRanker(
objective="lambdarank",
metric="ndcg",
)
我在这里只使用了最少的参数。随意看看 LightGBM 文档并使用更多参数,它是一个非常强大的库。
要开始训练过程,我们调用模型上的拟合函数。这里我们指定我们想要 NDCG@10,并希望函数每 10 次迭代打印一次结果。
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,
)
开始训练并打印:
[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
我希望我能用这个简单的例子充分说明这个过程。如果您还有任何问题,请告诉我。
任何人都可以分享一个关于如何使用 lightgbm 训练排名模型的最小数据示例吗?最好使用 Scikit-Lean api?我苦苦挣扎的是如何传递标签数据。我的数据是页面展示次数,如下所示:
X:
user1, feature1, ...
user2, feature1, ...
y:
user1, page1, 10 impressions
user1, page2, 6 impressions
user2, page1, 9 impressions
到目前为止我想我已经明白了
- 我的训练数据的长度必须是上面 y (3) 的长度:每个(用户,页面)组一行。
- scikit-klearn api中的参数
group
(标准api中的set_group()
)是一个长度为set(user_ids)
的列表,其中每个条目是该用户访问过的不同页面的数量。在上面的示例中,thaat 将是 (2, 1)。此列表的总和将等于我的训练集的长度。
但是如何给出user1的page1比page2访问次数多的信息呢?
下面是我如何使用 LightGBM LambdaRank。
首先我们导入一些库并定义我们的数据集
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
})
这是数据框:
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 的设置。我将数据集拆分为训练集和验证集,但你可以随心所欲。我建议在训练期间至少使用 1 个验证集。
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 个 vectors/matrices。 X_train
是独立变量的集合,因此是模型的输入数据。 y_train
是你的因变量,你正在尝试 predict/rank。最后,qids_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_train
:
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
:
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
请注意,它们都是 pandas 数据帧,LightGBM 支持它们,但是 numpy 数组也可以。
如您所见,它们表示每个查询的长度。如果您的查询长度可变,那么此列表中的数字也会不同。在我的示例中,所有查询的长度都相同。
我们对验证集做完全相同的事情,然后我们准备开始 LightGBM 模型设置和训练。我使用 SKlearn API 因为我熟悉它。
model = lightgbm.LGBMRanker(
objective="lambdarank",
metric="ndcg",
)
我在这里只使用了最少的参数。随意看看 LightGBM 文档并使用更多参数,它是一个非常强大的库。 要开始训练过程,我们调用模型上的拟合函数。这里我们指定我们想要 NDCG@10,并希望函数每 10 次迭代打印一次结果。
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,
)
开始训练并打印:
[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
我希望我能用这个简单的例子充分说明这个过程。如果您还有任何问题,请告诉我。