2013-12-14 60 views
0

我還是新的python,我有一個問題曲線擬合。以下程序是我創建的更大程序的簡化,但它代表了我擁有的問題。scipy.optimize.curve_fit:無法做曲線擬合

問題是我有一個函數,我稱之爲漢堡,我不適合曲線。這一行: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() 

回答

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),並且維基百科表示,收斂取決於初始猜測,並且它找到本地而非全局最小值(有時您的代碼會爲某些情況下使y的sqrt不確定的參數)。如果有一種方法可以給它一個很好的初始猜測,那麼它應該可以工作([1.,3.,3.,2]適用於我)。我解決它的命令是:pa,j = curve_fit(burger,xlist,ylist, [1., 3., 3., 2], maxfev=10000))。

第三,當我使用你的代碼時,我得到的第一個錯誤是它達到了最大值。作爲curve_fit的最後一個參數添加maxfev=10000(或更多,如果需要)。

檢查出來。如果你可以給你更大的問題一個初步的猜測,那麼也許你會得到它的收斂。否則,也許不同的算法可能更適合?

更新:請參閱此question瞭解此原因的更詳細說明,但是如果您再給它一個千焦,diag,則可以毫無猜測地使用它。

用途:

pa,j = curve_fit(burger,xlist,ylist, diag=(1./xlist.mean(), 1./ylist.mean()), maxfev=10000)