isotonic_regression#
- scipy.optimize.isotonic_regression(y, *, weights=None, increasing=True)[原始碼]#
非參數等張迴歸。
使用鄰近違反者集值演算法 (PAVA) 計算一個與 y 相同長度的(非嚴格)單調遞增陣列 x,參見 [1]。 更多詳細資訊請參見「註解」章節。
- 參數:
- y(N,) array_like
反應變數。
- weights(N,) array_like 或 None
案例權重。
- increasingbool
若為 True,則擬合單調遞增(即等張)迴歸。 若為 False,則擬合單調遞減(即反張)迴歸。 預設值為 True。
- 回傳值:
- resOptimizeResult
最佳化結果以
OptimizeResult
物件表示。 重要的屬性有x
: 等張迴歸解,即一個與 y 相同長度的遞增(或遞減)陣列,元素值範圍從 min(y) 到 max(y)。weights
: 陣列,包含每個區塊(或群組)B 的案例權重總和。blocks
: 長度為 B+1 的陣列,包含每個區塊(或群組)B 的起始位置索引。 第 j 個區塊由x[blocks[j]:blocks[j+1]]
給出,其中所有值都相同。
註解
給定資料 \(y\) 和案例權重 \(w\),等張迴歸解決以下最佳化問題
\[\operatorname{argmin}_{x_i} \sum_i w_i (y_i - x_i)^2 \quad \text{subject to } x_i \leq x_j \text{ whenever } i \leq j \,.\]對於每個輸入值 \(y_i\),它產生一個值 \(x_i\),使得 \(x\) 是遞增的(但非嚴格遞增),即 \(x_i \leq x_{i+1}\)。 這是通過 PAVA 完成的。 解決方案包含群組或區塊,即 \(x\) 的相鄰元素,例如 \(x_i\) 和 \(x_{i+1}\),它們都具有相同的值。
最有趣的是,如果將平方損失替換為廣泛的 Bregman 函數類別,解決方案保持不變,Bregman 函數類別是均值的唯一嚴格一致評分函數類別,參見 [2] 及其中的參考文獻。
根據 [1] 實作的 PAVA 版本,其計算複雜度為 O(N),其中 N 為輸入大小。
參考文獻
[1] (1,2)Busing, F. M. T. A. (2022). Monotone Regression: A Simple and Fast O(n) PAVA Implementation. Journal of Statistical Software, Code Snippets, 102(1), 1-25. DOI:10.18637/jss.v102.c01
[2]Jordan, A.I., Mühlemann, A. & Ziegel, J.F. Characterizing the optimal solutions to the isotonic regression problem for identifiable functionals. Ann Inst Stat Math 74, 489-514 (2022). DOI:10.1007/s10463-021-00808-0
範例
此範例示範了
isotonic_regression
確實解決了一個受約束的最佳化問題。>>> 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 array([1.25 , 1.25 , 4. , 5.56666667, 5.56666667, 5.56666667, 7.8 , 8.25 , 8.25 , 9.25 , 9.25 ]) >>> result = isotonic_regression(y) >>> result.x array([1.25 , 1.25 , 4. , 5.56666667, 5.56666667, 5.56666667, 7.8 , 8.25 , 8.25 , 9.25 , 9.25 ])
isotonic_regression
相較於呼叫minimize
的最大優勢在於,它更使用者友善,也就是說,使用者不需要定義目標函數和約束函數,而且速度快了好幾個數量級。 在一般硬體上(2023 年),對於長度為 1000 的常態分佈輸入 y,最佳化器大約需要 4 秒,而isotonic_regression
大約需要 200 微秒。