【问题标题】:Why is optimize curve fit in scipy creating a straight line for this non linear model?为什么在 scipy 中优化曲线拟合会为这个非线性模型创建一条直线?
【发布时间】:2019-04-20 02:16:56
【问题描述】:

我正在尝试将我必须的一些数据拟合到与 x 成反比的模型中。我查看了一些类似的线程,我认为问题可能与扩展我的数据有关,但我已经对此进行了试验,但不幸的是没有成功。

import numpy as np
import scipy.optimize as optimize
import matplotlib.pyplot as plt

x = np.array([367.18,411.42,443.76,565.22,689.31,778.94,867.38,963.98,1085.79,1112.01,1212.47,1299.21,1408.08,1458.8,1528.76])
y = np.array([17.21,13.38,9.41,11.40,6.40,6.62,6.11,5.50,5.03,4.52,2.34,3.62,3.84,5.97,1.97])

def f(a,n,x1):
    return (a*np.power(x1,-n));

popt, pcov = optimize.curve_fit(f,x,y, diag=(1./x.mean(),1./y.mean()))
x1 = np.linspace(0,1700,num =1700)
plt.plot(x1, f(x1, *popt))
plt.plot(x,y,'ro')
plt.show()
print(popt, pcov)

结果是这样的: Plot

【问题讨论】:

    标签: python scipy curve-fitting


    【解决方案1】:

    我无法在评论中放置图像,因此将其放置在此处。我发现移动 X 值可以更好地拟合数据,使用等式“y = a * pow((xb), c)”,系数 a = 2.2685718105301993E+02,b = 2.7711446388529180E+02 和 c = -5.7863164386558297E-01 产生 R 平方 = 0.895 和 RMSE = 1.33

    【讨论】:

      【解决方案2】:

      您的函数f 的参数错误。根据documentation of curve_fit

      模型函数 f(x, …)。它必须将自变量作为第一个参数,并将适合的参数作为单独的剩余参数。

      所以你只需要将参数的顺序改为f,并把x1放在最前面:

      def f(x1, a,n):
          return (a*np.power(x1,-n))
      

      另外,关于绘图的另一个注意事项,为了能够看到拟合,请使用以下定义自变量来绘制曲线,使其适合您的数据范围:

      x1 = np.linspace(min(x),max(x),num =1700)
      

      然后你会得到图:

      【讨论】:

        【解决方案3】:

        当你跑线时

        plt.plot(x1, f(x1, *popt))
        

        您将 x1 作为第一个参数传递给函数 f。函数 f 的第一个参数是 a。

        def f(a,n,x1):
            return (a*no.power(x1,-n))
        

        即使您调用了第一个参数 x1,该函数也关心您传递变量的顺序,而不是变量名。因此,由于您将 f 定义为采用三个参数 a、n 和 x1,因此当您传入 x1 时,它将变量 x1 视为 a。

        重新排序你的函数定义,所以 x1 是第一个参数应该可以解决这个问题。

        import numpy as np
        import scipy.optimize as optimize
        import matplotlib.pyplot as plt
        
        x = np.array([367.18,411.42,443.76,565.22,689.31,778.94,867.38,963.98,1085.79,1112.01,1212.47,1299.21,1408.08,1458.8,1528.76])
        y = np.array([17.21,13.38,9.41,11.40,6.40,6.62,6.11,5.50,5.03,4.52,2.34,3.62,3.84,5.97,1.97])
        
        def f(x1,a,n):
            return (a*np.power(x1,-n));
        
        popt, pcov = optimize.curve_fit(f,x,y, diag=(1./x.mean(),1./y.mean()))
        x1 = np.linspace(0,1700,num =1700)
        plt.plot(x1, f(x1, *popt))
        plt.plot(x,y,'ro')
        plt.show()
        print(popt, pcov)
        

        【讨论】:

          猜你喜欢
          • 2017-09-15
          • 2017-11-23
          • 1970-01-01
          • 2021-07-23
          • 2017-04-21
          • 2018-06-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多