One-hot encode class labels

Easy8 min11 hidden tests

A support-ticket classifier sorts tickets into num_classes queues, numbered from 0. The training labels arrive as one integer per ticket, but the loss function wants one row per ticket with 1.0 in the column of its queue and 0.0 everywhere else. Write one_hot(labels, num_classes) that builds this matrix. Some queues may have no tickets in a batch, and their columns stay all zeros.

Tap a cell to move a ticket

row i: 1.0 in column labels[i]

labels = [2, 0, 1, 1, 0] becomes a (5, 4) matrix. Ticket 0 is in queue 2, so row 0 has 1.0 in column 2. Queue 3 got no tickets, so its column stays all zeros: the width is num_classes, not the highest label.

Shape 5 by 4.

Examples

Three tickets, one in each queue

one_hot([2, 0, 1], 3)

returns [[0, 0, 1], [1, 0, 0], [0, 1, 0]]

Queues 2 and 3 got no tickets, so their columns are all zeros

one_hot([1, 1, 0], 4)

returns [[0, 1, 0, 0], [0, 1, 0, 0], [1, 0, 0, 0]]

Requirements

  • labels is a list or 1-D array of n integers (n of 1 or more), each from 0 to num_classes - 1.
  • Return a float NumPy array of shape (n, num_classes).
  • Row i has 1.0 in column labels[i] and 0.0 everywhere else.
  • The width is always num_classes, even when the highest classes are missing from labels.
The idea behind it

Class ids are names for categories. Queue 2 is in no sense twice queue 1, so feeding the raw integer to a model would invent an order and a distance that do not exist. One-hot encoding fixes that: each class gets its own column, and a label becomes a row with 1.0 in its column and 0.0 elsewhere.

The same rows are the targets for cross-entropy loss. The model outputs one probability per class, and the loss compares that row with the one-hot row. The width has to be the full number of classes so every batch lines up with the model's output layer, even a batch where some classes never appear.

Libraries ship this as a helper, such as torch.nn.functional.one_hot and Keras's to_categorical. Most of them take the number of classes as an argument for exactly this reason.

pythonCtrl+Enter runs
import numpy as np

def one_hot(labels, num_classes):
"""One-hot encode integer class labels.

labels: list or 1-D array of n ints, each in 0..num_classes - 1
num_classes: int, the number of classes (the width of the output)
Returns a float array of shape (n, num_classes) with a single 1.0
per row, in the column of that row's label.
"""
raise NotImplementedError

Stuck? Reveal one rung at a time

Worked solution

Pro includes the solution and walkthrough for every problem, plus the hands-on labs. The first problem of each topic is free.