我正在尝试使用minimize function from the scipy module . 完整代码太冗长而无法发布,但主要思想是有多个定义的分布应该适合数据集 . 每个bin的观察结果很容易根据数据集计算,而每个bin的期望值是通过一个函数计算的,该函数使用一个参数来指定应该在bin边界上整合哪个分布(其中bin边界与直方图bin相同) . 有三个函数chisqI,其中I = 1,2,3(每个分布一个),每个函数输入每个bin的指定观察值和每个bin的期望值以输出卡方 . 然后有三个函数,每个函数输入一个chisqI和args来输出最小化的函数结果和优化的参数 . 这里,args是参数mu和sigma,它们将被优化以产生最小的卡方 . 我能够通过一个函数链为一个分布传递参数,并且想知道我是否需要通过另一个arg来指定从链中的一个函数处理哪个分布 .
最小化函数可以使用不同的方法,如Nelder-Mead或CG . 我一直试图比较不同方法的结果来找到提供最佳拟合的结果(最佳拟合定义为与实际数据集相比产生最小卡方或最大p值的拟合) ) . 有趣的是,Nelder-Mead和Powell方法相对于其他方法产生最低的卡方,但是对于实际数据的直方图的绘制拟合看起来比其他方法更好 . 对于下面的代码输出,函数值是与卡方值相关联的p值的负数;这是最小化的结果 . CHISQ_RED
是通过使用 CHISQ_TOT
和自由度减小的卡方值,而 x: array
中的第一个和第二个元素分别是分布的优化参数mu和sigma .
运行Nelder-Mead最小化方法会产生下面的输出 .
final_simplex: (array([[ 6.00002802, 0.60020636],
[ 5.99995429, 0.60018798],
[ 6.0000716 , 0.60011127]]), array([ -5.16845821e-21, -5.16838926e-21, -5.16815050e-21]))
fun: -5.1684582072826815e-21
message: 'Optimization terminated successfully.'
nfev: 47
nit: 24
status: 0
success: True
x: array([ 6.00002802, 0.60020636])
CHISQ_TOT = 259.042420419 CHISQ_RED = 3.36418727816
运行CG最小化方法会产生下面的输出 .
fun: -4.0964504680695594e-97
jac: array([ 8.72867710e-94, -3.96555507e-93])
message: 'Optimization terminated successfully.'
nfev: 4
nit: 0
njev: 1
status: 0
success: True
x: array([ 6.01921293, 0.54436257])
CHISQ_TOT = 683.781671477 CHISQ_RED = 8.88028144776
然而,与higher chi square value looks like a better fit(直方图中的相同数据集)的拟合 .
问题是每种最小化方法都输出我的猜测参数(mu和sigma)作为优化参数 . Nelder-Mead方法(较小的卡方,更差的拟合)具有47个函数评估和24个迭代,而CG方法(更大的卡方,更好看的拟合)具有4个函数评估和0个迭代 . 我试图通过在最小化函数中添加额外的args来改变这一点(其中 chisq3
是mu和sigma的预定义函数被最小化, parameterguess
是 [mu_guess, sigma_guess]
.
minimize( chisq3 , parameterguess , method = 'CG', options={'gtol':1e-50, 'maxiter': 100})
如果我通过向每个加2来改变mu和sigma的猜测值,则拟合变得非常糟糕(因为优化参数的猜测值相当不错) . 我不确定它是否相关,但是图中显示的数据是通过采用我的数据集中每个值的对数来改变对数正态分布,以创建“伪”高斯形状/分布(在对数x轴上) .
我猜测通过scipy的最小化函数应该做很多迭代才能真正成功 . 因此,我认为添加更多迭代会降低最小化函数对初始参数猜测的敏感度 .
最重要的是,这是通过scipy使用最小化函数的常见错误吗?如果是这样,对此有哪些常见的解决方法?另外,为什么最小化函数会进行多次迭代和函数求值只能产生与输入相同的结果?
1 回答
问题是卡方是计算等于期望值和观测值的每箱差的平方之和,全部除以期望值 . 结果是一个小数除以一个大数,平方,然后连续总计数千次,导致零除法问题和舍入错误 . 通过最小化一个更简单的函数,例如没有分母项的卡方,bug的来源消失了,可以从获得的参数拟合中计算出卡方 .