最小二乘函数和 4 参数物流函数不起作用
Least squares function and 4 parameter logistics function not working
python 相对较新,主要用于绘图。我目前正在尝试使用 4 参数逻辑 (4PL) 方程和来自 scipy 的曲线拟合来确定最佳拟合线。有一个或两个网站展示了 4PL 的工作原理,但无法让它们为我的数据工作。示例,但类似于以下 4PL 数据:
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import scipy.optimize as optimization
xdata = [2.3, 2.3, 2, 2, 1.7, 1.7, 1, 1, 0.000001, 0.000001, -1, -1]
ydata = [0.32, 0.3, 0.55, 0.60, 0.88, 0.92, 1.27, 1.21, 1.15, 1.12, 1.1, 1.1]
def fourPL(x, A, B, C, D):
return ((A-D)/(1.0+((x/C)**(B))) + D)
guess = [0, -0.5, 0.5, 1]
params, params_covariance = optimization.curve_fit(fourPL, xdata, ydata,
guess)
params
给出警告(也是测试数据中的指数警告,但不是真实的):
OptimizeWarning: Covariance of the parameters could not be estimated
category=OptimizeWarning)
和参数 returns 我最初的猜测。我尝试了各种初步猜测。
最佳拟合线是在绘图时绘制的,但不是曲线并且不会低于 x = 0(我找不到负片会扰乱 4PL 模型的原因)。
4PL fit plotted
我不确定我是不是对方程做错了什么,或者曲线拟合函数是如何工作的,或者两者都有。我有一个类似的问题,使用最小二乘法而不是曲线拟合。我已经尝试了一系列基于类似方程式的变体来拟合等,但已经被困了一段时间,如果能帮助我指出正确的方向,我将不胜感激。
我很惊讶你没有收到任何警告或没有与我们分享。我无法用科学的方法为你分析这个任务,只是一些技术性的东西:
观察
当 运行 你的代码时,你应该有一些警告,比如:
RuntimeWarning: invalid value encountered in power
return ((A-D)/(1.0+((x/C)**(B))) + D)
不要忽略这个!
调试
向您的函数添加一些打印 fourPL
,可能是您函数的所有不同组件,然后看看发生了什么。
示例:
def fourPL(x, A, B, C, D):
print('1: ', (A-D))
print('2: ', (x/C))
print('3: ', (1.0+((x/C)**(B))))
return ((A-D)/(1.0+((x/C)**(B))) + D)
...
params, params_covariance = optimization.curve_fit(fourPL, xdata, ydata, guess, maxfev=1)
# maxfev=1 -> let's just check 1 or few it's
输出:
1: -1.0
2: [ 4.60000000e+00 4.60000000e+00 4.00000000e+00 4.00000000e+00
3.40000000e+00 3.40000000e+00 2.00000000e+00 2.00000000e+00
2.00000000e-06 2.00000000e-06 -2.00000000e+00 -2.00000000e+00]
RuntimeWarning: invalid value encountered in power
print('3: ', (1.0+((x/C)**(B))))
3: [ 1.4662524 1.4662524 1.5 1.5 1.54232614
1.54232614 1.70710678 1.70710678 708.10678119 708.10678119
nan nan]
这就足够了。 nans 和 infs 不好!
理论
现在是理论时间,我不会那样做。但是通常你现在应该考虑一下基础理论以及为什么会出现这些问题。
关于这些假设,您是否遗漏了什么?
修复(不检查理论)
没有检查理论,只是查看了一些 example 在 30 秒内发现:嗯是负面的 x-values 有问题吗?
让我们移动 x(最小值;此处硬编码为 1):
xdata = np.array([2.3, 2.3, 2, 2, 1.7, 1.7, 1, 1, 0.000001, 0.000001, -1, -1]) + 1
完整代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import scipy.optimize as optimization
xdata = np.array([2.3, 2.3, 2, 2, 1.7, 1.7, 1, 1, 0.000001, 0.000001, -1, -1]) + 1
ydata = np.array([0.32, 0.3, 0.55, 0.60, 0.88, 0.92, 1.27, 1.21, 1.15, 1.12, 1.1, 1.1])
def fourPL(x, A, B, C, D):
return ((A-D)/(1.0+((x/C)**(B))) + D)
guess = [0, -0.5, 0.5, 1]
params, params_covariance = optimization.curve_fit(fourPL, xdata, ydata, guess)#, maxfev=1)
x_min, x_max = np.amin(xdata), np.amax(xdata)
xs = np.linspace(x_min, x_max, 1000)
plt.scatter(xdata, ydata)
plt.plot(xs, fourPL(xs, *params))
plt.show()
输出:
RuntimeWarning: divide by zero encountered in power
return ((A-D)/(1.0+((x/C)**(B))) + D)
看起来不错,但现在是另一种理论的时候了session:我们的linear-shift对我们的结果做了什么?我又忽略了这个。
所以只有一个警告和一个 nice-looking 输出。
如果您想删除最后一个警告,请添加一些小的 epsilon 以在 xdata 中不包含 0:
xdata = np.array([2.3, 2.3, 2, 2, 1.7, 1.7, 1, 1, 0.000001, 0.000001, -1, -1]) + 1 + 1e-10
这将实现相同的效果,没有任何警告。
python 相对较新,主要用于绘图。我目前正在尝试使用 4 参数逻辑 (4PL) 方程和来自 scipy 的曲线拟合来确定最佳拟合线。有一个或两个网站展示了 4PL 的工作原理,但无法让它们为我的数据工作。示例,但类似于以下 4PL 数据:
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import scipy.optimize as optimization
xdata = [2.3, 2.3, 2, 2, 1.7, 1.7, 1, 1, 0.000001, 0.000001, -1, -1]
ydata = [0.32, 0.3, 0.55, 0.60, 0.88, 0.92, 1.27, 1.21, 1.15, 1.12, 1.1, 1.1]
def fourPL(x, A, B, C, D):
return ((A-D)/(1.0+((x/C)**(B))) + D)
guess = [0, -0.5, 0.5, 1]
params, params_covariance = optimization.curve_fit(fourPL, xdata, ydata,
guess)
params
给出警告(也是测试数据中的指数警告,但不是真实的):
OptimizeWarning: Covariance of the parameters could not be estimated
category=OptimizeWarning)
和参数 returns 我最初的猜测。我尝试了各种初步猜测。
最佳拟合线是在绘图时绘制的,但不是曲线并且不会低于 x = 0(我找不到负片会扰乱 4PL 模型的原因)。 4PL fit plotted
我不确定我是不是对方程做错了什么,或者曲线拟合函数是如何工作的,或者两者都有。我有一个类似的问题,使用最小二乘法而不是曲线拟合。我已经尝试了一系列基于类似方程式的变体来拟合等,但已经被困了一段时间,如果能帮助我指出正确的方向,我将不胜感激。
我很惊讶你没有收到任何警告或没有与我们分享。我无法用科学的方法为你分析这个任务,只是一些技术性的东西:
观察
当 运行 你的代码时,你应该有一些警告,比如:
RuntimeWarning: invalid value encountered in power
return ((A-D)/(1.0+((x/C)**(B))) + D)
不要忽略这个!
调试
向您的函数添加一些打印 fourPL
,可能是您函数的所有不同组件,然后看看发生了什么。
示例:
def fourPL(x, A, B, C, D):
print('1: ', (A-D))
print('2: ', (x/C))
print('3: ', (1.0+((x/C)**(B))))
return ((A-D)/(1.0+((x/C)**(B))) + D)
...
params, params_covariance = optimization.curve_fit(fourPL, xdata, ydata, guess, maxfev=1)
# maxfev=1 -> let's just check 1 or few it's
输出:
1: -1.0
2: [ 4.60000000e+00 4.60000000e+00 4.00000000e+00 4.00000000e+00
3.40000000e+00 3.40000000e+00 2.00000000e+00 2.00000000e+00
2.00000000e-06 2.00000000e-06 -2.00000000e+00 -2.00000000e+00]
RuntimeWarning: invalid value encountered in power
print('3: ', (1.0+((x/C)**(B))))
3: [ 1.4662524 1.4662524 1.5 1.5 1.54232614
1.54232614 1.70710678 1.70710678 708.10678119 708.10678119
nan nan]
这就足够了。 nans 和 infs 不好!
理论
现在是理论时间,我不会那样做。但是通常你现在应该考虑一下基础理论以及为什么会出现这些问题。
关于这些假设,您是否遗漏了什么?
修复(不检查理论)
没有检查理论,只是查看了一些 example 在 30 秒内发现:嗯是负面的 x-values 有问题吗?
让我们移动 x(最小值;此处硬编码为 1):
xdata = np.array([2.3, 2.3, 2, 2, 1.7, 1.7, 1, 1, 0.000001, 0.000001, -1, -1]) + 1
完整代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import scipy.optimize as optimization
xdata = np.array([2.3, 2.3, 2, 2, 1.7, 1.7, 1, 1, 0.000001, 0.000001, -1, -1]) + 1
ydata = np.array([0.32, 0.3, 0.55, 0.60, 0.88, 0.92, 1.27, 1.21, 1.15, 1.12, 1.1, 1.1])
def fourPL(x, A, B, C, D):
return ((A-D)/(1.0+((x/C)**(B))) + D)
guess = [0, -0.5, 0.5, 1]
params, params_covariance = optimization.curve_fit(fourPL, xdata, ydata, guess)#, maxfev=1)
x_min, x_max = np.amin(xdata), np.amax(xdata)
xs = np.linspace(x_min, x_max, 1000)
plt.scatter(xdata, ydata)
plt.plot(xs, fourPL(xs, *params))
plt.show()
输出:
RuntimeWarning: divide by zero encountered in power
return ((A-D)/(1.0+((x/C)**(B))) + D)
看起来不错,但现在是另一种理论的时候了session:我们的linear-shift对我们的结果做了什么?我又忽略了这个。
所以只有一个警告和一个 nice-looking 输出。
如果您想删除最后一个警告,请添加一些小的 epsilon 以在 xdata 中不包含 0:
xdata = np.array([2.3, 2.3, 2, 2, 1.7, 1.7, 1, 1, 0.000001, 0.000001, -1, -1]) + 1 + 1e-10
这将实现相同的效果,没有任何警告。