最佳曲线拟合分布

时间:2018-10-26 23:55:47

标签: numpy plot scipy model-fitting

我尝试使用多项式(3度)来拟合数据序列,但似乎仍然不是最佳拟合(如下图所示,有些点不对)。我还尝试添加日志功能来帮助绘图。但是结果也没有改善。

这里最好的曲线拟合是什么?

以下是我拥有的原始数据点: 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]

多项式拟合的结果: enter image description here

1 个答案:

答案 0 :(得分:0)

如果您的曲线拟合过程是假设驱动的,那就更好了,也就是说,您已经有了一个想法,即期望什么样的关系。在我看来,形状更像是指数函数:

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()

这将提供以下输出:

enter image description here

这看起来仍然不正确,第一部分似乎具有线性偏移。如果我们考虑到这一点:

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()

我们有以下输出: enter image description here

现在,这更接近您的数据点。 但。您应该查看数据并考虑哪种模型最有可能反映现实,然后实施此模型。您总是可以构造更复杂的函数以更好地适合您的数据,但是它们不一定能反映出更好的现实。