【问题标题】:Fit a logarithmic curve to data points and extrapolate out in numpy将对数曲线拟合到数据点并在 numpy 中外推
【发布时间】:2018-10-01 07:28:20
【问题描述】:

我有一组数据点(代码中的 x 和 y)。我想绘制这些点,并为它们拟合一条曲线,显示使 y = 100.0 所需的 x 值(y 值是百分比)。这是我尝试过的,但我的曲线是 3 次多项式(我知道这是错误的)。对我来说,数据看起来是对数的,但我现在知道如何将对数曲线拟合到我的数据中。

import numpy as np
import matplotlib.pyplot as plt

x = np.array([4,8,15,29,58,116,231,462,924,1848])
y = np.array([1.05,2.11,3.95,7.37,13.88,25.46,43.03,64.28,81.97,87.43])

for x1, y1 in zip(x,y):
    plt.plot(x1, y1, 'ro')

z = np.polyfit(x, y, 3)
f = np.poly1d(z)

for x1 in np.linspace(0, 1848, 110):
    plt.plot(x1, f(x1), 'b+')

plt.show()

【问题讨论】:

  • "...但我不知道如何将对数曲线拟合到我的数据中"您不使用 polyfit 将对数函数拟合到数据。看看scipy.optimize.curve_fit

标签: python numpy matplotlib curve-fitting


【解决方案1】:

看起来像绑定curve:

def binding(x,kd,bmax):
    return (bmax*x)/(x+kd)
param=sp.optimize.curve_fit(binding, x,y)

plt.plot(x,y,'o',np.arange(2000),binding(np.arange(2000),*param[0]))

在这种情况下,严格来说,y=100% 只会发生在 x=inf

【讨论】:

    【解决方案2】:

    您实际上不需要使用 Numpy 或 Scipy 中的任何拟合函数,因为有一个“简单”closed form formula for finding the least-squares fit to a logarithmic curve。这是 Python 中的一个实现:

    def logFit(x,y):
        # cache some frequently reused terms
        sumy = np.sum(y)
        sumlogx = np.sum(np.log(x))
    
        b = (x.size*np.sum(y*np.log(x)) - sumy*sumlogx)/(x.size*np.sum(np.log(x)**2) - sumlogx**2)
        a = (sumy - b*sumlogx)/x.size
    
        return a,b
    

    然后你可以将它应用到你的问题上:

    x = np.array([4,8,15,29,58,116,231,462,924,1848])
    y = np.array([1.05,2.11,3.95,7.37,13.88,25.46,43.03,64.28,81.97,87.43])
    
    def logFunc(x, a, b):
        return a + b*np.log(x)
    
    plt.plot(x, y, ls="none", marker='.')
    
    xfit = np.linspace(0,2000,num=200)
    plt.plot(xfit, logFunc(xfit, *logFit(x,y)))
    

    不过,我不认为您的数据是对数的:

    【讨论】:

      【解决方案3】:

      我解决这类问题的方法是使用scipy.optimize.curve_fit。当然,这是您必须从scipy.optimize 导入的函数。

      该函数将您使用def f( x, a, b ) 定义的一个函数作为第一个参数。函数必须将自变量作为第一个参数,所有其他参数都应该是函数的参数。
      然后 .curve_fit() 获取 x 数据,然后获取 y 数据(numpy 一维数组很好)。它返回一个具有最佳拟合参数的数组。最后你应该有这样的东西。

      import numpy as np
      from scipy.optimize import curve_fit
      
      def l( x, a, b, c, d ):
          return a*np.log( b*x + c ) + d
      
      param = curve_fit( l, x, y )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-13
        • 2016-02-02
        • 2020-02-14
        相关资源
        最近更新 更多