EasyMetrics & Evaluation

Log Loss (Per-Sample)

Metrics & Evaluation

Easy

Problem

Compute binary log loss independently for every sample. Clip each predicted probability before applying the logarithm:

\widehat p=\min(1-\varepsilon,\max(\varepsilon,p))

L(y,p)=-\left[y\ln(\widehat p)+(1-y)\ln(1-\widehat p)\right]

Here, y is a binary target, p is its predicted probability, and \varepsilon is eps. Use the natural logarithm and return a list of losses in input order.

Theory

In binary classification:

The model outputs a single probability for the positive class. The probability of the negative class is 1 - \hat{y}.


Log Loss for a Single Sample

The log loss (also called binary cross-entropy) for one sample is:

L = -[y \log(\hat{y}) + (1-y) \log(1-\hat{y})]

This formula has two cases:

When y = 1 (positive class):

L = -\log(\hat{y}) The loss is the negative log of the predicted probability for the positive class.

When y = 0 (negative class):

L = -\log(1-\hat{y}) The loss is the negative log of the predicted probability for the negative class.


Understanding the Formula

The loss measures how surprised you should be given your prediction:

Correct and confident:

Correct but uncertain:

Wrong and uncertain:

Wrong and confident:


The Loss Curve

For a positive sample (y = 1), loss as function of predicted probability:

p = 0.99: loss = 0.01 p = 0.90: loss = 0.105 p = 0.70: loss = 0.357 p = 0.50: loss = 0.693 p = 0.30: loss = 1.204 p = 0.10: loss = 2.303 p = 0.01: loss = 4.605

Key observations:


Why Logarithm?

The logarithm is not arbitrary. It comes from information theory:

Information content: The information gained from observing an event with probability p is -\log(p).

Surprise: If you predict p = 0.9 and the event happens, you are not surprised (low information gain). If you predict p = 0.1 and it happens, you are very surprised (high information gain).

Proper scoring rule: Log loss is a proper scoring rule, meaning the optimal prediction is always the true probability. You cannot game the metric by predicting something other than your true belief.


Aggregating Over Multiple Samples

For a dataset with n samples:

L_{\text{total}} = -\frac{1}{n}\sum_{i=1}^{n}[y_i \log(\hat{y}_i) + (1-y_i) \log(1-\hat{y}_i)]

This is the mean log loss, which:


Connection to Cross-Entropy

Log loss and binary cross-entropy are the same thing:

L = -[y \log(\hat{y}) + (1-y) \log(1-\hat{y})] = H(y, \hat{y})

Where H(y, \hat{y}) is the cross-entropy between the true distribution y (a delta at 0 or 1) and the predicted distribution \hat{y}.

Multi-class cross-entropy is the generalization to more than 2 classes.


The Gradient

The gradient of log loss with respect to the predicted probability:

\frac{\partial L}{\partial \hat{y}} = -\frac{y}{\hat{y}} + \frac{1-y}{1-\hat{y}}

For y = 1: gradient = -1/\hat{y} (negative, push prediction up) For y = 0: gradient = 1/(1-\hat{y}) (positive, push prediction down)

The gradient magnitude:


Numerical Stability

Computing log(p) is dangerous when p is near 0:

Solutions:

Clipping: Clip predictions to [epsilon, 1-epsilon] where epsilon = 1e-7

Log-sum-exp trick: Compute log(sigmoid(z)) directly from logit z

Framework functions: Use built-in functions like torch.nn.BCEWithLogitsLoss that handle stability internally.


Log Loss vs. Other Metrics

Accuracy:

Log loss:

Example with two models predicting y=1:

Accuracy sees both as correct. Log loss sees Model B as much better.


Where Log Loss Is Used

Examples

Example 1

Input
y_true = [1, 0, 1], y_pred = [0.9, 0.1, 0.8], eps = 1e-15
Output
[0.105361, 0.105361, 0.223144]
Explanation
Each confident correct prediction produces a small positive loss.

Example 2

Input
y_true = [1, 0], y_pred = [1, 0], eps = 1e-15
Output
[0, 0]

Hints

  1. Clip with max(eps, min(1 - eps, probability)).
  2. Append -(y * math.log(p) + (1 - y) * math.log(1 - p)) for each pair.

Requirements

Constraints

Starter Code

import math

def log_loss(y_true: list, y_pred: list, eps: float = 1e-15) -> list:
    """
    Returns a list of loss values.
    """
    # Write code here
    pass

Test Cases

CaseMatches
Simplepublic
Clippingpublic