首页 > 解决方案 > 为什么 scipy 的 minimumsq 无法生成 cov_x 矩阵?

问题描述

我最近一直在使用 specutils' fit_lines,它依赖于 scipy's leastsq,将高斯轮廓拟合到谱线。但是,有时不会返回拟合错误,因为 cov_x 矩阵被 scipy's 作为 None 值返回leastsq。拟合成功,即返回的 ierr 值是“等于 1、2、3 或 4,[意味着] 找到了解决方案。” 如leastsq文档中所述,因此这不是问题的原因。

因此,我的问题是双重的——首先我想知道是否有人可以帮助解释为什么会发生这种情况,也许更重要的是,我是否可以做些什么来对其进行排序。

我花了很长时间搜索所有文档并阅读源代码以找出我的问题,虽然我对我对统计数据方面的了解不是很有信心,但我认为问题正在发生,因为何时leastsq尝试为了最小化函数,它到达底部的一个平坦点而不是找到一个最小值?在leastsq文档中对 cov_x 的描述中,它指出“无值表示奇异矩阵,这意味着参数 x 中的曲率在数值上是平坦的。”。

我曾尝试更改各种参数,例如 epsfcn、xtol,但这并没有帮助,除非我大量更改这些值,而且由于我不是 100% 确定我理解这是在做什么,我不是真的只是将其用作解决方案。

我花了几个小时在谷歌搜索,但无法找到我的问题的答案,所以我非常感谢任何人可以提供的任何帮助!

from astropy.modeling import models, fitting
from specutils import Spectrum1D
from specutils.fitting import fit_lines

#The arrays are:
Waves = [4379.25263541926,4380.261111703601,4381.26982022493,4382.278761036721,4383.2879341924645,4384.297339745673,4385.306977749856,4386.316848258552,4387.326951325295,4388.337287003648,4389.34785534717,4390.358656409448,4391.369690244064,4392.380956904633,4393.3924564447625,4394.404188918088,4395.416154378243,4396.428352878889,4397.440784473684,4398.453449216315,4399.466347160462,4400.479478359837,4401.492842868152,4402.50644073913,4403.520272026519,4404.534336784062,4405.548635065535,4406.563166924702,4407.5779324153655,4408.592931591316,4409.608164506378,4410.623631214367,4411.6393317691345,4412.655266224519,4413.671434634397,4414.687837052633,4415.704473533126,4416.721344129766,4417.738448896479,4418.7557878871785,4419.773361155814,4420.79116875633,4421.809210742687,4422.827487168868,4423.845998088853,4424.86474355665,4425.883723626264,4426.90293835173,4427.922387787075,4428.942071986359,4429.961991003635,4430.982144892989,4432.002533708497,4433.02315750427,4434.04401633441,4435.065110253052,4436.086439314323,4437.1080035723835,4438.129803081385,4439.1518378955125,4440.174108068944,4441.1966136558885,4442.219354710549,4443.242331287159,4444.265543439951,4445.28899122317,4446.312674691088,4447.3365938979705,4448.360748898113,4449.385139745807,4450.409766495372,4451.434629201126,4452.459727917414,4453.485062698576,4454.510633598985,4455.536440673005,4456.562483975033,4457.58876355946,4458.615279480707,4459.642031793189,4460.669020551353,4461.6962458096405,4462.723707622523,4463.75140604447,4464.779341129965,4465.8075129335175,4466.835921509631,4467.864566912838,4468.89344919767,4469.922568418684,4470.951924630434,4471.981517887507,4473.0113482444785,4474.041415755961,4475.071720476557,4476.102262460901,4477.133041763624,4478.164058439384]

 Flux = [-1.609175,-0.47427708,-0.60574985,-0.9217671,-0.14470458,1.7211268,-0.2885138,-0.0131763145,2.017541,-0.1551357,-0.62813485,0.42844194,0.23762748,0.1571013,0.18695286,-0.34576598,-0.079983935,0.11033059,0.6188194,-1.9645425,-1.1938491,-0.0038357377,1.2829684,-0.05393645,1.1477329,0.24603112,0.491022,0.55074716,-0.704924,-1.8671623,-0.96216017,1.0169754,1.9615287,1.8186992,0.4183128,6.846475,16.397682,32.69029,35.413,22.62686,6.9653482,0.36010352,1.244956,2.468903,-0.48600048,0.33933347,-0.45105207,0.21166058,-0.32686746,-0.26580417,-1.0156804,-0.676653,0.106376775,0.77532375,-0.18942682,-0.37561917,-0.5789215,0.7508146,0.4098208,-0.5737959,2.2061667,1.0370786,-1.323368,-2.41041,0.058673777,0.19647884,-0.7343958,-0.5081159,0.42372695,-0.057333924,-1.5179241,-1.119834,0.44848588,1.3844675,-0.19506846,-1.1519253,-0.6201113,0.3387856,0.33886302,0.028457977,-0.91573006,-0.7338029,1.1618475,-0.9490578,0.58596385,-0.086719885,-1.1230637,-1.3438936,-0.76436615,1.4362102,-0.20128047,-0.50129366,-0.9696252,-1.0146995,0.2377935,-0.593785,-1.0109384,-0.95101863]


#Then I created a Spectrum1D object with these in order to use specutils, but it uses the astropy fitting routine (with LevMarLeastSq), which relies on scipy's leastsq anyways, so shouldn't make a difference which is used.

#Then astropy's fitting routine is used, with a compound model of 2 Gaussian components and a constant background. 
model_init = models.Const1D(amplitude=0.) + models.Gaussian1D(amplitude=32.69028854, mean=4416.72134413, stddev=1.) + models.Gaussian1D(amplitude=2.20616674, mean=4440.17410807, stddev=1.) 

Fitter = fitting.LevMarLSQFitter()
#astropy fitting routine:
fitted_model = Fitter(model_init, Waves, Flux)

#Then the covariance matrix is accessible by doing 
print(Fitter.fit_info['cov_x'])
#Which for me returns None. 

虽然拟合图看起来不错,但我知道在这种情况下它并没有拾取较小的线,但这不是我可以真正取出的东西,因为我的拟合点是确定它是否存在于样本中的几个光谱。 在此处输入图像描述

标签: pythonscipyleast-squaresastropyastronomy

解决方案


推荐阅读