如何在python中使用scipy.optimize中的leastsq函数将直线和二次线拟合到数据集x和y

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19791581/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 14:38:38  来源:igfitidea点击:

How to use leastsq function from scipy.optimize in python to fit both a straight line and a quadratic line to data sets x and y

pythonnumpyscipyleast-squares

提问by user2956673

How would i fit a straight line and a quadratic to the data set below using the leastsq function from scipy.optimize? I know how to use polyfit to do it. But i need to use leastsq function.

我将如何使用 scipy.optimize 中的 leastsq 函数将直线和二次方拟合到下面的数据集?我知道如何使用 polyfit 来做到这一点。但我需要使用 leastsq 函数。

Here are the x and y data sets:

这是 x 和 y 数据集:

x: 1.0,2.5,3.5,4.0,1.1,1.8,2.2,3.7

y: 6.008,15.722,27.130,33.772,5.257,9.549,11.098,28.828

Can someone help me out please?

有人可以帮我吗?

回答by Robert Ribas

The leastsq() method finds the set of parameters that minimize the error function ( difference between yExperimental and yFit). I used a tuple to pass the parameters and lambda functions for the linear and quadratic fits.

leastsq() 方法找到使误差函数(yExperimental 和 yFit 之间的差异)最小化的参数集。我使用了一个元组来传递线性和二次拟合的参数和 lambda 函数。

leastsq starts from a first guess ( initial Tuple of parameters) and tries to minimize the error function. At the end, if leastsq succeeds, it returns the list of parameters that best fit the data. ( I printed to see it). I hope it works best regards

leastsq 从第一个猜测(参数的初始元组)开始,并尝试最小化误差函数。最后,如果 leastsq 成功,它将返回最适合数据的参数列表。(我打印出来看看)。我希望它效果最好

from scipy.optimize import leastsq
import numpy as np
import matplotlib.pyplot as plt


def main():
   # data provided
   x=np.array([1.0,2.5,3.5,4.0,1.1,1.8,2.2,3.7])
   y=np.array([6.008,15.722,27.130,33.772,5.257,9.549,11.098,28.828])
   # here, create lambda functions for Line, Quadratic fit
   # tpl is a tuple that contains the parameters of the fit
   funcLine=lambda tpl,x : tpl[0]*x+tpl[1]
   funcQuad=lambda tpl,x : tpl[0]*x**2+tpl[1]*x+tpl[2]
   # func is going to be a placeholder for funcLine,funcQuad or whatever 
   # function we would like to fit
   func=funcLine
   # ErrorFunc is the diference between the func and the y "experimental" data
   ErrorFunc=lambda tpl,x,y: func(tpl,x)-y
   #tplInitial contains the "first guess" of the parameters 
   tplInitial1=(1.0,2.0)
   # leastsq finds the set of parameters in the tuple tpl that minimizes
   # ErrorFunc=yfit-yExperimental
   tplFinal1,success=leastsq(ErrorFunc,tplInitial1[:],args=(x,y))
   print " linear fit ",tplFinal1
   xx1=np.linspace(x.min(),x.max(),50)
   yy1=func(tplFinal1,xx1)
   #------------------------------------------------
   # now the quadratic fit
   #-------------------------------------------------
   func=funcQuad
   tplInitial2=(1.0,2.0,3.0)

   tplFinal2,success=leastsq(ErrorFunc,tplInitial2[:],args=(x,y))
   print "quadratic fit" ,tplFinal2
   xx2=xx1

   yy2=func(tplFinal2,xx2)
   plt.plot(xx1,yy1,'r-',x,y,'bo',xx2,yy2,'g-')
   plt.show()

if __name__=="__main__":
   main()

回答by LetzerWille

from scipy.optimize import leastsq
import scipy as sc
import numpy as np
import matplotlib.pyplot as plt

with optimize.curve_fitthe code is simpler, there is no need to define the residual(error) function.

使用optimize.curve_fit代码更简单,不需要定义残差(误差)函数。

fig, ax = plt.subplots ()
# data
x=np.array([1.0,2.5,3.5,4.0,1.1,1.8,2.2,3.7])
y=np.array([6.008,15.722,27.130,33.772,5.257,9.549,11.098,28.828])

# modeling functions
def funcLine(x, a,b):
    return a*x+b
def funcQuad(x, a, b, c):
    return a*x**2+b*x+c

# optimize constants for the linear function
constantsLine, _ = sc.optimize.curve_fit (funcLine, x, y)

X=np.linspace(x.min(),x.max(),50)
Y1=funcLine(X, *constantsLine)

# optimize constants for the quadratic function
constantsQuad, _ = sc.optimize.curve_fit (funcQuad, x, y)

Y2=funcQuad(X,*constantsQuad)
plt.plot(X,Y1,'r-',label='linear approximation')
plt.plot(x,y,'bo',label='data points')
plt.plot(X,Y2,'g-', label='quadratic approximation')
matplotlib.pylab.legend ()
ax.set_title("Nonlinear Least Square Problems", fontsize=18)
plt.show()

回答by Fletch F Fletch

Here's a super simple example. Picture a paraboloid, so like a bowl with sides growing like a parabola. If we put the bottom at coordinates (x, y) = (a, b) and then minimize the height of the paraboloid over all values of x and y - we would expect the minimum to be x=a and y=b. Here's code that would do this.

这是一个超级简单的例子。想象一个抛物面,就像一个碗,边长得像抛物线。如果我们将底部放在坐标 (x, y) = (a, b) 处,然后在 x 和 y 的所有值上最小化抛物面的高度 - 我们预计最小值为 x=a 和 y=b。这是可以做到这一点的代码。

import random

from scipy.optimize import least_squares


a, b = random.randint(1, 1000), random.randint(1, 1000)
print("Expect", [a, b])

def f(args):
    x, y = args
    return (x-a)**2 + (y-b)**2

x0 = [-1, -3]

result = least_squares(fun=f, x0=x0)

print(result.x)