LogitObjective#

class empulse.metrics.LogitObjective[source]#

Class to compute the loss and gradient of a logistic regression objective.

An objective is the sum of a data term and an ElasticNetPenalty. Concrete objectives implement the data term through data_loss and data_gradient and set penalty; the regularized logit_* methods are derived from those here.

Keeping the two separable is what lets a solver treat them differently – most importantly LBFGSBOptimizer, which reformulates a non-smooth L1 penalty rather than handing its subgradient to a solver that assumes smoothness.

Overriding logit_loss/logit_gradient directly and leaving penalty as None remains supported: the objective is then opaque to solvers, which fall back to treating it as an arbitrary, possibly non-smooth function.

__call__(weights)[source]#

Compute the loss and its gradient for minimization.

Here for backward compatibility. Delegates to logit_loss_gradient.

data_gradient(weights)[source]#

Compute the gradient of the unregularized loss for minimization.

Parameters:
weightsndarray

Coefficient vector.

Returns:
ndarray

Gradient of the data term alone.

data_loss(weights)[source]#

Compute the unregularized loss for minimization.

Parameters:
weightsndarray

Coefficient vector.

Returns:
float

Loss of the data term alone.

data_loss_gradient(weights)[source]#

Compute the unregularized loss and its gradient for minimization.

Parameters:
weightsndarray

Coefficient vector.

Returns:
lossfloat

Loss of the data term alone.

gradientndarray

Gradient of the data term alone.

logit_gradient(weights)[source]#

Compute the gradient of the loss for minimization.

Parameters:
weightsndarray

Coefficient vector.

Returns:
ndarray

Regularized gradient.

logit_gradient_steps()[source]#

Yield gradients for successive weight vectors.

Send either a weights vector or a (weights, refresh) tuple into the generator; for this objective refresh is accepted but ignored.

Yields:
gradientndarray

Gradient at the weights last sent in.

Examples

Driving the generator by hand (objective is a built objective, theta a coefficient vector):

gen = objective.logit_gradient_steps()
grad = gen.send(theta)  # first time gradient is computed from scratch
grad = gen.send(theta)  # gradient computed from cached information
grad = gen.send((theta, True))  # gradient computed from scratch
gen.close()
logit_loss(weights)[source]#

Compute the loss for minimization.

Parameters:
weightsndarray

Coefficient vector.

Returns:
float

Regularized loss.

logit_loss_gradient(weights)[source]#

Compute the loss and its gradient for minimization.

Parameters:
weightsndarray

Coefficient vector.

Returns:
lossfloat

Regularized loss.

gradientndarray

Regularized gradient.

penalty = None#

Penalty applied on top of the data term. None means the objective already includes whatever penalty it wants inside logit_loss/logit_gradient, and solvers must treat it as opaque.

set_alpha(alpha)[source]#

Override the smoothing parameter alpha (no-op for objectives without alpha annealing).

Gradient optimizers with an alpha_schedule call this before each gradient computation to externally drive the annealing schedule. Objectives that implement alpha annealing (e.g. MaxProfitLogitGradientPiecewise) override this method; all others silently ignore the call.

Parameters:
alphafloat

New alpha value to use for the next gradient computation.

with_indices(indices)[source]#

Return a new objective restricted to the sample subset given by indices.

Used by gradient optimizers for mini-batch training. The default implementation raises NotImplementedError; concrete objectives that store their data should override this method.

Only the data arrays are sliced. penalty is shared unchanged, because its scale is already an average and mini-batch data gradients are themselves 1 / batch_size means, so the penalty stays consistent across batch sizes.

Parameters:
indicesndarray of int

Row indices into the full training set.

Returns:
LogitObjective

A new objective for the selected samples.

Raises:
NotImplementedError

If this objective does not support mini-batch slicing.