[英]Python: Fitting a piecewise polynomial
我正在嘗試擬合分段多項式 function
代碼:
import numpy as np
import scipy
from scipy.interpolate import UnivariateSpline, splrep
from scipy.optimize import curve_fit
from matplotlib import pyplot as plt
def piecewise_func(x, X, Y):
"""
cond_l: condition list
func_l: function list
"""
spl = UnivariateSpline(X, Y, k=3, s=0.5)
tck = (spl._data[8], spl._data[9], 3) # tck = (knots, coefficients, degree)
p = scipy.interpolate.PPoly.from_spline(tck)
cond_l = []
func_l = []
for idx, i in enumerate(range(3, len(spl.get_knots()) + 3 - 1)):
cond_l.append([(x >= p.x[i] & x < p.x[i + 1])])
func_l.append([lambda x: p.c[3, i] + p.c[2, i] * x + p.c[1, i] * x ** 2 + p.c[0, i] * x ** 3])
return np.piecewise(x, cond_l, func_l)
if __name__ == '__main__':
xdata = [0.28190937, 0.63429607, 0.91620544, 1.68793236, 2.32350115, 2.95215219, 4.5,
4.78103382, 7.2, 7.53430054, 8.03627018, 9., 9.86212529, 11.25951191, 11.62658532, 11.65598578, 13.90295926]
ydata = [0.36273168, 0.81614628, 1.17887796, 1.4475374, 5.52692706, 2.17548169, 3.55313396, 3.80326533, 7.75556311, 8.30176616, 10.72117182, 11.2499386,
11.72296513, 11.02146624, 14.51260631, 20.59365525, 21.77847853]
spl = UnivariateSpline(xdata, ydata, k=3, s=1)
plt.plot(xdata, ydata, '*')
plt.plot(xdata, spl(xdata))
plt.show()
p, e = curve_fit(piecewise_func, xdata, ydata)
# x_plot = np.linspace(0., 0.15, len(x))
# plt.plot(x, y, "+")
# plt.plot(x, (piecewise_func(x_plot, *p)), 'C3-', lw=3)
我嘗試了UnivariateSpline
function 進行插值,我看到了以下結果
但是,我不希望多項式曲線通過所有數據點。 我嘗試改變平滑因子,但無法獲得如下所示的結果。
預計 output:
我正在嘗試曲線擬合( 使用 UnivariateSpline 來緊密擬合數據)以獲得預期的 output 並且我遇到以下問題。
發布的代碼中的piecewise_func
返回分段多項式。 將其傳遞給curve_fit(piecewise_func, xdata, ydata)
返回錯誤
錯誤: res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)
ValueError: diff requires input that is at least one dimensional
我不確定哪里出了問題。
有關如何獲得預期合身性的建議將大有幫助。
我建議仔細查看UnivariateSpline 文檔中的參數s
:
s:浮動或無,可選
用於選擇結數的正平滑因子。 節點數將增加,直到滿足平滑條件:
sum((w[i] * (y[i]-spl(x[i])))**2, axis=0) <= s
如果
s
是None
,s = len(w)
如果1/w[i]
是y[i]
的標准偏差的估計值,這應該是一個很好的值。 如果為 0,spline 將插值所有數據點。 默認為None
。
由於您沒有設置w
,這只是一種復雜的說法,即s
是您允許的最小二乘誤差,即對所有數據點求和的平方誤差。 您的 1 值不會導致插值,但與您想要實現的目標相比,它非常緊湊。
服用
spl = UnivariateSpline(xdata, ydata, k=3, s=10)
所以我的建議是玩弄s
,如果證明不夠,請問一個新問題,更准確地描述你需要什么。 我還沒有正確看待piecewise_func
的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.