簡體   English   中英

Python:擬合分段多項式

[英]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

如果sNones = len(w)如果1/w[i]y[i]的標准偏差的估計值,這應該是一個很好的值。 如果為 0,spline 將插值所有數據點。 默認為None

由於您沒有設置w ,這只是一種復雜的說法,即s是您允許的最小二乘誤差,即對所有數據點求和的平方誤差。 您的 1 值不會導致插值,但與您想要實現的目標相比,它非常緊湊。

服用

    spl = UnivariateSpline(xdata, ydata, k=3, s=10)

你得到以下信息: 樣條 s=10

然而更接近你的目標是s=100 樣條 s=100

所以我的建議是玩弄s ,如果證明不夠,請問一個新問題,更准確地描述你需要什么。 我還沒有正確看待piecewise_func的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM