使用参数作为 scipy.optimize.curve_fit 的界限
Using parameters as bounds for scipy.optimize.curve_fit
我想知道是否可以为 curve_fit()
中的参数设置界限,使界限依赖于另一个参数。例如,假设我想将直线的斜率设置为大于截距。
def linear(x, m, b):
return lambda x: (m*x) + b
def plot_linear(x, y):
B = ([b, -np.inf], [np.inf, np.inf])
p, v = curve_fit(linear, x, y, bounds = B)
xs = np.linspace(min(x), max(x), 1000)
plt.plot(x,y,'.')
plt.plot(xs, linear(xs, *p), '-')
我知道这行不通,因为参数 b 在边界内调用之前没有定义,但我不确定是否有办法使它工作?
我们总是可以重新参数化 w.r.t。具体的曲线拟合问题。例如,如果您想拟合 y=mx+b s.t。 m >= b,可以改写成m=b+k*k,加上另一个参数k 并且我们现在可以使用参数 b, k 进行优化,如下所示:
def linear(x, m, b):
return m*x + b
def linear2(x, k, b): # constrained fit, m = b + k**2 >= b
return (b+k**2)*x + b
def plot_linear(x, y):
p, v = curve_fit(linear, x, y)
print(p)
# [3.1675609 6.01025041]
p2, v2 = curve_fit(linear2, x, y)
print(p2)
# [2.13980283e-05 4.99368661e+00]
xs = np.linspace(min(x), max(x), 1000)
plt.plot(x,y,'.')
plt.plot(xs, linear(xs, *p), 'r-', label='unconstrained fit')
plt.plot(xs, linear2(xs, *p2), 'b-', label='constrained (m>b) fit')
plt.legend()
现在让我们使用约束和无约束拟合函数拟合以下数据的曲线(注意无约束最优拟合的斜率小于截距)
x = np.linspace(0,1,100)
y = 3*x + 5 + 2*np.random.rand(len(x))
plot_linear(x, y)
我想知道是否可以为 curve_fit()
中的参数设置界限,使界限依赖于另一个参数。例如,假设我想将直线的斜率设置为大于截距。
def linear(x, m, b):
return lambda x: (m*x) + b
def plot_linear(x, y):
B = ([b, -np.inf], [np.inf, np.inf])
p, v = curve_fit(linear, x, y, bounds = B)
xs = np.linspace(min(x), max(x), 1000)
plt.plot(x,y,'.')
plt.plot(xs, linear(xs, *p), '-')
我知道这行不通,因为参数 b 在边界内调用之前没有定义,但我不确定是否有办法使它工作?
我们总是可以重新参数化 w.r.t。具体的曲线拟合问题。例如,如果您想拟合 y=mx+b s.t。 m >= b,可以改写成m=b+k*k,加上另一个参数k 并且我们现在可以使用参数 b, k 进行优化,如下所示:
def linear(x, m, b):
return m*x + b
def linear2(x, k, b): # constrained fit, m = b + k**2 >= b
return (b+k**2)*x + b
def plot_linear(x, y):
p, v = curve_fit(linear, x, y)
print(p)
# [3.1675609 6.01025041]
p2, v2 = curve_fit(linear2, x, y)
print(p2)
# [2.13980283e-05 4.99368661e+00]
xs = np.linspace(min(x), max(x), 1000)
plt.plot(x,y,'.')
plt.plot(xs, linear(xs, *p), 'r-', label='unconstrained fit')
plt.plot(xs, linear2(xs, *p2), 'b-', label='constrained (m>b) fit')
plt.legend()
现在让我们使用约束和无约束拟合函数拟合以下数据的曲线(注意无约束最优拟合的斜率小于截距)
x = np.linspace(0,1,100)
y = 3*x + 5 + 2*np.random.rand(len(x))
plot_linear(x, y)