簡體   English   中英

Scipy curve_fit僅對非常特定的x值靜默失敗

[英]Scipy curve_fit silently fails only for very specific x-values

我有一大段代碼,它的核心功能適合數據。 要擬合的數據和功能是動態的。 最近我在整個系統中添加了一個額外的數據點,現在curve_fit總是返回初始猜測(或者太接近它的東西),無論我如何選擇它。 這發生在非常不同的y值和x值(前者的10組,后者的兩組)中。

我知道選擇起始值很重要,但我以前從未遇到過使用默認值(我的函數通常很簡單)的問題,並且可以通過取消注釋添加附加數據點的新代碼來恢復到它正常工作的狀態。 現在人們會認為顯然新代碼是問題所在,但新添加和實際將數據提供給curve_fit之間有相當多的步驟。 我已經檢查過curve_fit的輸入類型是相同的: np.ndarray ,在有問題的情況下只有一個元素。

但是,在創建MWE時,我注意到只有精確的x陣列才會導致問題。 當我在MWE中復制主程序的打印x向量而不是內部表示時,它完全消失了。 因此我只能用外部文件顯示問題: local_z.npy [150kB]

MWE:

import numpy as np
from scipy.optimize import curve_fit

values = np.array([[1.37712972, 1.58475346, 1.78578759, 1.9843099,  1.73393093],
                   [-0.0155715,  -0.01534987, -0.00910744, -0.00189728, -1.73393093],
                   [1.23613934, 0.76894505, 0.18876817, 0.06376843, 1.1637315 ],
                   [0.8535248,  0.53093829, 0.13033993, 0.04403058, 0.80352895],
                   [0.51505805, 0.32039379, 0.0786534,  0.02657018, 0.48488813]])
heights = np.array([ 22.110203,  65.49054,  110.321526, 156.54034,  166.59094])
local_z = np.load('local_z.npy')
print('difference in heights', local_z - heights)

def func(z, a0, a1):
    return a0 + a1*z

for v in values:
    popt_non_working = curve_fit(func, local_z, v)[0]
    print('not working: ', popt_non_working)
    popt_working = curve_fit(func, heights, v)[0]
    print('working: ', popt_working)

我的輸出使用Python 2.7.6,numpy 1.14.1和scipy 1.0.0:

$ python auxiliary/SUBLIME_fit_test.py  
('difference in heights', array([-2.10693358e-07, -4.49218746e-07, -4.26269537e-07,  4.23828126e-06, 2.38281251e-06]))
/home/csag5117/venv/local/lib/python2.7/site-packages/scipy/optimize/minpack.py:785: OptimizeWarning: Covariance of the parameters could not be estimated category=OptimizeWarning)
('not working: ', array([1., 1.]))
('working: ', array([1.35420488, 0.00325281]))
('not working: ', array([1., 1.]))
('working: ', array([ 0.38896878, -0.00714073]))
('not working: ', array([1., 1.]))
('working: ', array([ 1.06301278, -0.00363439]))
('not working: ', array([1., 1.]))
('working: ', array([ 0.73398503, -0.00250946]))
('not working: ', array([1., 1.]))
('working: ', array([ 0.442922  , -0.00151433]))

正如您所看到的,我使用heights作為x值的版本按預期工作(返回擬合參數),而我使用存儲的`local_z'的版本沒有,即使兩個數組之間的差異非常小。 我只顯示多個y值,表明這不是一百萬個故障中的一個,可以通過適當的起始值來修復。 這也只是一個例子,我也有一個具有相同行為的更多數據點(24而不是5)。

為了完整起見,我添加了代碼塊(當我關閉它時一切正常)。 有趣的是,在MWE中使用local_z[:-1] local_z的最后一個值(這是由代碼塊添加的值)並不能解決問題。

zi_minus_dd -= 1
zf_long = np.append(out.zf, np.squeeze(data.zf[t])[z_mask_full[-1] + 1])
u_zi = np.interp(zi_minus_dd, zf_long,
    np.append(out.u, np.squeeze(data.u[t])[z_mask_full[-1] + 1]))
v_zi = np.interp(zi_minus_dd, zf_long,
    np.append(out.v, np.squeeze(data.v[t])[z_mask_full[-1] + 1]))
th_zi = np.interp(zi_minus_dd, zf_long,
    np.append(out.th, np.squeeze(data.th[t])[z_mask_full[-1] + 1]))

zh_long = np.append(out.zh, np.squeeze(data.zh[t])[z_mask_full[-1] + 1])
uw_zi = np.interp(zi_minus_dd, zf_long,
    np.append(out.uw_raw, np.squeeze(data.uw[t])[z_mask_full[-1] + 1]))
vw_zi = np.interp(zi_minus_dd, zf_long,
    np.append(out.vw_raw, np.squeeze(data.vw[t])[z_mask_full[-1] + 1]))
tke_zi = np.interp(zi_minus_dd, zf_long,
    np.append(out.tke, np.squeeze(data.TKE[t])[z_mask_full[-1] + 1]))

out.zf = np.append(out.zf, zi_minus_dd)
out.u = np.append(out.u, u_zi)
out.v = np.append(out.v, u_zi)
out.th = np.append(out.th, u_zi)

out.zh = np.append(out.zh, zi_minus_dd)
out.uw_raw = np.append(out.uw_raw, u_zi)
out.vw_raw = np.append(out.vw_raw, u_zi)
out.tke = np.append(out.tke, u_zi)

out.zfout.zh是后來被制作為local_z的向量。 整個代碼相當大,還取決於netCDF文件(上面代碼段中的data )。 我已經在這里詢問了這個問題 ,但這是針對工作代碼的。

我非常難過,不知道如何解決這個問題甚至繼續調試。 復制與深度復制有什么問題或類似的問題嗎? 雖然我想知道如何通過存儲的陣列轉移到MWE ...

追蹤這一點很有趣。 :-)

這不是價值觀,而是它們的類型 這是一個精確的問題:有效的heights是float64,local_z,它不起作用,只是float32。

我們有

In [70]: heights
Out[70]: array([ 22.110203,  65.49054 , 110.321526, 156.54034 , 166.59094 ])

In [71]: heights.dtype
Out[71]: dtype('float64')

In [72]: curve_fit(func, heights, v)[0]
Out[72]: array([1.35420488, 0.00325281])

In [73]: local_z
Out[73]: 
array([ 22.110205,  65.49054 , 110.321526, 156.54034 , 166.59094 ],
      dtype=float32)

In [74]: curve_fit(func, local_z, v)[0]
C:\Python\lib\site-packages\scipy\optimize\minpack.py:794: OptimizeWarning: Covariance of the parameters could not be estimated
  category=OptimizeWarning)
Out[74]: array([1., 1.])

但是如果我們想要,我們可以使local_z工作:

In [75]: curve_fit(func, local_z.astype(np.float64), v)[0]
Out[75]: array([1.35420488, 0.00325281])

或高度失敗:

In [76]: curve_fit(func, heights.astype(np.float32), v)[0]
C:\Python\lib\site-packages\scipy\optimize\minpack.py:794: OptimizeWarning: Covariance of the parameters could not be estimated
  category=OptimizeWarning)
Out[76]: array([1., 1.])

暫無
暫無

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

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