指数回归函数Python [英] Exponential regression function Python

查看:815
本文介绍了指数回归函数Python的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现指数回归函数. sp代表sympy.我使用numpy和sympy.首先,在func_exp中,我尝试使用np.exp,但它生成了一个错误(属性错误),因此我决定改用sympy.好吧,这是代码

I am trying to implement a exponential regression function. sp stands for sympy. I use numpy and sympy. Firstly, in func_exp I tried to use np.exp but it generated an error (attribute error), so I decided to use sympy instead. Well, this is the code

import numpy as np
from numpy.linalg import matrix_rank
import scipy 
import scipy.integrate

import random 

import matplotlib.pyplot as plt
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D

from sympy import integrate
import sympy as sp

x, y = sp.symbols('x, y')

sp.init_printing(use_unicode=True,use_latex='mathjax')
def exponential_regression (x_data, y_data):
   def func_exp(x, a, b):
       return a*sp.exp(b*x)
   popt, pcov = scipy.optimize.curve_fit(func_exp, x_data, y_data)
   a = popt[0] # componente a, Parámetro ÓPTimo (popt).
   b = popt[1] # componente b, Parámetro ÓPTimo (popt).
   plt.figure()
   puntos = plt.plot(x_data, y_data, 'x', color='xkcd:maroon')
   curva_regresion = plt.plot(x_data, func_exp(x_data, a, b),    color='xkcd:teal')
   plt.show(puntos, curva_regresion)
   return func_exp(x, a, b)

我尝试执行:

  x_data = np.arange(0, 51) # Crea un array de 0 a 50.
  y_data = np.array([0.001, 0.199, 0.394, 0.556, 0.797, 0.891, 1.171, 1.128, 1.437, 
          1.525, 1.720, 1.703, 1.895, 2.003, 2.108, 2.408, 2.424,2.537, 
          2.647, 2.740, 2.957, 2.58, 3.156, 3.051, 3.043, 3.353, 3.400, 
          3.606, 3.659, 3.671, 3.750, 3.827, 3.902, 3.976, 4.048, 4.018, 
          4.286, 4.353, 4.418, 4.382, 4.444, 4.485, 4.465, 4.600, 4.681, 
          4.737, 4.792, 4.845, 4.909, 4.919, 5.100])
  exponential_regression(x_data, y_data)

然后我得到:

exponential_regression(x_data, y_data)
TypeError: Cannot cast array data from dtype('O') to dtype('float64') according to the rule 'safe'

Traceback (most recent call last):

File "<ipython-input-122-ee7c243ae4b0>", line 1, in <module>
exponential_regression(x_data, y_data)

 File "/Volumes/TOSHIBA/spline.py", line 35, in exponential_regression
popt, pcov = scipy.optimize.curve_fit(func_exp, x_data, y_data)

 File "/Applications/anaconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py", line 742, in curve_fit
res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs)

 File "/Applications/anaconda3/lib/python3.6/site-packages/scipy/optimize/minpack.py", line 387, in leastsq
gtol, maxfev, epsfcn, factor, diag)

 error: Result from function call is not a proper array of floats.

怎么了?预先感谢!

推荐答案

以下是适合您的fit函数的最小示例,该函数尽可能靠近您的代码,但删除了所有不必要的元素.您可以轻松删除c以符合您的要求:

Here is a minimal example for your fit function as close as possible to your code but removing all unnecessary elements. You can easily remove c to adhere to your requirements:

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

def func_exp(x, a, b, c):
        #c = 0
        return a * np.exp(b * x) + c

def exponential_regression (x_data, y_data):
    popt, pcov = curve_fit(func_exp, x_data, y_data, p0 = (-1, 0.01, 1))
    print(popt)
    puntos = plt.plot(x_data, y_data, 'x', color='xkcd:maroon', label = "data")
    curva_regresion = plt.plot(x_data, func_exp(x_data, *popt), color='xkcd:teal', label = "fit: {:.3f}, {:.3f}, {:.3f}".format(*popt))
    plt.legend()
    plt.show()
    return func_exp(x_data, *popt)

x_data = np.arange(0, 51) 
y_data = np.array([0.001, 0.199, 0.394, 0.556, 0.797, 0.891, 1.171, 1.128, 1.437, 
        1.525, 1.720, 1.703, 1.895, 2.003, 2.108, 2.408, 2.424,2.537, 
        2.647, 2.740, 2.957, 2.58, 3.156, 3.051, 3.043, 3.353, 3.400, 
        3.606, 3.659, 3.671, 3.750, 3.827, 3.902, 3.976, 4.048, 4.018, 
        4.286, 4.353, 4.418, 4.382, 4.444, 4.485, 4.465, 4.600, 4.681, 
        4.737, 4.792, 4.845, 4.909, 4.919, 5.100])
exponential_regression(x_data, y_data)

使用c = 0输出:

Output with c = 0:

使用c != 0的输出:

主要更改说明:

  1. 已删除sympy-与安装过程无关.
  2. 指数拟合函数的定义位于exponential_regression之外,因此可以从脚本的其他部分进行访问.它使用np.exp是因为您在scipy中使用numpy数组.
  3. 添加了参数p0 ,其中包含参数的初始猜测.由于局部极值,拟合函数通常对此初始猜测敏感.
  4. 使用*popt解压缩变量,使其对于不同数量的变量更加灵活. a = popt[0]b = popt[1]
  5. 删除了不必要的导入. 保持您的命名空间整洁.
  1. Removed sympy - it has nothing to do with the fitting procedure.
  2. The definition of the exponential fit function is placed outside exponential_regression, so it can be accessed from other parts of the script. It uses np.exp because you work with numpy arrays in scipy.
  3. Added the parameter p0 which contains the initial guesses for the parameters. Fit functions are often sensitive to this initial guess because of local extrema.
  4. Unpack variables with *popt to make it more flexible for different numbers of variables. a = popt[0], b = popt[1], etc.
  5. Removed unnecessary imports. Keep your namespace free from clutter.

这篇关于指数回归函数Python的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆