Optimization 使用scipy.optimize Curve\u fit在Python中进行曲线拟合

Optimization 使用scipy.optimize Curve\u fit在Python中进行曲线拟合,optimization,scipy,curve-fitting,Optimization,Scipy,Curve Fitting,作为Python的相对初学者,我正在努力理解(并因此使用)scipy.optimize中的“曲线拟合” 我尝试了以下对前面问题的回答: 但不幸的是,我没能成功 这是一个工程问题(处理来自试验台的测量数据),因此我知道公式的格式是Y=(X/a)+(X/B)^(1/C),其中a、B、C是需要找到的常数 [现行守则] import numpy as np from scipy.optimize import curve_fit valY_list = [yyy1,yyy2,yyy3,yyy4] va

作为Python的相对初学者,我正在努力理解(并因此使用)scipy.optimize中的“曲线拟合”

我尝试了以下对前面问题的回答: 但不幸的是,我没能成功

这是一个工程问题(处理来自试验台的测量数据),因此我知道公式的格式是Y=(X/a)+(X/B)^(1/C),其中a、B、C是需要找到的常数

[现行守则]

import numpy as np
from scipy.optimize import curve_fit

valY_list = [yyy1,yyy2,yyy3,yyy4]
valX_list = [xxx1,xxx2,xxx3,xxx4]

val_Y = np.array(valY_list)
val_X = np.array(valX_list)

def fit_func(val_X,A,B,C):
    return (val_X/A)+((val_X/B)^(1/C))

params = curve_fit(fit_func, val_X, val_Y)

[A,B,C] = params[0]
NB1:实际上,valY_列表和valX_列表的长度大于500个条目(存储为浮动)

NB2:我也知道A、B、C的值应该在一定的值范围内,所以我想在执行优化时约束解决方案

0.005 0.0 0.0001 我意识到我的代码可能相当初级,可能遗漏了很多东西(或者对于一个有经验的程序员来说明显的错误!),所以我向您道歉。任何帮助都将不胜感激

您可能会发现lmfit()对于此问题和其他曲线拟合问题非常有用。它为曲线拟合提供了比
curve\u fit
更高级别的界面,并提供了许多方便和高级的选项,用于建模和使用参数和拟合统计信息

对于lmfit,我建议采用以下方法:

import numpy as np
from scipy.optimize import curve_fit
from lmfit import Model

valY_list = [yyy1,yyy2,yyy3,yyy4]
valX_list = [xxx1,xxx2,xxx3,xxx4]

val_Y = np.array(valY_list)
val_X = np.array(valX_list)

def fit_func(x, a, b, c):
    return (a*x)+(b*x)**c

mymodel = Model(fit_func)

params = mymodel.make_params(a=10, b=1, c=100.0)

params['a'].min = 2.0
params['a'].max = 200.

params['b'].min = 0.002
params['b'].max = 1.e8

params['c'].min = 10.0
params['c'].max = 10000.0

result = mymodel.fit(val_Y, params, x=val_X)

print(result.fit_report())

for par_name, param in result.params.items():
    print(par_name, param.value, param.stderr)
请注意,我稍微更改了模型函数以使用1/PARAM,并相应地调整了边界(我想!)。打印的拟合报告将包括拟合统计数据以及每个变量的最佳拟合值和标准误差。另外,请注意,使用lmfit时,参数是根据fitting函数的参数名称命名的,并且最小/最大边界与参数对象一致。尽管上面的示例设置了边界,但您也可以使用(例如):

而且,如果确实需要A、B和C,可以将这些参数设置为约束表达式:

params.add('A', expr='1/a')
params.add('B', expr='1/b')
params.add('C', expr='1/c')
拟合度不会变化,但会报告其值和标准误差。实际上,可以使用任何使用其他参数名和基本数学函数的有效python表达式


还有更多的功能、体面的文档和示例,但这应该让您开始学习。

您是否尝试过为A、B和C提供预期范围内的功能?你的问题也会从你知道答案的玩具数据集中受益,这样人们就可以用它来测试改进。啊,我明白了
^
是位运算符。您是lmfit的作者吗?或者为什么您的每个答案都以相同的复制粘贴部分开头?我是lmfit的作者之一。关于曲线拟合,我的许多回答都建议使用lmfit,因为它方便地提供了许多被问及的特性。这里的问题包括对参数设置边界。Lmfit提供了一种方便的方法——比curve_fit好得多(IMO),后者需要保留三个保持相同顺序的单独列表。这确实需要更好的数据结构,这就是lmfit参数所提供的。在这种情况下,它是错误的运算符。你应该先回答问题,然后说,“这是另一种使用lmfit的方法”。否则就有自我推销的味道,所以有规则:。不。这不是我的意图。a) 在你的答案中披露你的从属关系,就像其他负责存储库的人一样。b) 在写一篇帖子之前问问自己“lmfit是OP问题的最佳答案吗?”。有时提出不同的方法是一个好主意,有时不是。你可以忽略我的评论,不管怎样,我和你一样是一个非常好的成员。好吧,我对你认为的“从属关系”在这里的含义感到困惑。我的SO档案没有列出我的雇主,但它有我的真实姓氏,可以搜索,特别是这些问题列出的任何主题。你是在建议一个人披露他们对问题或答案中提到的图书馆做出了贡献吗?那对我来说似乎不切实际。我不记得在这里把它看作是一种常见的做法,但也许你可以指出你和/或其他人的答案,以证明你想看到什么。
params.add('A', expr='1/a')
params.add('B', expr='1/b')
params.add('C', expr='1/c')