bundles / scipy latest / scipy / optimize / _isotonic / isotonic_regression
function
scipy.optimize._isotonic:isotonic_regression
source: /scipy/optimize/_isotonic.py :15
Signature
def isotonic_regression ( y : npt.ArrayLike , * , weights : npt.ArrayLike | None = None , increasing : bool = True ) → OptimizeResult Summary
Nonparametric isotonic regression.
Extended Summary
A (not strictly) monotonically increasing array x with the same length as y is calculated by the pool adjacent violators algorithm (PAVA), see [1]. See the Notes section for more details.
Parameters
y: (N,) array_likeResponse variable.
weights: (N,) array_like or NoneCase weights.
increasing: boolIf True, fit monotonic increasing, i.e. isotonic, regression. If False, fit a monotonic decreasing, i.e. antitonic, regression. Default is True.
Returns
res: OptimizeResultThe optimization result represented as a
OptimizeResultobject. Important attributes are:x: The isotonic regression solution, i.e. an increasing (or decreasing) array of the same length than y, with elements in the range from min(y) to max(y).weightsArray with the sum of case weights for each block (or pool) B.blocks: Array of length B+1 with the indices of the start positions of each block (or pool) B. The j-th block is given byx[blocks[j]:blocks[j+1]]for which all values are the same.
Notes
Given data and case weights , the isotonic regression solves the following optimization problem:
For every input value , it generates a value such that is increasing (but not strictly), i.e. . This is accomplished by the PAVA. The solution consists of pools or blocks, i.e. neighboring elements of , e.g. and , that all have the same value.
Most interestingly, the solution stays the same if the squared loss is replaced by the wide class of Bregman functions which are the unique class of strictly consistent scoring functions for the mean, see [2] and references therein.
The implemented version of PAVA according to [1] has a computational complexity of O(N) with input size N.
Examples
This example demonstrates that ``isotonic_regression`` really solves a constrained optimization problem.import numpy as np from scipy.optimize import isotonic_regression, minimize y = [1.5, 1.0, 4.0, 6.0, 5.7, 5.0, 7.8, 9.0, 7.5, 9.5, 9.0] def objective(yhat, y): return np.sum((yhat - y)**2) def constraint(yhat, y): # This is for a monotonically increasing regression. return np.diff(yhat) result = minimize(objective, x0=y, args=(y,), constraints=[{'type': 'ineq', 'fun': lambda x: constraint(x, y)}])✓
result.x
✗result = isotonic_regression(y)
✓result.x
✗Aliases
-
scipy.optimize.isotonic_regression