Skip to content

[WIP] Test custom obj function#21

Draft
wagnerlmichael wants to merge 11 commits into
masterfrom
test-new-obj-function
Draft

[WIP] Test custom obj function#21
wagnerlmichael wants to merge 11 commits into
masterfrom
test-new-obj-function

Conversation

@wagnerlmichael
Copy link
Copy Markdown
Member

@wagnerlmichael wagnerlmichael commented Apr 10, 2026

This PR builds a custom objective function closure to be passed to lightgbm.

Supports model PR: ccao-data/model-res-avm#475

Comment thread R/lightgbm.R
custom_obj <- make_obj_mse_cov(rho = rho_val, y_mean = mean(y))
# When `obj` is a custom callback we must NOT also set `objective` in
# params, otherwise lgb.train will reject the unknown name.
others$objective <- NULL
Copy link
Copy Markdown
Member Author

@wagnerlmichael wagnerlmichael Apr 15, 2026

Choose a reason for hiding this comment

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

LightGBM takes either objective or obj args, code here, and ultimately collects one of the two as objective

More context on the comment here from the lightbgm source code. Shown here:

  # extract any function objects passed for objective or metric
  fobj <- NULL
  if (is.function(params$objective)) {
    fobj <- params$objective
    params$objective <- "none"
  }

Checks to see if if there is a custom function supplied, saves it as fobj to be passed to C later using gradient and hessian, and the "none" value lets lightgbm know that the custom math will be supplied later, rather than it using one of its built in C objective functions.

Comment thread R/lightgbm.R Outdated
custom_obj <- NULL
if (!is.null(others$objective) && identical(others$objective, "mse_cov")) {
rho_val <- if (is.null(mse_cov_rho)) 1e-3 else as.numeric(mse_cov_rho)
custom_obj <- make_obj_mse_cov(rho = rho_val, y_mean = mean(y))
Copy link
Copy Markdown
Member Author

@wagnerlmichael wagnerlmichael Apr 15, 2026

Choose a reason for hiding this comment

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

This function ultimately ends up in lightbgm source code here

Where it gets passed to a C program for compuation, expecting a gradient and a hessian, supplied by R/objectives.R

Comment thread R/objectives.R
small_h <- hess < zero_grad_tol
if (any(small_h)) hess[small_h] <- zero_grad_tol

list(grad = grad, hess = hess)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This list is passed and parsed as gpair in lightbm source code

Comment thread R/lightgbm.R
stats::predict(
object$fit,
as.matrix(new_data),
type = "raw",
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This stops the script of dropping a bunch of warnings

Comment thread R/objectives.R
#' passing as the `obj` argument of [lightgbm::lgb.train].
#'
#' @export
make_obj_mse_cov <- function(rho, y_mean, zero_grad_tol = 1e-6) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The math here is completely borrowed from the source implementation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant