我仍然是python的新手,我有一个问题机智曲线拟合。以下程序是我创建的更大程序的简化,但它代表了我所遇到的问题。
问题在于我有一个我称汉堡的功能,我无法适应曲线。这一行:y = np.sqrt(y):是个问题。当我删除它时,我可以完美地适应它,但这不是我想要的功能。
我如何拟合这个函数y = np.sqrt(y)?
# -*- coding: utf-8 -*-
"""
Created on Wed Dec 11 22:14:54 2013
@author:
"""
import numpy as np
import matplotlib.pyplot as plt
import pdb
import scipy.optimize as optimization
from math import *
from scipy.optimize import curve_fit
import math
import moyenne
####################Function Burger###############################
def burger(t, E1, E2, N,tau):
nu=0.4 #Coefficient de Poisson
P=50 #Peak force
alpha=70.3 #Tip angle
y=((((pi/2.)*P*(1.-nu**2.))/(tan(alpha)))*(1./E1 + 1./E2*(1.-np.exp(-t/tau)) + 1./((N)*(1.-nu))*t))
y=np.sqrt(y)
return y
#######exemple d'utilisation##########
xlist=np.linspace(0,1,100)
ylist=[ burger(t,3, 2,1,0.1) for t in xlist]
#pdb.set_trace()
pa,j = curve_fit(burger,xlist,ylist)
yfit=[burger(x,*pa) for x in xlist]
plt.figure()
plt.plot(xlist,ylist,marker='o')
plt.plot(xlist,yfit)
plt.show()
答案 0 :(得分:1)
所以,这可能不是你得到的最佳答案,但是当你在这里等待其他人时,需要考虑一些事情。
首先,既然你是python的新手,也许你不知道,或者也许有理由在列表理解中解决这些问题,但我认为你不需要列表推导。您可以使用numpy数学运算一次处理整个数组。而不是
y=((((pi/2.)*P*(1.-nu**2.))/(tan(alpha)))* ...
你可以写
y = ((((np.pi/2.)*P*(1.-nu**2.))/(np.tan(alpha)))* ...
然后代替
[ burger(t, 3., 2., 1., 0.1) for t in xlist]
你可以做到
burger(xlist, 3., 2., 1., 0.1)
使用数组时,这会快得多。
其次,只是查看算法中发生的一些事情。它没有在正确的范围内寻找您的参数。我在scipy.optimize页面(here)上查找了它正在使用的算法,维基百科说收敛取决于初始猜测,并且它找到了本地而非全局的最小值(有时你的代码命中对于某些情况,使得sqrt of y undefined的参数的负值)。如果有一种方法你可以给它一个很好的初始猜测然后它应该工作([1.,3.,3.,2]为我工作)。我解决它的命令是:pa,j = curve_fit(burger,xlist,ylist, [1., 3., 3., 2], maxfev=10000)
)。
第三,我使用你的代码时得到的第一个错误是它达到了最大数量的fevals。添加maxfev=10000
(如果需要,可以更多)作为curve_fit的最后一个参数。
检查出来。如果你可以给你一个更大的问题进行初步猜测,那么你可能会让它收敛。否则,不同的算法可能更合适?
更新:请参阅此question以获取有关其工作原理的更详细说明,但如果您再给它一个kwg diag
,则无需猜测即可使用它。
使用:
pa,j = curve_fit(burger,xlist,ylist, diag=(1./xlist.mean(), 1./ylist.mean()), maxfev=10000)