Python - 最小化卡方

Wil*_*282 5 python statistics minimization scipy chi-squared

我一直在尝试通过最小化卡方来将线性模型拟合到一组应力/应变数据。不幸的是,使用下面的代码并不能正确地最小化该chisqfunc函数。它正在寻找初始条件下的最小值 ,x0这是不正确的。我已经查看了scipy.optimize文档并测试了最小化其他工作正常的功能。您能否建议如何修复下面的代码,或者建议我可以使用另一种方法通过最小化卡方来将线性模型拟合到数据?

import numpy
import scipy.optimize as opt

filename = 'data.csv'

data = numpy.loadtxt(open(filename,"r"),delimiter=",")

stress = data[:,0]
strain = data[:,1]
err_stress = data[:,2]

def chisqfunc((a, b)):
    model = a + b*strain
    chisq = numpy.sum(((stress - model)/err_stress)**2)
    return chisq

x0 = numpy.array([0,0])

result =  opt.minimize(chisqfunc, x0)
print result
Run Code Online (Sandbox Code Playgroud)

感谢您阅读我的问题,任何帮助将不胜感激。

干杯,威尔

编辑:我当前使用的数据集:链接到数据

gg3*_*349 5

问题是你最初的猜测与实际的解决方案相差甚远。chisqfunc()如果您在like中添加 print 语句print (a,b),然后重新运行代码,您将得到类似以下内容的信息:

(0, 0)
(1.4901161193847656e-08, 0.0)
(0.0, 1.4901161193847656e-08)
Run Code Online (Sandbox Code Playgroud)

这意味着minimize仅在这些点评估函数。

例如,如果您现在尝试评估chisqfunc()这 3 对值,您会发现它们完全匹配

print chisqfunc((0,0))==chisqfunc((1.4901161193847656e-08,0))
True
Run Code Online (Sandbox Code Playgroud)

发生这种情况是因为对浮点运算进行舍入。换句话说,在计算 时stress - model,var 比stress的数量级大太多model,结果被截断。

然后,人们可以尝试暴力破解它,提高浮点精度,并data=data.astype(np.float128)在使用 加载数据后立即写入loadtxtminimize失败,result.success=False但有一条有用的消息

由于精度损失,不一定能实现所需的误差。

一种可能性是提供更好的初始猜测,以便在减法中stress - modelmodel部分具有相同的数量级,另一种可能性是重新缩放数据,以便解决方案将更接近您的初始猜测(0,0)

如果您只是重新调整数据的比例,例如相对于某个应力值(例如这种材料的屈服/开裂)变得无量纲,那就更好了

这是一个拟合示例,使用最大测量应力作为应力标度。您的代码几乎没有变化:

import numpy
import scipy.optimize as opt

filename = 'data.csv'

data = numpy.loadtxt(open(filename,"r"),delimiter=",")

stress = data[:,0]
strain = data[:,1]
err_stress = data[:,2]


smax = stress.max()
stress = stress/smax
#I am assuming the errors err_stress are in the same units of stress.
err_stress = err_stress/smax

def chisqfunc((a, b)):
    model = a + b*strain
    chisq = numpy.sum(((stress - model)/err_stress)**2)
    return chisq

x0 = numpy.array([0,0])

result =  opt.minimize(chisqfunc, x0)
print result
assert result.success==True
a,b=result.x*smax
plot(strain,stress*smax)
plot(strain,a+b*strain)
Run Code Online (Sandbox Code Playgroud)

你的线性模型非常好,即你的材料对于这个变形范围具有非常线性的行为(到底是什么材料?): 在此输入图像描述