Scipy曲线的误差适合两个以上的参数

时间:2018-11-27 23:01:06

标签: python-3.x numpy scipy curve-fitting

我对Scipy很陌生。我有一个数据文件(https://www.dropbox.com/s/mwz8s2kap2mnwo0/data.dat?dl=0),想要适合函数a exp(b x ^ c)。问题是当我手动给出c的值(例如c = 0.75)时,代码可以正常工作,但是如果我想从拟合中找到'a','b'和'c',则代码将无法工作并产生一条扁线对不起,如果问题太傻了。该代码显示为:

import numpy as np
from scipy.optimize import curve_fit
import sys
import matplotlib.pyplot as plt
import math as math

filename = sys.argv[1]

data = np.loadtxt(filename)

x = np.array(data[:,0])
y = np.array(data[:,1])

def func(x, a, b, c):
    return a*np.exp(b*x**c)

params = curve_fit(func, x, y)

[a, b, c] = params[0]

perr = np.sqrt(np.diag(params[1]))

x_new = []
y_new = []

for i in np.linspace(1.00003e-05, 0.10303175629999914, num=1000):
    j = func(i, a, b, c)
    x_new.append(i)
    y_new.append(j)

x1 = np.array(x_new)
y1 = np.array(y_new)

print ("a = ", a, "error = ", perr[0], "error % = ", (perr[0]/a)*100, '\t' "b = ", b, "error = ", perr[1], "error % = ", (perr[1]/b)*100), '\t' "c = ", c, "error = ", perr[2], "error % = ", (perr[2]/c)*100,

#np.savetxt('fit.dat', np.c_[x1, y1])

plt.plot(x, y, label='data')
plt.plot(x1, y1, label = 'a*np.exp(b*x**c)')
plt.xlabel('Time(s)')
plt.ylabel('SRO')
plt.legend()
plt.show()

1 个答案:

答案 0 :(得分:1)

指数方程对非线性求解器的初始参数估计可能非常敏感。默认情况下,如果未提供任何初始值估计,许多非线性求解器(包括scipy的curve_fit)都将默认初始值1.0用作这些初始参数估计值,在这种情况下,这些值对于数据和方程的组合而言并不是很好的初始估计值。 Scipy确实包含一种遗传算法,可用于确定初始参数估计值,并且其实现需要在搜索范围内进行。这是一个使用scipydifferential_evolution遗传算法模块的图形解算器示例,请注意我在其中使用遗传算法进行搜索的范围。用这种方法给参数范围而不是显式值要容易得多,尽管这并不总是正确的。您将需要更改用于加载数据的文件路径。

def self.to_csv(options = {}) 
        CSV.generate(options) do |csv|
            csv << column_names
            all.each do |order|
                csv << order.attributes.values_at(*column_names)
            end
        end
    end