簡體   English   中英

Python中的非線性最小二乘回歸

[英]Non-linear least-square regression in Python

我必須按照公式為我的 ~30 個數據點計算非線性最小二乘回歸

非線性最小二乘公式

我使用以下代碼嘗試了curve_fit函數

def func(x, p1 ,p2):
  return p1*x/(1-x/p2)

popt, pcov = curve_fit(func, CSV[:,1], CSV[:,0])

p1 = popt[0]
p2 = popt[1]

p1 和 p2 分別相當於 A 和 C,CSV 是我的數據數組。 函數運行時沒有錯誤消息,但結果與預期不同。 我已經繪制了函數的結果和原始數據點。 我不想得到這條近乎直線的直線(圖中的紅線),而是更接近綠線的東西,這只是 Excel 中的二階多項式擬合。 綠色虛線顯示了一個快速的手動嘗試,以接近多項式擬合。

擬合函數的錯誤計算以及原始數據點: 1

有沒有人知道如何按照我的意願運行計算?

你的代碼沒問題。 數據雖然不容易擬合。 圖表右側的點太少,左側的噪音太多。 這就是 curve_fit 失敗的原因。 改進解決方案的一些方法可能是:

  • 提高 curve_fit() 的 maxfev 參數請參見此處
  • 為 curve_fit() 提供起始值 - 見同一個地方
  • 添加更多數據點
  • 在函數或不同的函數中使用更多參數。

curve_fit() 可能不是最強大的工具。 看看您是否可以使用其他回歸類型的工具獲得更好的結果。

以下是我對您的初始數據和公式所能得到的最好結果:

df = pd.read_csv("c:\\temp\\data.csv", header=None, dtype = 'float' )
df.columns = ('x','y')

def func(x,  p1 ,p2):
    return p1*x/(1-x/p2)

popt, pcov = curve_fit(func, df.x, df.y,  maxfev=3000)
print('p1,p2:',popt)
p1, p2 = popt

y_pred = [ p1*x/(1-x/p2)+p3*x for x in range (0, 140, 5)]
plt.scatter(df.x, df.y)
plt.scatter(range (0, 140, 5), y_pred)

plt.show()

p1,p2: [-8.60771432e+02 1.08755430e-05]

在此處輸入圖片說明

我想我已經找到了使用 lmfit 包( https://lmfit.github.io/lmfit-py/v )解決這個問題的最佳方法。 當我嘗試將非線性最小二乘回歸擬合到 Excel 提供的擬合函數而不是原始數據時,效果最好(雖然不是很優雅)。

from lmfit import Model
import matplotlib.pyplot as plt
import numpy as np

def func(x,  o1 ,o2):
    return o1*x/(1-x/o2) 

xt = np.arange(0, 0.12, 0.005)
yt = 2.2268*np.exp(40.755*xt)

model = Model(func)
result = model.fit(yt, x=xt, o1=210, o2=0.118)

print(result.fit_report())

plt.plot(xt, yt, 'bo')
plt.plot(xt, result.init_fit, 'k--', label='initial fit')
plt.plot(xt, result.best_fit, 'r-', label='best fit')
plt.legend(loc='best') 
plt.show

結果看起來很不錯,而且這個包真的很容易使用(我省略了最終的情節)

[[Fit Statistics]]
    # fitting method   = leastsq
    # function evals   = 25
    # data points      = 24
    # variables        = 2
    chi-square         = 862.285318
    reduced chi-square = 39.1947872
    Akaike info crit   = 89.9567771
    Bayesian info crit = 92.3128848
[[Variables]]
    o1:  310.243771 +/- 12.7126811 (4.10%) (init = 210)
    o2:  0.13403974 +/- 0.00120453 (0.90%) (init = 0.118)
[[Correlations]] (unreported correlations are < 0.100)
    C(o1, o2) =  0.930

暫無
暫無

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

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