numpy.polynomial.polynomial.polyfit#

polynomial.polynomial.polyfit(x, y, deg, rcond=None, full=False, w=None)[原始碼]#

多項式對資料的最小平方擬合。

傳回次數為 deg 的多項式係數,該多項式是對在點 x 給定的資料值 y 進行最小平方擬合。如果 y 是一維的,則傳回的係數也將是一維的。如果 y 是二維的,則會進行多次擬合,y 的每一直行各進行一次,且結果係數會儲存在二維傳回值的對應直行中。擬合的多項式形式為

\[p(x) = c_0 + c_1 * x + ... + c_n * x^n,\]

其中 ndeg

參數:
xarray_like,形狀為 (M,)

M 個樣本(資料)點 (x[i], y[i]) 的 x 座標。

yarray_like,形狀為 (M,) 或 (M, K)

樣本點的 y 座標。可以使用一個 polyfit 呼叫,為 y 傳入一個二維陣列,其中每一直行包含一組資料集,以(獨立地)擬合多組共用相同 x 座標的樣本點。

deg整數或一維 array_like

擬合多項式的次數。如果 deg 是單一整數,則擬合中會包含直到且包含 deg 次項的所有項。對於 NumPy 版本 >= 1.11.0,可以使用整數列表來指定要包含的項的次數。

rcond浮點數,可選

擬合的相對條件數。小於 rcond 的奇異值(相對於最大奇異值)將被忽略。預設值為 len(x)*eps,其中 eps 是平台浮點型別的相對精度,在大多數情況下約為 2e-16。

full布林值,可選

切換決定傳回值的性質。當 False(預設值)時,僅傳回係數;當 True 時,也會傳回來自奇異值分解(用於解擬合的矩陣方程式)的診斷資訊。

warray_like,形狀為 (M,),可選

權重。如果不是 None,則權重 w[i] 適用於在 x[i] 處的未平方殘差 y[i] - y_hat[i]。理想情況下,選擇權重應使乘積 w[i]*y[i] 的誤差都具有相同的變異數。當使用反變異數加權時,請使用 w[i] = 1/sigma(y[i])。預設值為 None。

傳回值:
coefndarray,形狀為 (deg + 1,) 或 (deg + 1, K)

多項式係數,從低次到高次排序。如果 y 是二維的,則 coef 的第 k 行中的係數代表對 y 的第 k 行中的資料進行多項式擬合。

[residuals, rank, singular_values, rcond]list

只有當 full == True 時才會傳回這些值

  • residuals – 最小平方擬合的平方殘差和

  • rank – 縮放的 Vandermonde 矩陣的數值秩

  • singular_values – 縮放的 Vandermonde 矩陣的奇異值

  • rcond – rcond 的值。

如需更多詳細資訊,請參閱 numpy.linalg.lstsq

引發:
RankWarning

如果最小平方擬合中的矩陣是秩虧的,則會引發此警告。只有當 full == False 時才會引發警告。可以透過以下方式關閉警告

>>> import warnings
>>> warnings.simplefilter('ignore', np.exceptions.RankWarning)

註解

解是多項式 p 的係數,它最小化了加權平方誤差的總和

\[E = \sum_j w_j^2 * |y_j - p(x_j)|^2,\]

其中 \(w_j\) 是權重。此問題透過建立(通常是)過度確定的矩陣方程式來解決

\[V(x) * c = w * y,\]

其中 Vx 的加權偽 Vandermonde 矩陣,c 是要解出的係數,w 是權重,而 y 是觀測值。然後使用 V 的奇異值分解來解此方程式。

如果 V 的某些奇異值太小而被忽略(且 full == False),則會引發 RankWarning。這表示係數值可能無法準確確定。擬合到較低階的多項式通常會消除警告(但可能不是您想要的;如果您有獨立的理由選擇無法運作的次數,您可能需要:a) 重新考慮這些理由,和/或 b) 重新考慮您的資料品質)。rcond 參數也可以設定為小於其預設值的值,但結果擬合可能是虛假的,並且可能具有來自捨入誤差的大量貢獻。

使用雙精度浮點數的多項式擬合在(多項式)次數約為 20 時往往會「失敗」。使用切比雪夫或勒讓德級數的擬合通常條件更好,但很大程度上仍取決於樣本點的分布和資料的平滑度。如果擬合品質不足,樣條曲線可能是個不錯的替代方案。

範例

>>> import numpy as np
>>> from numpy.polynomial import polynomial as P
>>> x = np.linspace(-1,1,51)  # x "data": [-1, -0.96, ..., 0.96, 1]
>>> rng = np.random.default_rng()
>>> err = rng.normal(size=len(x))
>>> y = x**3 - x + err  # x^3 - x + Gaussian noise
>>> c, stats = P.polyfit(x,y,3,full=True)
>>> c # c[0], c[1] approx. -1, c[2] should be approx. 0, c[3] approx. 1
array([ 0.23111996, -1.02785049, -0.2241444 ,  1.08405657]) # may vary
>>> stats # note the large SSR, explaining the rather poor results
[array([48.312088]),                                        # may vary
 4,
 array([1.38446749, 1.32119158, 0.50443316, 0.28853036]),
 1.1324274851176597e-14]

相同的事情,但沒有加入雜訊

>>> y = x**3 - x
>>> c, stats = P.polyfit(x,y,3,full=True)
>>> c # c[0], c[1] ~= -1, c[2] should be "very close to 0", c[3] ~= 1
array([-6.73496154e-17, -1.00000000e+00,  0.00000000e+00,  1.00000000e+00])
>>> stats # note the minuscule SSR
[array([8.79579319e-31]),
 np.int32(4),
 array([1.38446749, 1.32119158, 0.50443316, 0.28853036]),
 1.1324274851176597e-14]