我正在尝试利用scipy.least_squares库来解决大型的,稀疏的,非线性的问题。到目前为止,太好了!
但是,我碰到的一个缺点(到目前为止还无法解决)是利用加权矩阵进行观测和/或残差向量。注意:我知道可以设置参数范围,但这不是我要完成的工作。
此示例来自上一个堆栈溢出问题,但答案涉及scipy.optimize,而不是scipy.optimize.least_squares。尽管这个特定示例有些琐碎,但我尝试解决的问题可能涉及数十万个观察值和数万个参数。因此,为什么必须使用minimum_squares。
在这种情况下,我想利用原始拟合残差中的权重,并尝试使用权重通过最小二乘法进行重新拟合。权重应为残差的倒数(或残差的倒数乘以比例因子)。
import numpy as np
from scipy.optimize import least_squares
ydata = [9.7372923, 10.0587245, 10.3838510, 10.6931371, 10.9616260, 11.1833220, 11.3806770, 11.5248917, 11.7353000]
xdata = np.array([j+5 for j in range(len(ydata))])
def get_weights(resid):
"""
This function calculates the weights per (x,y) by using the inverse of the squared residuals divided by the total sum of the inverse of the squared residuals.
This might be incorrect but should work for the sake of example.
"""
total = sum([abs(resid[i]) for i in range(len(resid))])
fract = np.array([resid[i]/total for i in range(len(resid))])
return fract
def get_least_squares_fit(xs, ys):
"""
This function finds alpha (1/slope) and the y-intercept in the equation
of a line y = x / alpha + intercept = mx + b
"""
## SPECIFY INITIAL GUESS OF OPTIMIZED PARAMETERS
params_guess = [1/3, 9] ## ps = [alpha, intercept]
## DEFINE FITTING FUNCTIONS
fit_func = lambda ps,x : x/ps[0] + ps[1]
err_func = lambda ps,x,y : fit_func(ps,x) - y
## GET OPTIMIZED PARAMETERS, RESIDUALS & WEIGHTS
res = least_squares(err_func, params_guess, args=(xs, ys))
alpha, intercept, residuals = res.x[0], res.x[1], res.fun
weights = get_weights(residuals)
return alpha, intercept, residuals, weights
alpha, intercept, residuals, weights = get_least_squares_fit(xdata, ydata)
print(alpha, intercept)
>> 4.03378447722 8.6198247828
print(residuals)
>> [ 0.12206326 0.04853721 -0.02868313 -0.09006308 -0.11064582 -0.08443567
-0.03388451 0.06980694 0.1073048 ]