python - 为什么 scipy.optimize.curve_fit 产生的参数与猜测几乎没有什么不同?

标签 python scipy histogram curve-fitting least-squares

我一直在尝试使用 scipy.optimize.curve_fit 拟合一些直方图数据,但到目前为止,我还没有能够生成与我的猜测参数显着不同的拟合参数。

如果发现我的拟合中更多神秘的参数陷入局部最小值,我不会感到非常惊讶,但即使是线性系数也不会偏离我最初的猜测!

如果您以前见过类似的事情,我希望得到一些建议。最小二乘最小化例程不适用于某些类型的函数吗?

我试试这个,

import numpy as np
from matplotlib.pyplot import *
from scipy.optimize import curve_fit

def grating_hist(x,frac,xmax,x0):
  #  model data to be turned into a histogram
  dx = x[1]-x[0]
  z = np.linspace(0,1,20000,endpoint=True)
  grating = np.cos(frac*np.pi*z)
  norm_grating = xmax*(grating-grating[-1])/(1-grating[-1])+x0
  # produce the histogram
  bin_edges = np.append(x,x[-1]+x[1]-x[0])
  hist,bin_edges = np.histogram(norm_grating,bins=bin_edges)
  return hist

x = np.linspace(0,5,512)
p_data = [0.7,1.1,0.8]
pct = grating_hist(x,*p_data)
p_guess = [1,1,1]
p_fit,pcov = curve_fit(grating_hist,x,pct,p0=p_guess)

plot(x,pct,label='Data')
plot(x,grating_hist(x,*p_fit),label='Fit')
legend()

show()

print 'Data Parameters:', p_data
print 'Guess Parameters:', p_guess
print 'Fit Parameters:', p_fit
print 'Covariance:',pcov

我看到这个:/image/GwXzJ.png (我是新来的,所以不能发布图片)

Data Parameters: [0.7, 1.1, 0.8]
Guess Parameters: [1, 1, 1]
Fit Parameters: [ 0.97600854  0.99458336  1.00366634]
Covariance: [[  3.50047574e-06  -5.34574971e-07   2.99306123e-07]
 [ -5.34574971e-07   9.78688795e-07  -6.94780671e-07]
 [  2.99306123e-07  -6.94780671e-07   7.17068753e-07]]

哇啊?我很确定这不是 xmax 和 x0 变化的局部最小值,而且距离全局最小值最佳拟合还有很长的路要走。即使有更好的猜测,拟合参数仍然不会改变。曲线函数的不同选择(例如两个正态分布的总和)确实会为相同的数据产生新的参数,所以我知道这不是数据本身。我也对 scipy.optimize.leastsq 本身尝试了同样的操作,以防万一,但没有骰子;参数还是没动。如果您对此有任何想法,我很想听听!

最佳答案

您面临的问题实际上不是由curve_fit(或leastsq)引起的。这是由于优化问题的目标情况所致。在您的情况下,目标是残差平方和,您试图将其最小化。现在,如果您在初始条件的附近仔细观察您的目标,例如使用下面的代码,该代码仅关注第一个参数:

p_ind = 0
eps = 1e-6
n_points = 100

frac_surroundings = np.linspace(p_guess[p_ind] - eps, p_guess[p_ind] + eps, n_points)

obj = []
temp_guess = p_guess.copy()
for p in frac_surroundings:
    temp_guess[0] = p
    obj.append(((grating_hist(x, *p_data) - grating_hist(x, *temp_guess))**2.0).sum())

py.plot(frac_surroundings, obj)
py.show()

你会注意到景观是分段常数(你可以很容易地检查其他参数的情况是否相同。问题是这些片段的数量级为 10^-6,而初始步骤拟合过程约为 10^-8,因此该过程很快结束,得出的结论是您无法从给定的初始条件进行改进。您可以尝试通过更改 curve_fit< 中的 epsfcn 参数来修复它,但你很快就会注意到,除了分段常数之外,景观也非常“崎岖”。换句话说,curve_fit 根本不适合解决这样的问题,对于基于梯度的方法来说,这是很困难的,因为它是高度非凸的。也许,一些随机优化方法可以做得更好。然而,这是一个不同的问题。

关于python - 为什么 scipy.optimize.curve_fit 产生的参数与猜测几乎没有什么不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17356793/

相关文章:

python - 从目录中读取所有文本文件

python - 是否可以使用 k-means 在 scikit/sklearn learn 中使用的 K++ 初始化过程?

python - Python 中的无限求和

python - SciPy leastsq 适合正弦波失败

image-processing - 哪些库可用于图像的直方图均衡化?

python - Matplotlib 直方图 : glitch when setting rwidth to 0. 9

r - 在不使用包的情况下编写直方图

python - 在 IP 地址列上合并两个 DataFrame

python - Scipy convolve2d 具有像 Theano 的 conv2d 那样的子采样功能吗?

Python:OOP 开销?