簡體   English   中英

使用 scipy curve_fit 將指數 function 擬合到數據,但 plot 中的所有 y 數據都接近 0

[英]Using scipy curve_fit to fit exponential function to data, but all y data is near 0 in plot

我一直在使用本教程( https://swharden.com/blog/2020-09-24-python-exponential-fit/ )在我的數據上擬合指數曲線(有關數據,請參見 pastebin: https://pastebin .com/DrEvJcRC )。 我調整了輸入以使用我自己的數據,並將 function 從負指數(m * np.exp(-t * x) + b)更改為正指數(m * np.exp(t * x) + b)

這是我的代碼(改編自教程):

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import scipy


# read data
df = pd.read_csv(r'C:/Users/HP/OneDrive/Bachelor/Segmentierung/Excel/1_new.csv', sep=";")
print(df)

x = df["x"]
y = df["y"]

# plot original
plt.plot(x, y, '.')
plt.title("Original Data")
plt.show()


def monoexp(x, m, t, b):
    return m * np.exp(t * x) + b

# perform the fit
# start with values near those we expect

params, cv = scipy.optimize.curve_fit(monoexp, x, y)
m, t, b = params
sampleRate = 20_000 # Hz
tauSec = (1 / t) / sampleRate

# determine quality of the fit
squaredDiffs = np.square(y - monoexp(x, m, t, b))
squaredDiffsFromMean = np.square(y - np.mean(y))
rSquared = 1 - np.sum(squaredDiffs) / np.sum(squaredDiffsFromMean)
print(f"R² = {rSquared}")

# plot the results
plt.plot(x, y, '.', label="data")
plt.plot(x, monoexp(x, m, t, b), '--', label="fitted")
plt.title("Fitted Exponential Curve")
plt.show()

# inspect the parameters
print(f"Y = {m} * e^({t} * x) + {b}")
print(f"Tau = {tauSec * 1e6} µs")

然而,當我嘗試 plot 擬合 function 時,所有 y 數據都集中在 y = 0 附近,盡管原始數據中的數據未集中在零附近。

原始數據
擬合曲線+原始數據

我不確定這是否是 matplotlib 或我的數據的問題。 任何幫助,將不勝感激。

編輯:這里是原來的 arrays:

y = np.array([[  50.265654   50.481338   55.598281   57.875762   54.32182    58.760685
   62.847534   64.28961    57.020572   72.1828     57.467019   62.230506
   67.540995   64.496286   54.763321   70.058298   70.710515   58.604998
   63.856038   71.711142   61.436699   69.918246   71.709434   72.019284
   71.667271   64.667837   73.15604    72.78848    75.194899   73.362767
   65.633833   76.527694   79.975514   66.31111    83.238201   86.12114
   61.883045   83.874603   68.157062   91.044078   92.729386   71.74222
   86.349847   82.8457     94.123932   89.738375   47.495947   78.255301
   98.873243   94.74139    93.019812  100.313886   97.69019    57.750244
   68.613443   37.156953  104.759545   85.397733  102.651581   99.332523
   66.748191  100.283648   84.807827   83.60035   109.183196   85.638829
   97.114549   99.870095   95.865177   95.974271   77.56365    95.365718
   79.186443   85.08403    76.981884   92.026004   90.356532   97.741741
   90.561301   95.034609   86.457017   93.39508    90.173374   92.576365
   96.131347   97.231791   95.589212   96.561979   94.905649   96.565916
   93.393454   99.992579   98.07305    93.475501  101.344676   98.577551
   97.309664   99.832354   96.305865  107.564353  100.852842  102.705253
   99.991087  100.500039   92.741113  105.655507  112.564399  113.391128
  112.92131   108.758485  116.600566  119.832142  116.127415   96.076771
  118.041184  121.801249  104.471811  119.362042  125.783554   99.582637
  121.588023  127.001352  142.354073  129.378792  122.716748  123.295855
  125.646691  117.353543  129.07801   133.94258   124.015839  125.661787
  130.53109   144.816005  157.213145  135.520705  149.981018  145.649621
  152.043158  151.030789  172.135762  157.441351  156.543511  136.303031
  166.656986  160.05244   161.973895  163.219232  170.589712  167.537767
  169.779851  194.229855  170.166431  174.551329  205.846669  188.975028
  206.772085  212.799242  193.089462  220.674931  225.05487   222.929436
  235.62132   257.330955  249.044577  231.147388  277.336486  257.839554
  269.695485  263.06116   271.412341  265.298246  271.612072  275.421131
  290.819824  267.474925  268.129235  261.022281  268.555814  269.902072
  274.178234  278.662213  291.951716  274.587357  279.547121  273.842799
  287.096126  301.781704  318.724333  320.13565   319.823382  305.842588
  323.785279  312.432472  360.068566  340.44523   357.468329  397.867687
  372.629412  373.711258  388.787463  401.839697  403.886104  407.850298
  414.755803  410.143675  407.997144  418.170715  446.555237  436.598994
  443.822001  453.202132  457.683222  473.140737  486.566587  507.351791
  521.557097  491.379094  523.612526  526.795454  553.596441  556.339232
  560.420248  564.853146  560.541646  574.501924  575.880492  580.008003
  606.287027  593.064523  575.563008  630.483781  614.198263  650.491796
  624.158124  666.845517  679.263829  663.266799  671.248458  655.239931
  669.626968  695.610041  667.202116  706.391511  711.907568  717.474155
  726.638     727.172115  758.956431  759.93291   764.690474  774.672464
  757.418492  822.346932  788.690474  794.585579  815.187357  828.10081
  810.168531  806.578016  833.373597  825.524955  895.056386  868.329793
  865.217297  892.069431  901.155111  841.722724  912.566196  906.663263
  911.161195  926.260885  891.846802  952.404458  968.076496  949.08048
  983.608895  975.126401 1020.251247  991.357126 1030.692856 1076.355363
 1057.721679 1100.199617 1068.971153 1109.204842 1123.111699 1136.594802
 1110.202018 1186.288809 1171.616713 1174.268427 1172.328883 1209.430644
 1213.274975 1226.917626 1243.912662 1258.744995 1284.971544 1286.015899
 1327.096185 1331.784306 1371.597679 1370.215724 1431.747674 1468.234523
 1476.391553 1466.01931  1444.764882 1472.96347  1511.162425 1551.551958
 1593.354289 1554.588089 1542.742428 1586.901403 1573.936749 1726.079181
 1619.650554 1657.632404 1761.770143 1719.361989 1703.11686  1747.136463
 1773.522743 1778.767987 1783.531536 1741.582718 1850.804924 1808.78412
 1790.434519])
x = np.array([[  1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18
  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36
  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54
  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72
  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90
  91  92  93  94  95  96  97  98  99 100 101 102 103 104 105 106 107 108
 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
 325 326 327 328 329 330 331])

你真誠的 科尼利厄斯

文檔說如果沒有提供初始值p0 ,所有參數都被初始化為1 這與您示例中的實際值相差幾個數量級。 還要注意,由於指數函數的范圍很廣,即使在很小的時間間隔內,這通常也只能在參數初始化良好的情況下工作。

從 plot 看起來我們可以假設m大約是1b大約是0 剩下的是t ,如果您認為指數 function 在x=300處應該在y=2000左右,我們可以從t=0.1t=0.01開始(作為log(2000)/300的近似值)。 如果我們將它作為p0=[1, 0.01, 0]插入你的curve_fit中,我們會得到更合理的結果:

在此處輸入圖像描述

最后我應該補充一點,如果最小二乘擬合(這是curve_fit使用的)真的是指數 function 想要的,或者是否有其他替代方法可以找到工作近似值,我會給出更多。

瑕疵者的回答非常好。 事實上,不需要更多的答案。

不過,我想添加一條評論(太長,無法在評論部分進行編輯)。

您的軟件中使用的非線性回歸方法是迭代的。 眾所周知,開始迭代演算需要為參數設置一些初始值。 在缺陷者的答案中明智地提到了這一點,並采用經驗方法來猜測初始值。

這非常重要,因為如果初始值離未知的正確值太遠,迭代演算可能會失敗。

當然,使用不需要猜測初始值的非迭代方法會更容易。 如下所示存在這樣的方法。

在此處輸入圖像描述

您的數據的數值示例:

在此處輸入圖像描述

與非線性回歸(迭代方法)相比,可以獲得:

a=-2.91212; b=35.547425; c=0.012030; RMSE=30.050141(均方根誤差)。

有了這些數據,兩種方法的擬合都是相同的。 人們無法區分上圖中兩條各自的藍色曲線之間的任何差異。

信息:

上述方法是線性回歸 wrt 指數方程是解的線性積分方程:

在此處輸入圖像描述

在數值微積分中,Sk 是通過數值積分計算的積分值。

參考: https://fr.scribd.com/doc/14674814/Regressions-et-equations-integrales

暫無
暫無

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

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