Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to optimize for NDCG at a given truncation level #3425

Merged
merged 15 commits into from
Oct 27, 2020

Conversation

metpavel
Copy link
Collaborator

Fixes #3420

In order to correctly optimize for NDCG@_k_, one should exclude pairs containing both documents beyond the top-_k_ (as they don't affect NDCG@_k_ when swapped).
@ghost
Copy link

ghost commented Sep 30, 2020

CLA assistant check
All CLA requirements met.

@guolinke
Copy link
Collaborator

Any benchmarks for the change?

@metpavel
Copy link
Collaborator Author

metpavel commented Oct 1, 2020

Any benchmarks for the change?

For MSLR-WEB30K dataset (fold 1) using default train.conf, performance on the validation set:
Optimize for NDCG@FullRank:
ndcg@1 : 0.498897
ndcg@3 : 0.484631
ndcg@5 : 0.487863
208.163323 seconds elapsed, finished iteration 100

Optimize for NDCG@20:
ndcg@1 : 0.502574
ndcg@3 : 0.486615
ndcg@5 : 0.489424
124.763394 seconds elapsed, finished iteration 100

Optimize for NDCG@10:
ndcg@1 : 0.504389
ndcg@3 : 0.487059
ndcg@5 : 0.48924
93.361508 seconds elapsed, finished iteration 100

Optimize for NDCG@5:
ndcg@1 : 0.498769
ndcg@3 : 0.483403
ndcg@5 : 0.48611
96.900527 seconds elapsed, finished iteration 100

Optimize for NDCG@3:
ndcg@1 : 0.503184
ndcg@3 : 0.483097
ndcg@5 : 0.485419
79.423862 seconds elapsed, finished iteration 100

Optimize for NDCG@1:
ndcg@1 : 0.502715
ndcg@3 : 0.47437
ndcg@5 : 0.47624
71.433821 seconds elapsed, finished iteration 100

@jameslamb jameslamb added the fix label Oct 6, 2020
@guolinke guolinke added feature and removed fix labels Oct 9, 2020
@guolinke
Copy link
Collaborator

guolinke commented Oct 9, 2020

I think this PR is a new feature.

@guolinke
Copy link
Collaborator

guolinke commented Oct 9, 2020

@metpavel Is the result of "full rank" the same as before?

const data_size_t low = sorted_idx[j];
// start accmulate lambdas by pairs that contain at least one document above truncation level
for (data_size_t i = 0; i < cnt - 1 && i < truncation_level_; ++i) {
for (data_size_t j = i + 1; j < cnt; ++j) {
Copy link
Collaborator

@guolinke guolinke Oct 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this start from '0' ? if not, why?

updated:
I see. never mind.

src/objective/rank_objective.hpp Show resolved Hide resolved
src/objective/rank_objective.hpp Outdated Show resolved Hide resolved
const double high_label_gain = label_gain_[high_label];
const double high_discount = DCGCalculator::GetDiscount(high_rank);

const data_size_t low_rank = label[sorted_idx[i]] > label[sorted_idx[j]] ? j : i;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the additional branching? get high_rank and low_rank by one if.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

metpavel and others added 2 commits October 9, 2020 14:25
Co-authored-by: Guolin Ke <guolin.ke@outlook.com>
remove the additional branching: get high_rank and low_rank by one "if".
@metpavel
Copy link
Collaborator Author

metpavel commented Oct 9, 2020

@metpavel Is the result of "full rank" the same as before?

@guolinke, yes

@guolinke
Copy link
Collaborator

guolinke commented Oct 9, 2020

From the results, it seems we need a slightly larger truncation level, e.g. k + m, to optimize NDCG@k?

@metpavel
Copy link
Collaborator Author

metpavel commented Oct 9, 2020

From the results, it seems we need a slightly larger truncation level, e.g. k + m, to optimize NDCG@k?

@guolinke, perhaps one may want to treat that m as a tunable hyper-parameter to balance between better alignment with the desired cutoff k (smaller m) and more pairs to train on (larger m)

@guolinke
Copy link
Collaborator

guolinke commented Oct 9, 2020

@metpavel Yes, maybe you can add this description into the document of truncation level?

@metpavel
Copy link
Collaborator Author

@metpavel Yes, maybe you can add this description into the document of truncation level?

@guolinke, do you mean here: /blob/master/docs/Parameters.rst?

@guolinke
Copy link
Collaborator

guolinke commented Oct 11, 2020

@metpavel we usually write the doc for parameters in config.h, and then run helpers/parameter_generator.py to auto-update .rst file.

@guolinke
Copy link
Collaborator

BTW, can you also merge master, to ensure CI passes?

add description to lambdarank_truncation_level parameter
@guolinke
Copy link
Collaborator

@jameslamb can you help to fix the R's tests? It needs to update some ranking score constraints, as the ranking objective is updated.

update expected NDCG value for a test, as it was affected by the underlying change in the algorithm
update NDCG@3 reference value
@jameslamb
Copy link
Collaborator

@jameslamb can you help to fix the R's tests? It needs to update some ranking score constraints, as the ranking objective is updated.

ok sure, I can help

@jameslamb
Copy link
Collaborator

@metpavel I just created a pull request into this branch on your fork. If you merge it, it should fix the R tests

metpavel#1

// lambda is negative, so use minus to accumulate
sum_lambdas -= 2 * p_lambda;
}
// update
lambdas[high] += static_cast<score_t>(high_sum_lambda);
hessians[high] += static_cast<score_t>(high_sum_hessian);
}
if (norm_ && sum_lambdas > 0) {
double norm_factor = std::log2(1 + sum_lambdas) / sum_lambdas;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/gha run-valgrind

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/gha run r-valgrind

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ this comment started this run checking that these changes pass our valgrind tests: https://github.com/microsoft/LightGBM/runs/1296338580?check_suite_focus=true

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this didn't show any new issues...but I'll run it again once my fixes are merged into this PR: #3425 (comment)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/gha run-valgrind

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/gha run r-valgrind

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

include/LightGBM/config.h Outdated Show resolved Hide resolved
@guolinke guolinke mentioned this pull request Oct 26, 2020
Co-authored-by: Guolin Ke <guolin.ke@outlook.com>
@guolinke
Copy link
Collaborator

You need to re-run the parameter generator, due to the default value is changed.

@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity since it was closed. To start a new related discussion, open a new issue at https://github.com/microsoft/LightGBM/issues including a reference to this.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 24, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

LambdarankNDCG objective ignores truncation level
3 participants