Scipy 曲线拟合(优化)- 使用自定义函数矢量化条件以识别阈值
Scipy curve fit (optimization) - vectorizing a conditional to identify threshold using a custom function
我正在尝试使用 scipy curve_fit
来捕获 a0
参数的值。截至目前,它没有变化(始终显示为 1):
X = [[1,2,3],[4,5,6]]
def func(X, a0, c):
x1 = X[0]; x2 = X[1]
a = x1*x2
result = np.where(a(a<a0), -c*(a + np.sqrt(x2)), -c*x1)
return result
Popt, Cov = scipy.curve_fit(func, X, y)
a0, c = Popt
Predicted = func(X, a0, c) # a0 and c are constants
我得到了 c 的值,它是一个标量,没有任何问题。我无法解释为什么 a0
(也是标量)始终为 1,而且我不确定如何修复它。我确实在 SO 上看到 elsewhere 可以像我在这里使用的那样使用 np.where
,但显然不适用于 curve_fit 函数。也许我需要使用不同的优化方法,我想要一些使用 scipy 方法来做到这一点的指示。
编辑:我尝试了 Brad 建议的构造,但不是这样。
已更新!
这应该有效。请注意,a
变量在此示例中是长度为 3 的向量,因为它是通过 X
(2x3 矩阵)的第一个和第二个元素的逐元素乘法计算得出的。因此 a0
可以是标量或长度为 3 的向量,c
也可以是标量或长度为 3 的向量。
import numpy as np
X = np.array([[1, 2, 3], [4, 5, 6]])
a0 = np.array([8,25,400])
# a0 = 2
# Code works whether C is scalar or a matrix since it can be broadcast to matrix a below.
# c = 3 # Uncomment this for scalar
c = np.array([8, 12, 2000]) # Element wise
def func(X, a0, c):
x = X[0]
y = X[1]
a = x * y
print(a.shape)
result = np.where(a < a0, c * (a + np.sqrt(y)), c * x)
return result
func(X, a0, c)
这是最低限度的有效代码。请注意,我删除了 y>0
并将 a
定义为与 c
相同的大小。现在您得到了正确的插入,因为 np.where
的第一个参数现在与第二个和第三个参数的大小相同。在 (x<a) & (y>0)
之前总是评估为 True
或 False
并且在这种情况下这是一个标量。如果 a
是一个 N 维数组,你会收到一个 ValueError
因为操作数不能一起广播
import numpy as np
c = np.array([[22,34],[33,480]])
def func(X, a):
x = X[0]; y = X[1]
return np.where(c[(x<a)], -c*(a + np.sqrt(y)), -c*x)
X = [25, 600]
a = np.array([[2,14],[33,22]])
func(X,a)
如果 c
是常量并且 a
是您想要操作的数组,这也适用
import numpy as np
c = 2
def func(X, a):
x = X[0]; y = X[1]
return np.where(a[(x<a)], -c*(a + np.sqrt(y)), -c*x)
X = [25, 600]
a = np.array([[2,14],[33,22]])
func(X,a)
我正在尝试使用 scipy curve_fit
来捕获 a0
参数的值。截至目前,它没有变化(始终显示为 1):
X = [[1,2,3],[4,5,6]]
def func(X, a0, c):
x1 = X[0]; x2 = X[1]
a = x1*x2
result = np.where(a(a<a0), -c*(a + np.sqrt(x2)), -c*x1)
return result
Popt, Cov = scipy.curve_fit(func, X, y)
a0, c = Popt
Predicted = func(X, a0, c) # a0 and c are constants
我得到了 c 的值,它是一个标量,没有任何问题。我无法解释为什么 a0
(也是标量)始终为 1,而且我不确定如何修复它。我确实在 SO 上看到 elsewhere 可以像我在这里使用的那样使用 np.where
,但显然不适用于 curve_fit 函数。也许我需要使用不同的优化方法,我想要一些使用 scipy 方法来做到这一点的指示。
编辑:我尝试了 Brad 建议的构造,但不是这样。
已更新!
这应该有效。请注意,a
变量在此示例中是长度为 3 的向量,因为它是通过 X
(2x3 矩阵)的第一个和第二个元素的逐元素乘法计算得出的。因此 a0
可以是标量或长度为 3 的向量,c
也可以是标量或长度为 3 的向量。
import numpy as np
X = np.array([[1, 2, 3], [4, 5, 6]])
a0 = np.array([8,25,400])
# a0 = 2
# Code works whether C is scalar or a matrix since it can be broadcast to matrix a below.
# c = 3 # Uncomment this for scalar
c = np.array([8, 12, 2000]) # Element wise
def func(X, a0, c):
x = X[0]
y = X[1]
a = x * y
print(a.shape)
result = np.where(a < a0, c * (a + np.sqrt(y)), c * x)
return result
func(X, a0, c)
这是最低限度的有效代码。请注意,我删除了 y>0
并将 a
定义为与 c
相同的大小。现在您得到了正确的插入,因为 np.where
的第一个参数现在与第二个和第三个参数的大小相同。在 (x<a) & (y>0)
之前总是评估为 True
或 False
并且在这种情况下这是一个标量。如果 a
是一个 N 维数组,你会收到一个 ValueError
因为操作数不能一起广播
import numpy as np
c = np.array([[22,34],[33,480]])
def func(X, a):
x = X[0]; y = X[1]
return np.where(c[(x<a)], -c*(a + np.sqrt(y)), -c*x)
X = [25, 600]
a = np.array([[2,14],[33,22]])
func(X,a)
如果 c
是常量并且 a
是您想要操作的数组,这也适用
import numpy as np
c = 2
def func(X, a):
x = X[0]; y = X[1]
return np.where(a[(x<a)], -c*(a + np.sqrt(y)), -c*x)
X = [25, 600]
a = np.array([[2,14],[33,22]])
func(X,a)