如何在Python中进行指数和对数曲线拟合?我发现只有多项式拟合

如何在Python中进行指数和对数曲线拟合?我发现只有多项式拟合

我有一组数据,我想比较哪条线最好地描述它(不同顺序的多项式,指数或对数)。

我使用Python和Numpy,对于多项式拟合,有一个函数polyfit()。但我没有发现指数和对数拟合的这些函数。

有吗?或者如何解决呢?


jeck猫
浏览 3602回答 3
3回答

千巷猫影

为了拟合y = A + B log x,只需对y(log x)拟合y。>>> x = numpy.array([1, 7, 20, 50, 79])>>> y = numpy.array([10, 19, 30, 35, 51])>>> numpy.polyfit(numpy.log(x), y, 1)array([ 8.46295607,  6.61867463])# y ≈ 8.46 log(x) + 6.62为了拟合y = Ae Bx,取两边的对数给出log y = log A + Bx。所以适合(log y)对抗x。注意,拟合(log y)就好像它是线性的一样会强调y的小值,导致大y的偏差很大。这是因为polyfit(线性回归)的工作原理是最小化Σ 我(Δ Ý)2 =Σ 我(ÿ 我 - Ŷ 我)2。当ÿ 我 =登录ÿ 我,残基Δ Ŷ 我 =Δ(日志Ý 我)≈Δ ÿ 我 / | Ÿ 我 |。即便如此polyfit对于大y做出了一个非常糟糕的决定,“除以| | y |” 因素将弥补它,导致polyfit有利于小的价值。这可以通过给每个条目赋予与y成比例的“权重”来减轻。polyfit通过w关键字参数支持加权最小二乘法。>>> x = numpy.array([10, 19, 30, 35, 51])>>> y = numpy.array([1, 7, 20, 50, 79])>>> numpy.polyfit(x, numpy.log(y), 1)array([ 0.10502711, -0.40116352])#    y ≈ exp(-0.401) * exp(0.105 * x) = 0.670 * exp(0.105 * x)# (^ biased towards small values)>>> numpy.polyfit(x, numpy.log(y), 1, w=numpy.sqrt(y))array([ 0.06009446,  1.41648096])#    y ≈ exp(1.42) * exp(0.0601 * x) = 4.12 * exp(0.0601 * x)# (^ not so biased)请注意,Excel,LibreOffice和大多数科学计算器通常使用指数回归/趋势线的未加权(偏差)公式。如果您希望结果与这些平台兼容,请不要包括权重,即使它提供了更好的结果。现在,如果你可以使用scipy,你可以使用scipy.optimize.curve_fit适合任何模型而不进行转换。对于y = A + B log x,结果与转换方法相同:>>> x = numpy.array([1, 7, 20, 50, 79])>>> y = numpy.array([10, 19, 30, 35, 51])>>> scipy.optimize.curve_fit(lambda t,a,b: a+b*numpy.log(t),  x,  y)(array([ 6.61867467,  8.46295606]),   array([[ 28.15948002,  -7.89609542],         [ -7.89609542,   2.9857172 ]]))# y ≈ 6.62 + 8.46 log(x)然而,对于y = Ae Bx,我们可以得到更好的拟合,因为它直接计算Δ(log y)。但我们需要提供初始化猜测,以便curve_fit达到所需的局部最小值。>>> x = numpy.array([10, 19, 30, 35, 51])>>> y = numpy.array([1, 7, 20, 50, 79])>>> scipy.optimize.curve_fit(lambda t,a,b: a*numpy.exp(b*t),  x,  y)(array([  5.60728326e-21,   9.99993501e-01]),  array([[  4.14809412e-27,  -1.45078961e-08],         [ -1.45078961e-08,   5.07411462e+10]]))# oops, definitely wrong.>>> scipy.optimize.curve_fit(lambda t,a,b: a*numpy.exp(b*t),  x,  y,  p0=(4, 0.1))(array([ 4.88003249,  0.05531256]),  array([[  1.01261314e+01,  -4.31940132e-02],         [ -4.31940132e-02,   1.91188656e-04]]))# y ≈ 4.88 exp(0.0553 x). much better.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python