|
| 1 | +""" |
| 2 | +Hinge Loss |
| 3 | +
|
| 4 | +Description: |
| 5 | +Compute the Hinge loss used for training SVM (Support Vector Machine). |
| 6 | +
|
| 7 | +Formula: |
| 8 | +loss = max(0, 1 - true * pred) |
| 9 | +
|
| 10 | +Reference: https://en.wikipedia.org/wiki/Hinge_loss |
| 11 | +
|
| 12 | +Author: Poojan Smart |
| 13 | + |
| 14 | +""" |
| 15 | + |
| 16 | +import numpy as np |
| 17 | + |
| 18 | + |
| 19 | +def hinge_loss(y_true: np.ndarray, y_pred: np.ndarray) -> float: |
| 20 | + """ |
| 21 | + Calculate the mean hinge loss for y_true and y_pred for binary classification. |
| 22 | +
|
| 23 | + Args: |
| 24 | + y_true: Array of actual values (ground truth) encoded as -1 and 1. |
| 25 | + y_pred: Array of predicted values. |
| 26 | +
|
| 27 | + Returns: |
| 28 | + The hinge loss between y_true and y_pred. |
| 29 | +
|
| 30 | + Examples: |
| 31 | + >>> y_true = np.array([-1, 1, 1, -1, 1]) |
| 32 | + >>> pred = np.array([-4, -0.3, 0.7, 5, 10]) |
| 33 | + >>> hinge_loss(y_true, pred) |
| 34 | + 1.52 |
| 35 | + >>> y_true = np.array([-1, 1, 1, -1, 1, 1]) |
| 36 | + >>> pred = np.array([-4, -0.3, 0.7, 5, 10]) |
| 37 | + >>> hinge_loss(y_true, pred) |
| 38 | + Traceback (most recent call last): |
| 39 | + ... |
| 40 | + ValueError: Length of predicted and actual array must be same. |
| 41 | + >>> y_true = np.array([-1, 1, 10, -1, 1]) |
| 42 | + >>> pred = np.array([-4, -0.3, 0.7, 5, 10]) |
| 43 | + >>> hinge_loss(y_true, pred) |
| 44 | + Traceback (most recent call last): |
| 45 | + ... |
| 46 | + ValueError: y_true can have values -1 or 1 only. |
| 47 | + """ |
| 48 | + |
| 49 | + if len(y_true) != len(y_pred): |
| 50 | + raise ValueError("Length of predicted and actual array must be same.") |
| 51 | + |
| 52 | + # Raise value error when y_true (encoded labels) have any other values |
| 53 | + # than -1 and 1 |
| 54 | + if np.any((y_true != -1) & (y_true != 1)): |
| 55 | + raise ValueError("y_true can have values -1 or 1 only.") |
| 56 | + |
| 57 | + hinge_losses = np.maximum(0, 1.0 - (y_true * y_pred)) |
| 58 | + return np.mean(hinge_losses) |
| 59 | + |
| 60 | + |
| 61 | +if __name__ == "__main__": |
| 62 | + import doctest |
| 63 | + |
| 64 | + doctest.testmod() |
0 commit comments