Python 曲线拟合应用于离散数据集问题
我正在尝试使用curve_fit软件包用自定义模型拟合一些(少数)离散的实验值。 问题是我得到了警告(?):“优化警告:参数的协方差无法估计”,当然参数没有可靠的值 我读到这个问题是我的数据集离散性的结果,我可以使用LMFIT包解决它。 根据我发现的一些例子,我应该定义一个线性空间,然后将我的实验值分配给相应的x点。不幸的是,由于我的分数太少,这个过程会引入太多错误。因此,我想知道是否有一种方法可以通过curve_fit软件包克服这个问题。在同一代码中,我使用它来适应指数模型和其他数据(相同数量的元素),没有任何问题 谢谢你的提示 具体而言,将代码简化为基本内容: xa= 阵列([0.5,0.53,0.56,0.59,0.62,0.65,0.68,0.7,0.72,0.74,0.76, 0.78,0.8,0.82],数据类型=对象) 嗯= 阵列([0.40168,0.4010399999995,0.4002799999999997,0.39936,, 0.39828, 0.397, 0.39544, 0.39424000000000003, 0.39292, 0.39144, 0.38976,0.38788,0.38580000000000003,0.38348],数据类型=对象)Python 曲线拟合应用于离散数据集问题,python,numpy,curve-fitting,Python,Numpy,Curve Fitting,我正在尝试使用curve_fit软件包用自定义模型拟合一些(少数)离散的实验值。 问题是我得到了警告(?):“优化警告:参数的协方差无法估计”,当然参数没有可靠的值 我读到这个问题是我的数据集离散性的结果,我可以使用LMFIT包解决它。 根据我发现的一些例子,我应该定义一个线性空间,然后将我的实验值分配给相应的x点。不幸的是,由于我的分数太少,这个过程会引入太多错误。因此,我想知道是否有一种方法可以通过curve_fit软件包克服这个问题。在同一代码中,我使用它来适应指数模型和其他数据(相同数量
fit_模型似乎无法调整数据 我将使fit_模型完美地拟合第一个数据点(0.5,0.40168),并使指数
(1+np.exp((a-x)/b))
随着x的增加而增加(1+np.exp((a+x)/b))
,因此fit_模型随着x的减少而与输入数据相同
from numpy import array
import numpy as np
xa= array([0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 0.7, 0.72, 0.74,
0.76, 0.78, 0.8, 0.82], dtype=object)
ya= array([0.40168, 0.40103999999999995, 0.40027999999999997, 0.39936,
0.39828, 0.397, 0.39544, 0.39424000000000003, 0.39292, 0.39144, 0.38976, 0.38788, 0.38580000000000003, 0.38348], dtype=object)
from scipy.optimize import curve_fit
def fit_model(x, a, b):
return (1 + np.exp((a + xa[0])/b))/(1 + np.exp((a + x)/b)) + (ya[0] - 1)
popt_an, pcov_an = curve_fit(fit_model, xa, ya, maxfev=100000)
我得到的解决方案是:
a = -1.47015573
b = 0.17030011
yp = array([0.40168 , 0.40103595, 0.40026891, 0.39935567, 0.39826869,
0.39697541, 0.3954374 , 0.39425403, 0.39292656, 0.39143789,
0.38976906, 0.38789897, 0.38580429, 0.38345918])
fit_模型似乎无法调整数据 我将使fit_模型完美地拟合第一个数据点(0.5,0.40168),并使指数
(1+np.exp((a-x)/b))
随着x的增加而增加(1+np.exp((a+x)/b))
,因此fit_模型随着x的减少而与输入数据相同
from numpy import array
import numpy as np
xa= array([0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 0.7, 0.72, 0.74,
0.76, 0.78, 0.8, 0.82], dtype=object)
ya= array([0.40168, 0.40103999999999995, 0.40027999999999997, 0.39936,
0.39828, 0.397, 0.39544, 0.39424000000000003, 0.39292, 0.39144, 0.38976, 0.38788, 0.38580000000000003, 0.38348], dtype=object)
from scipy.optimize import curve_fit
def fit_model(x, a, b):
return (1 + np.exp((a + xa[0])/b))/(1 + np.exp((a + x)/b)) + (ya[0] - 1)
popt_an, pcov_an = curve_fit(fit_model, xa, ya, maxfev=100000)
我得到的解决方案是:
a = -1.47015573
b = 0.17030011
yp = array([0.40168 , 0.40103595, 0.40026891, 0.39935567, 0.39826869,
0.39697541, 0.3954374 , 0.39425403, 0.39292656, 0.39143789,
0.38976906, 0.38789897, 0.38580429, 0.38345918])
我不理解在这里使用lmfit的问题。我也不明白“对象数组”在这里的用法。我可能会将您的硬连线非x依赖因子称为其自身变量(例如,“c”),并使用以下方法:
import numpy as np
import matplotlib.pyplot as plt
from lmfit import Model
xa = np.array([0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 0.7, 0.72, 0.74,
0.76, 0.78, 0.8, 0.82])
ya = np.array([0.40168, 0.40103999999999995, 0.40027999999999997, 0.39936,
0.39828, 0.397, 0.39544, 0.39424000000000003, 0.39292,
0.39144, 0.38976, 0.38788, 0.38580000000000003, 0.38348])
def modelfunc(x, a, b, c):
return (1 + c)/(1 + np.exp((a-x)/b))
my_model = Model(modelfunc)
params = my_model.make_params(a=1, b=-0.1, c=-0.5)
result = my_model.fit(ya, params, x=xa)
print(result.fit_report())
plt.plot(xa, ya, label='data')
plt.plot(xa, result.best_fit, label='fit')
plt.legend()
plt.show()
这将打印出一份
[[Model]]
Model(modelfunc)
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 29
# data points = 14
# variables = 3
chi-square = 7.6982e-10
reduced chi-square = 6.9984e-11
Akaike info crit = -324.734898
Bayesian info crit = -322.817726
[[Variables]]
a: 1.29660513 +/- 6.9684e-04 (0.05%) (init = 1)
b: -0.16527738 +/- 2.7098e-04 (0.16%) (init = -0.1)
c: -0.59507868 +/- 1.6502e-05 (0.00%) (init = -0.5)
[[Correlations]] (unreported correlations are < 0.100)
C(a, b) = -0.995
C(b, c) = -0.955
C(a, c) = 0.925
[[Model]]
模型(modelfunc)
[[Fit统计数据]]
#拟合方法=最小二乘法
#函数evals=29
#数据点=14
#变量=3
卡方检验=7.6982e-10
缩减卡方=6.9984e-11
Akaike信息临界值=-324.734898
贝叶斯信息临界值=-322.817726
[[变量]]
a:1.29660513+/-6.9684e-04(0.05%)(初始值=1)
b:-0.16527738+/-2.7098e-04(0.16%)(初始值=-0.1)
c:-0.59507868+/-1.6502e-05(0.00%)(初始值=-0.5)
[[相关性]](未报告的相关性<0.100)
C(a,b)=-0.995
C(b,C)=-0.955
C(a,C)=0.925
然后显示这样一个图:我不理解在这里使用lmfit会产生什么问题。我也不明白“对象数组”在这里的用法。我可能会将您的硬连线非x依赖因子称为其自身变量(例如,“c”),并使用以下方法:
import numpy as np
import matplotlib.pyplot as plt
from lmfit import Model
xa = np.array([0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 0.7, 0.72, 0.74,
0.76, 0.78, 0.8, 0.82])
ya = np.array([0.40168, 0.40103999999999995, 0.40027999999999997, 0.39936,
0.39828, 0.397, 0.39544, 0.39424000000000003, 0.39292,
0.39144, 0.38976, 0.38788, 0.38580000000000003, 0.38348])
def modelfunc(x, a, b, c):
return (1 + c)/(1 + np.exp((a-x)/b))
my_model = Model(modelfunc)
params = my_model.make_params(a=1, b=-0.1, c=-0.5)
result = my_model.fit(ya, params, x=xa)
print(result.fit_report())
plt.plot(xa, ya, label='data')
plt.plot(xa, result.best_fit, label='fit')
plt.legend()
plt.show()
这将打印出一份
[[Model]]
Model(modelfunc)
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 29
# data points = 14
# variables = 3
chi-square = 7.6982e-10
reduced chi-square = 6.9984e-11
Akaike info crit = -324.734898
Bayesian info crit = -322.817726
[[Variables]]
a: 1.29660513 +/- 6.9684e-04 (0.05%) (init = 1)
b: -0.16527738 +/- 2.7098e-04 (0.16%) (init = -0.1)
c: -0.59507868 +/- 1.6502e-05 (0.00%) (init = -0.5)
[[Correlations]] (unreported correlations are < 0.100)
C(a, b) = -0.995
C(b, c) = -0.955
C(a, c) = 0.925
[[Model]]
模型(modelfunc)
[[Fit统计数据]]
#拟合方法=最小二乘法
#函数evals=29
#数据点=14
#变量=3
卡方检验=7.6982e-10
缩减卡方=6.9984e-11
Akaike信息临界值=-324.734898
贝叶斯信息临界值=-322.817726
[[变量]]
a:1.29660513+/-6.9684e-04(0.05%)(初始值=1)
b:-0.16527738+/-2.7098e-04(0.16%)(初始值=-0.1)
c:-0.59507868+/-1.6502e-05(0.00%)(初始值=-0.5)
[[相关性]](未报告的相关性<0.100)
C(a,b)=-0.995
C(b,C)=-0.955
C(a,C)=0.925
然后显示这样的图:是的!这正是我想要的。非常感谢!这正是我想要的。非常感谢。嗯,是的,你是对的,在这种情况下使用对象数组是胡说八道。我现在让它们漂浮起来。非常感谢。我还将lmfit引入到我的代码中,它运行得非常好。我仍然有绘制曲线的问题。为了获得一条平滑的拟合曲线,即使是对于少数(6个点),我想让它相对于一个新的x轴来绘制最佳拟合结果,例如定义为xdata=np.linspace(min(xa)、max(xa)、num=200)。当然,会生成一条错误消息“ValueError:x和y必须具有相同的第一维度,但具有形状(200,)和(6,)”。如何操作?请阅读lmfit文档,使用
lmfit.ModelResult.eval()
评估不同x
值的模型结果。因此xnew=np.linspace(min(xa),max(xa),num=200)
然后ynew=result.eval(x=xnew)
。然后,阅读文档和示例。是的,你是对的,在这种情况下使用对象数组是胡说八道。我现在让它们漂浮起来。非常感谢。我还将lmfit引入到我的代码中,它运行得非常好。我仍然有绘制曲线的问题。为了获得一条平滑的拟合曲线,即使是对于少数(6个点),我想让它相对于一个新的x轴来绘制最佳拟合结果,例如定义为xdata=np.linspace(min(xa)、max(xa)、num=200)。当然,会生成一条错误消息“ValueError:x和y必须具有相同的第一维度,但具有形状(200,)和(6,)”。如何操作?请阅读lmfit文档,使用lmfit.ModelResult.eval()
评估不同x
值的模型结果。因此xnew=np.linspace(min(xa),max(xa),num=200)
然后ynew=result.eval(x=xnew)
。然后,阅读文档和示例。