2016-11-20 263 views
0

我正在嘗試做一些曲線擬合。我有一個測量曲線,我相信這將是我的Y數據,我試圖用一些其他曲線的加權和進行擬合,我相信這些曲線是我的X數據。python中的scipy curvefit曲線擬合

我最近試圖做到這一點的嘗試如下,但我有幾個錯誤,我決定詢問是否有人能幫助指出我做錯了什麼?

import numpy as np 
import scipy.optimize 

ydata = np.array([1.0, 7.0, 4.0]) 
xdata = np.array([[0.0, 1.0],[3.5, 0.0],[1.0, 2.0]]) 

def fitfunc(xdata, *params): 
    ctx = 0.0 
    for n in np.nditer(c): 
     ctx = c[n]*xdata[:,n] + ctx 
    return ctx 

# initial guesses for fitting parameters, answer for this simple example is 2.0, 1.0 
c = np.array([0.6, 0.3]) 

# fit data using SciPy's Levenberg-Marquart method 
nlfit, nlpcov = scipy.optimize.curve_fit(fitfunc, xdata, ydata, p0=[c], sigma=None) 

print(nlfit) 

道歉,因爲無疑將是錯誤無處不在這一點,但我希望我的什麼,我試圖完成描述清楚

預先感謝您

+1

您確定您正在處理曲線擬合問題嗎?看來你正試圖將向量'ydata'逼近爲兩個向量'xdata [:,0]','xdata [:,1]'的線性組合,這本質上是一個線性代數問題。 – Stelios

回答

1
  1. fitfunc環路過來的參數的c,但n實際上是c的值,而不是指數。它試圖運行例如ctx = c[0.6]*xdata[:,0.6] + ctx
  2. fitfunc使用固定的全局c,而不是curve_fit傳遞給它的參數。它應該參考params,而不是c

你想要什麼,而不是爲

def fitfunc(xdata, *params): 
    ctx = 0.0 
    for n in range(len(params)): 
     ctx = params[n]*xdata[:,n] + ctx 
    return ctx 

我們可以看到,它的工作原理是通過自身運行它與print(fitfunc(xdata, *c)),返回[ 0.3 2.1 1.2]

請注意,*cprint(fitfunc(xdata, *c))中取c的元素,並將它們作爲單獨的參數傳遞,而不是作爲單個數組傳遞。這相當於編寫了fitfunc(xdata, c[0], c[1])

正如Stelios在評論中指出的,這是矩陣乘法,xdata[:,0] * c[0] + xdata[:,1] * c[1]。您可以使用np.matmul,這可能更快,如下所示:

def fitfunc(xdata, *params): 
    return np.matmul(xdata, params) 
+0

謝謝你的回答。我確實懷疑我的問題的這部分是線性的。在此之前,我已經在Excel中使用了Solver,但有人確信我應該學習Python,它看起來非常強大。我的例子很簡單,可能還有一些額外的操作,比如允許列向上或向下移動以獲得最佳擬合,由於實際數據中的噪聲和實驗位移,可能會使其非線性?但我會一步一步來看看我能否先讓這部分工作。再次感謝你,史蒂夫。 – steve

+0

這種特定的方法將始終是線性的,因爲您擬合的函數是線性的 - y = b1 * x1 + b2 * x2。 [curve_fit文檔](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html)有一個非線性函數的例子 - y = a * e ^( b * x)+ c。我建議查看數據的散點圖,看看是否有明顯的非線性。 – David

+0

再次感謝您,代碼現在完全符合我的要求。我選擇了使用矩陣乘法的更簡單的fitfunc。一些建議表明,我應該看看使用線性代數的解決方案,所以我會閱讀我如何用這種方法解決這類問題,而不是曲線擬合問題,因爲這對我來說都是新的。我還將研究可能的方式,以便我可以允許我的xdata的列相對於另一個「上下滑動」,以便在該功能可以改善配合的情況下。 – steve