EasyLoss Functions

Implement Hinge Loss (Binary SVM)

Loss Functions

Easy

Problem

Compute binary hinge loss from labels in \{-1,+1\} and real-valued prediction scores:

\ell_i = \max(0, m-y_is_i)

Here, y_i is the label, s_i is its prediction score, m is the margin, and \ell_i is the sample loss. Return the mean of the sample losses when reduction="mean" or their sum when reduction="sum". The result must be a Python float.

Theory

Hinge loss is the loss function behind Support Vector Machines (SVMs). It was designed with a specific goal: maximize the margin between classes.

For binary classification with labels y \in \{-1, +1\} and raw model output f(x) (not a probability):

L = \max(0, 1 - y \cdot f(x))

This deceptively simple formula encodes a powerful idea: the model should not just classify correctly, but classify with confidence.


Breaking Down the Formula

The term y \cdot f(x) is called the functional margin:

The loss max(0, 1 - y * f(x)) then says:


Numerical Examples

Example 1: Confident correct prediction

Example 2: Weak correct prediction

Example 3: Wrong prediction

Example 4: Confident wrong prediction


The Margin Concept

The "1" in hinge loss represents the target margin. The model is asked to:

Why margin matters:

This is the core idea behind SVMs: find the hyperplane that separates classes with the largest margin.


The Loss Curve

For a positive sample (y = +1), plotting loss vs. f(x):

f(x) = -2.0: margin = -2.0, loss = 3.0 f(x) = -1.0: margin = -1.0, loss = 2.0 f(x) = 0.0: margin = 0.0, loss = 1.0 f(x) = 0.5: margin = 0.5, loss = 0.5 f(x) = 1.0: margin = 1.0, loss = 0.0 f(x) = 2.0: margin = 2.0, loss = 0.0

The curve is:

This is where the name "hinge loss" comes from.


The Gradient

\frac{\partial L}{\partial f(x)} = \begin{cases} 0 & \text{if } y \cdot f(x) \geq 1 \\ -y & \text{if } y \cdot f(x) < 1 \end{cases}

Key properties:

This sparsity of gradients is why SVMs have "support vectors": only samples near the decision boundary contribute to the gradient.


Hinge Loss vs. Cross-Entropy

Hinge loss:

Cross-entropy:

Hinge loss is "satisfied" once the margin is large enough. Cross-entropy always wants higher confidence, even for samples already correctly classified with high confidence.


Multi-Class Hinge Loss

For C classes, the multi-class hinge loss is:

L = \sum_{j \neq y} \max(0, 1 + f_j(x) - f_y(x))

Where:

Interpretation: for each wrong class, penalize if its score is within 1 of the true class score.


Squared Hinge Loss

A variant that penalizes misclassifications more heavily:

L = \max(0, 1 - y \cdot f(x))^2

Differences from standard hinge:


Where Hinge Loss Is Used

Examples

Example 1

Input
y_true = [1, 1, -1], y_score = [2, 0, 0], margin = 1.0, reduction = "mean"
Output
0.666667
Explanation
The sample losses are [0, 1, 1], whose mean is 2/3.

Example 2

Input
y_true = [-1, 1], y_score = [-3, 0.5], margin = 1.0, reduction = "mean"
Output
0.25

Hints

  1. Use np.maximum(0.0, margin - y_true * y_score) to compute all sample losses.
  2. Finish with .mean() or .sum() according to reduction.

Requirements

Constraints

Starter Code

import numpy as np

def hinge_loss(y_true: list, y_score: list, margin: float = 1.0, reduction: str = "mean") -> float:
    """
    Returns the loss as a float.
    """
    # Write code here
    pass

Test Cases

CaseMatches
Basicpublic
With marginpublic