2016-12-06 218 views
0

爲什麼這件衣服很糟糕?曲線擬合scipy

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
from scipy.optimize import curve_fit 

def fit(x, a, b, c, d): 
    return a * np.sin(b * x + c) + d 

xdata = np.linspace(0, 360, 1000) 
ydata = 89.9535 + 60.9535 * np.sin(0.0174 * xdata - 1.5708) 

popt, pcov = curve_fit(fit, xdata, ydata) 

plt.plot(xdata, 89.9535 + 60.9535 * np.sin(0.0174 * xdata - 1.5708)) 
plt.plot(xdata, fit(xdata, popt[0], popt[1], popt[2], popt[3])) 
plt.show() 

擬合曲線看起來很奇怪,或許我很想用它,謝謝你的幫助。

這是結果:

This is the result

回答

0

curve_fit找到本地最小的最小二乘問題。在這種情況下,有很多當地最低。

解決這個問題的一個方法是儘可能使用最初的猜測。對於有多個局部最小值的問題,curve_fit對所有初始猜測的缺省值可能非常糟糕。對於你的功能,關鍵參數是b,頻率。如果你知道值將是小的,即0.01順序,使用0.01作爲初始猜測:

In [77]: (a, b, c, d), pcov = curve_fit(fit, xdata, ydata, p0=[1, .01, 1, 1]) 

In [78]: a 
Out[78]: 60.953499999999998 

In [79]: b 
Out[79]: 0.017399999999999999 

In [80]: c 
Out[80]: -102.10176491487339 

In [81]: ((c + np.pi) % (2*np.pi)) - np.pi 
Out[81]: -1.570800000000002 

In [82]: d 
Out[82]: 89.953500000000005 
0

作爲替代,單獨繪製的原始數據,並用它來作參數的初始猜測。對於週期性函數,可以很容易地估計週期和幅度。在這種情況下,猜測不必太靠近。

然後我用這些在curve_fit

popt, pcov = curve_fit(fit, xdata, ydata, [ 80., np.pi/330, 1., 1. ])

它返回的結果基本上是原來的值。

array([ 6.09535000e+01, 1.74000000e-02, -1.57080000e+00, 
     8.99535000e+01])