Package {labelnoise}


Title: Find Label Errors in Classification Data with Confident Learning
Version: 0.1.0
Description: Finds examples whose given class label is likely wrong, using out-of-sample predicted probabilities from any classifier. Implements confident learning (Northcutt, Jiang and Chuang, 2021) <doi:10.1613/jair.1.12125>: per-class confidence thresholds, the confident joint, calibrated estimates of the joint distribution of given and true labels, noise transition matrices, and five rank-and-prune rules for flagging label issues. Also provides model-agnostic label quality scores (Kuan and Mueller, 2022) <doi:10.5281/zenodo.18168246> and a per-class label health summary. Inputs can be a label vector with a probability matrix, a data frame of predictions, resampling results from 'tune', predictions from 'mlr3', or a fitted 'caret' model.
License: MIT + file LICENSE
URL: https://ridsonap.is-a.dev/labelnoise/, https://github.com/ridsonap/labelnoise
BugReports: https://github.com/ridsonap/labelnoise/issues
Encoding: UTF-8
Depends: R (≥ 4.1.0)
Imports: cli, rlang (≥ 1.1.0), stats, utils, tibble, tidyselect
Suggests: caret, knitr, lgr, mlr3, nnet, parsnip, rmarkdown, rsample, testthat (≥ 3.0.0), tune, withr, workflows, yardstick
VignetteBuilder: knitr
Config/testthat/edition: 3
Config/roxygen2/version: 8.0.0
NeedsCompilation: no
Packaged: 2026-10-28 13:06:50 UTC; macbook
Author: Ridson Al Farizal P ORCID iD [aut, cre, cph]
Maintainer: Ridson Al Farizal P <ridsonalfarizal15@gmail.com>
Repository: CRAN
Date/Publication: 2026-11-13 17:10:08 UTC

labelnoise: Find Label Errors in Classification Data with Confident Learning

Description

Finds examples whose given class label is likely wrong, using out-of-sample predicted probabilities from any classifier. Implements confident learning (Northcutt, Jiang and Chuang, 2021) doi:10.1613/jair.1.12125: per-class confidence thresholds, the confident joint, calibrated estimates of the joint distribution of given and true labels, noise transition matrices, and five rank-and-prune rules for flagging label issues. Also provides model-agnostic label quality scores (Kuan and Mueller, 2022) doi:10.5281/zenodo.18168246 and a per-class label health summary. Inputs can be a label vector with a probability matrix, a data frame of predictions, resampling results from 'tune', predictions from 'mlr3', or a fitted 'caret' model.

Author(s)

Maintainer: Ridson Al Farizal P ridsonalfarizal15@gmail.com (ORCID) [copyright holder]

Authors:

See Also

Useful links:


Per-class confidence thresholds

Description

The threshold of class j is the mean predicted probability of class j among examples whose given label is j (Northcutt et al., 2021, Eq. 2). An example is a confident member of class j when its predicted probability for j reaches this threshold.

Usage

class_thresholds(x, ...)

Arguments

x

Labels or an object holding labels and predicted probabilities. See Description.

...

Passed to label_inputs(): for example pred_probs when x is a label vector, or truth when x is a data frame.

Value

A named numeric vector with one threshold per class. Classes without any given label get Inf, so no example is counted as a confident member of them.

References

Northcutt, C., Jiang, L., & Chuang, I. (2021). Confident learning: Estimating uncertainty in dataset labels. Journal of Artificial Intelligence Research, 70, 1373–1411. doi:10.1613/jair.1.12125

Examples

sim <- simulate_label_noise(n = 200, seed = 1)
class_thresholds(sim, truth = given)

The confident joint

Description

confident_joint() counts, for every pair of given label i and (estimated) true label j, the examples labelled i that are confident members of class j (Northcutt et al., 2021, Eq. 1 and Algorithm 1). An example is a confident member of class j when its predicted probability for j is at least the threshold of j (see class_thresholds()). When it is a confident member of several classes, the one with the largest predicted probability among them is used. Examples that are confident members of no class are not counted.

With calibrate = TRUE, each row is rescaled so that it sums to the number of examples with that given label (the numerator of Eq. 3). Rows with no confident examples are treated as noise free.

Off-diagonal cells are label errors: examples given label i that look like they belong to class j.

Usage

confident_joint(x, ..., calibrate = TRUE)

Arguments

x

Labels or an object holding labels and predicted probabilities. See Description.

...

Passed to label_inputs(): for example pred_probs when x is a label vector, or truth when x is a data frame.

calibrate

Rescale rows to the observed class counts?

Value

A square matrix with dimension names given (rows) and true (columns). Integer counts when calibrate = FALSE; real-valued calibrated counts otherwise.

References

Northcutt, C., Jiang, L., & Chuang, I. (2021). Confident learning: Estimating uncertainty in dataset labels. Journal of Artificial Intelligence Research, 70, 1373–1411. doi:10.1613/jair.1.12125

See Also

estimate_joint(), noise_matrices(), num_label_issues()

Examples

sim <- simulate_label_noise(n = 500, seed = 1)
confident_joint(sim, truth = given, calibrate = FALSE)
confident_joint(sim, truth = given)

Estimate the joint distribution of given and true labels

Description

Normalises the calibrated confident joint so that it sums to one (Northcutt et al., 2021, Eq. 3 and Algorithm 2). Entry ⁠[i, j]⁠ estimates the proportion of examples that have given label i and true label j.

Usage

estimate_joint(x, ...)

Arguments

x

Labels or an object holding labels and predicted probabilities. See Description.

...

Passed to label_inputs(): for example pred_probs when x is a label vector, or truth when x is a data frame.

Value

A square matrix with dimension names given and true that sums to one. Its row sums equal the observed class proportions.

References

Northcutt, C., Jiang, L., & Chuang, I. (2021). Confident learning: Estimating uncertainty in dataset labels. Journal of Artificial Intelligence Research, 70, 1373–1411. doi:10.1613/jair.1.12125

Examples

sim <- simulate_label_noise(n = 500, seed = 1)
round(estimate_joint(sim, truth = given), 3)

Find examples with likely label errors

Description

Flags examples whose given label is likely wrong, using one of the rank and prune rules of confident learning (Northcutt et al., 2021, Sec. 3.2). Every rule needs out-of-sample predicted probabilities, for example from cross-validation.

As in the cleanlab Python package, an example whose most likely class is its given label is never flagged, whichever rule is used: the classifier then offers no evidence against the label.

Flagged examples are candidates for review, not proven errors: ambiguous examples that genuinely fit several classes are flagged too.

Usage

find_label_issues(
  x,
  ...,
  filter_by = c("prune_by_noise_rate", "prune_by_class", "both", "confident_learning",
    "predicted_neq_given"),
  rank_by = c("self_confidence", "normalized_margin", "confidence_weighted_entropy"),
  frac_noise = 1,
  min_examples_per_class = 1
)

Arguments

x

Labels or an object holding labels and predicted probabilities. See Description.

...

Passed to label_inputs(): for example pred_probs when x is a label vector, or truth when x is a data frame.

filter_by

Rule used to flag examples, see Description.

rank_by

Label quality score reported in label_quality, see label_quality_scores(). Sort by it to review the most suspicious examples first.

frac_noise

Fraction of the estimated number of label errors to flag, between 0 and 1. Only used by the "prune_by_*" and "both" rules. Lower values flag fewer, more certain examples.

min_examples_per_class

The rules never flag so many examples of a given label that fewer than this number would remain unflagged.

Value

A tibble with one row per example, in the order of the input, and columns

References

Northcutt, C., Jiang, L., & Chuang, I. (2021). Confident learning: Estimating uncertainty in dataset labels. Journal of Artificial Intelligence Research, 70, 1373–1411. doi:10.1613/jair.1.12125

See Also

health_summary() for a class-level overview.

Examples

sim <- simulate_label_noise(n = 500, noise_rate = 0.1, seed = 1)
issues <- find_label_issues(sim, truth = given)
issues

# Review the most suspicious examples first
flagged <- issues[issues$is_label_issue, ]
head(flagged[order(flagged$label_quality), ])

# How well did it do on this simulation?
table(flagged = issues$is_label_issue, mislabelled = sim$given != sim$true)

Summarise label health by class

Description

Gives a dataset-level and class-level overview of label quality from the estimated joint distribution of given and true labels (see noise_matrices()):

Usage

health_summary(x, ..., method = c("confident_joint", "calibrated"))

Arguments

x

Labels or an object holding labels and predicted probabilities. See Description.

...

Passed to label_inputs(): for example pred_probs when x is a label vector, or truth when x is a data frame.

method

Estimator of the number of label errors, see num_label_issues().

Value

An object of class label_health, a list with

References

Northcutt, C., Jiang, L., & Chuang, I. (2021). Confident learning: Estimating uncertainty in dataset labels. Journal of Artificial Intelligence Research, 70, 1373–1411. doi:10.1613/jair.1.12125

Examples

sim <- simulate_label_noise(n = 1000, noise_rate = 0.15, seed = 1)
health <- health_summary(sim, truth = given)
health
health$classes

Standardise labels and predicted probabilities

Description

label_inputs() converts the many ways of supplying given labels and out-of-sample predicted probabilities into one validated object. Every other function in labelnoise calls it, so anything accepted here is accepted everywhere:

Predicted probabilities must be out-of-sample (for example from cross-validation). In-sample probabilities from a model that has seen the labels will hide most label errors.

When an example has several out-of-sample predictions (repeated cross-validation), its probabilities are averaged.

Other packages can add methods for their own prediction objects. A method should end by calling label_inputs() on a label vector and a probability matrix.

Usage

label_inputs(x, ...)

## S3 method for class 'labelnoise_inputs'
label_inputs(x, ...)

## Default S3 method:
label_inputs(x, pred_probs, ..., row_id = NULL)

## S3 method for class 'data.frame'
label_inputs(x, truth, ..., pred_probs = NULL)

## S3 method for class 'tune_results'
label_inputs(x, ..., parameters = NULL)

## S3 method for class 'PredictionClassif'
label_inputs(x, ...)

## S3 method for class 'ResampleResult'
label_inputs(x, ...)

## S3 method for class 'train'
label_inputs(x, ...)

Arguments

x

Labels or an object holding labels and predicted probabilities. See Description.

...

Passed on to methods. For data frames, a tidyselect specification of the probability columns.

pred_probs

A numeric matrix or data frame with one row per example and one column per class. Rows must sum to one. Columns are matched to labels by name when both have names, otherwise by position.

row_id

Integer identifiers returned in the .row column of find_label_issues(). Defaults to seq_along(x).

truth

For data frames, the column holding the given labels.

parameters

For tune_results with several candidate models, a one-row data frame of tuning parameters, such as the output of tune::select_best().

Value

An object of class labelnoise_inputs: a list with labels (factor), pred_probs (numeric matrix with one column per level of labels) and row_id (integer).

Examples

labels <- factor(c("a", "b", "b", "a"))
probs <- matrix(
  c(0.9, 0.1,
    0.2, 0.8,
    0.7, 0.3,
    0.6, 0.4),
  ncol = 2, byrow = TRUE, dimnames = list(NULL, c("a", "b"))
)
label_inputs(labels, probs)

# The yardstick convention
preds <- data.frame(class = labels, .pred_a = probs[, 1], .pred_b = probs[, 2])
label_inputs(preds, truth = class)

Label quality scores

Description

Scores how likely each given label is to be correct, from 0 (probably wrong) to 1 (probably right). Scores depend only on the predicted probabilities p of an example and its given label y (Kuan and Mueller, 2022):

With adjust = TRUE, each class threshold t (see class_thresholds()) is subtracted from the predicted probabilities before scoring. This corrects for a classifier that systematically favours some classes. The adjusted probabilities are (p - t + max(t)) / sum(p - t + max(t)), which are non-negative and sum to one.

Usage

label_quality_scores(
  x,
  ...,
  method = c("self_confidence", "normalized_margin", "confidence_weighted_entropy"),
  adjust = FALSE
)

Arguments

x

Labels or an object holding labels and predicted probabilities. See Description.

...

Passed to label_inputs(): for example pred_probs when x is a label vector, or truth when x is a data frame.

method

Scoring method, see Description.

adjust

Adjust predicted probabilities by the class thresholds before scoring? Not available for "confidence_weighted_entropy".

Value

A numeric vector with one score per example, in the order of label_inputs(x, ...)$row_id.

References

Kuan, J., & Mueller, J. (2022). Model-agnostic label quality scoring to detect real-world label errors. ICML DataPerf Workshop. doi:10.5281/zenodo.18168246

Examples

sim <- simulate_label_noise(n = 300, seed = 1)
scores <- label_quality_scores(sim, truth = given)
# Mislabelled examples get lower scores
tapply(scores, sim$given != sim$true, mean)

Noise transition matrices and class priors

Description

Derives from the estimated joint (see estimate_joint()) the quantities used to characterise label noise (Northcutt et al., 2021, Sec. 3.1). Both matrices are oriented with given labels in rows and true labels in columns.

Usage

noise_matrices(x, ...)

Arguments

x

Labels or an object holding labels and predicted probabilities. See Description.

...

Passed to label_inputs(): for example pred_probs when x is a label vector, or truth when x is a data frame.

Value

A list with

A class with an estimated true prior of zero has NA in its column of noise_matrix.

References

Northcutt, C., Jiang, L., & Chuang, I. (2021). Confident learning: Estimating uncertainty in dataset labels. Journal of Artificial Intelligence Research, 70, 1373–1411. doi:10.1613/jair.1.12125

Examples

sim <- simulate_label_noise(n = 500, seed = 1)
nm <- noise_matrices(sim, truth = given)
round(nm$inverse_noise_matrix, 2)

Estimate the number of label errors

Description

Two estimators are available:

Usage

num_label_issues(x, ..., method = c("confident_joint", "calibrated"))

Arguments

x

Labels or an object holding labels and predicted probabilities. See Description.

...

Passed to label_inputs(): for example pred_probs when x is a label vector, or truth when x is a data frame.

method

Estimator, see Description.

Value

A single integer.

References

Northcutt, C., Jiang, L., & Chuang, I. (2021). Confident learning: Estimating uncertainty in dataset labels. Journal of Artificial Intelligence Research, 70, 1373–1411. doi:10.1613/jair.1.12125

Examples

sim <- simulate_label_noise(n = 500, noise_rate = 0.2, seed = 1)
num_label_issues(sim, truth = given)
sum(sim$given != sim$true)

Simulate a classification dataset with label errors

Description

Generates true classes, given labels in which a share of examples have been switched to another class at random, and predicted probabilities from a softmax of noisy logits that favour the true class. Useful for examples, teaching and checking how well the methods recover known errors.

Usage

simulate_label_noise(
  n = 1000,
  n_classes = 4,
  noise_rate = 0.1,
  signal = 2,
  prior = NULL,
  seed = NULL
)

Arguments

n

Number of examples.

n_classes

Number of classes, at least two.

noise_rate

Probability that an example's given label is switched to a different, uniformly chosen class.

signal

How much the logit of the true class is raised. Larger values give a more accurate classifier.

prior

Class probabilities of the true classes. Defaults to a moderately imbalanced distribution.

seed

Optional random seed. The global random number generator is restored afterwards.

Value

A tibble in the yardstick convention with columns true, given (factors) and one ⁠.pred_<class>⁠ probability column per class.

Examples

sim <- simulate_label_noise(n = 10, seed = 42)
sim