【问题标题】:Bounds in scipy curve_fitscipy curve_fit 中的界限
【发布时间】:2021-07-22 08:44:55
【问题描述】:

我正在尝试拟合二分量高斯拟合:

mu0 = sum(velo_peak * spec_peak) / sum(spec_peak)
    sigma = np.sqrt(sum(spec_peak * (velo_peak - mu0)**2) / sum(spec_peak))
    
    def Gauss(velo_peak, a, mu0, sigma):
         res = a * np.exp(-(velo_peak - mu0)**2 / (2 * sigma**2))
         return res
    
    p0 = [max(spec_peak) - RMS, mu0, sigma]   # a = max(spec_peak)
    popt,pcov = curve_fit(Gauss, velo_peak, spec_peak, p0,maxfev=10000, bounds=((0, 0, +np.inf, +np.inf), (0, 0, +np.inf, +np.inf)))
    
    
    #____________________two component gaussian fit_______________________#
    
    def double_gaussian(velo_peak,a1, mu1, sigma1, a2, mu2, sigma2):
      
        res_two = a1 * np.exp(-(velo_peak - mu1)**2/(2 * sigma1**2))  \
                  + a2 * np.exp(-(velo_peak - mu2)**2/(2 * sigma2**2))
        return res_two
    
    ##_____________________Initial guess values__________________________##
    sigma1 = 0.7 * sigma
    sigma2 = 0.7 * sigma
    mu1 = mu0 + sigma  
    mu2 = mu0 - sigma
    a1 = 3        
    a2 = 1               
    guess = [a1, mu1, sigma1, a2, mu2, sigma2]
    popt_2,pcov_2 = curve_fit(double_gaussian, velo_peak, spec_peak, guess,maxfev=10000, bounds=((0, 0, +np.inf, +np.inf), (0, 0, +np.inf, +np.inf)))

但是我得到了一个我想避免的负面部分,但我不知道如何正确实现边界,因为我不太了解文档。 我收到以下错误: ValueError: Inconsistent shapes between bounds and `x0`.

谁能指导我如何正确使用边界?

【问题讨论】:

标签: python numpy scipy curve-fitting bounds


【解决方案1】:

它期待"2-tuple of array_like, optional",所以看起来像:

((lower_bound0, lower_bound1, ..., lower_boundn), (upper_bound0, upper_bound1, ..., upper_boundn))

在我看来,如果您想避免负值,那么在双高斯中您希望将 a1a2 限制为正值。

关注你的guess:

[a1, mu1, sigma1, a2, mu2, sigma2]

那就是:

... bounds=[(0, -np.inf, -np.inf, 0, -np.inf, -np.inf), (np.inf, np.inf, np.inf, np.inf, np.inf, np.inf)], ...

演示:

import matplotlib.pyplot as plt

def double_gaussian(velo_peak,a1, mu1, sigma1, a2, mu2, sigma2):

    res_two = a1 * np.exp(-(velo_peak - mu1)**2/(2 * sigma1**2))  \
              + a2 * np.exp(-(velo_peak - mu2)**2/(2 * sigma2**2))
    return res_two
x = np.linspace(0, 10, 1000)
y = double_gaussian(x, 1, 3, 1, 1, 7, 0.5) + 0.4*(np.random.random(x.shape) - 0.5)
popt, _ = curve_fit(double_gaussian, x, y, bounds=[(0, -np.inf, -np.inf, 0, -np.inf, -np.inf), (np.inf, np.inf, np.inf, np.inf, np.inf, np.inf)])
plt.plot(x, y)
plt.plot(x, double_gaussian(x, *popt))

【讨论】:

  • 这似乎合乎逻辑,谢谢。但我有一个错误: ValueError: sigma has wrong shape.
  • 改变了它,认为是现在
猜你喜欢
  • 2017-04-08
  • 2018-02-03
  • 2017-10-29
  • 2014-09-05
  • 1970-01-01
  • 1970-01-01
  • 2020-10-29
  • 2018-06-07
  • 1970-01-01
相关资源
最近更新 更多