如果你的曲线拟合过程是假设驱动的,那就更好了,也就是说,你已经有了一个想法,期望什么样的关系。在我看来,这个形状更像是一个指数函数:
from matplotlib import pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
#the function that describes the data
def func(x, a, b, c, d):
return a * np.exp(b * x + c) + d
x_values = [0.51,0.56444444, 0.61888889, 0.67333333 , 0.72777778, 0.78222222, 0.83666667, 0.89111111 , 0.94555556 , 1. ]
y_values = [0.67154591, 0.66657266, 0.65878351, 0.6488696, 0.63499979, 0.6202393, 0.59887225, 0.56689689, 0.51768976, 0.33029004]
#start values [a, b, c, d]
start = [-.1, 1, 0, .1]
#curve fitting
popt, pcov = curve_fit(func, x_values, y_values, p0 = start)
#output [a, b, c, d]
print(popt)
#calculating the fit curve at a better resolution
x_fit = np.linspace(min(x_values), max(x_values), 1000)
y_fit = func(x_fit, *popt)
#plot data and fit
plt.scatter(x_values, y_values, label = "data")
plt.plot(x_fit, y_fit, label = "fit")
plt.legend()
plt.show()
这给出了以下输出:
这看起来仍然不正确,第一部分似乎有线性偏移。如果我们考虑到这一点:
from matplotlib import pyplot as plt
import numpy as np
from scipy.optimize import curve_fit
def func(x, a, b, c, d, e):
return a * np.exp(b * x + c) + d * x + e
x_values = [0.51,0.56444444, 0.61888889, 0.67333333 , 0.72777778, 0.78222222, 0.83666667, 0.89111111 , 0.94555556 , 1. ]
y_values = [0.67154591, 0.66657266, 0.65878351, 0.6488696, 0.63499979, 0.6202393, 0.59887225, 0.56689689, 0.51768976, 0.33029004]
start = [-.1, 1, 0, .1, 1]
popt, pcov = curve_fit(func, x_values, y_values, p0 = start)
print(popt)
x_fit = np.linspace(min(x_values), max(x_values), 1000)
y_fit = func(x_fit, *popt)
plt.scatter(x_values, y_values, label = "data")
plt.plot(x_fit, y_fit, label = "fit")
plt.legend()
plt.show()
我们有以下输出:
这现在更接近您的数据点。
但。你应该去你的数据思考,哪个模型最有可能反映现实,然后实施这个模型。您始终可以构建更复杂的函数来更好地拟合您的数据,但它们不一定能反映更好的现实。