当前位置: 首页 > 工具软件 > Fit > 使用案例 >

python 使用scipy中的curve_fit拟合自定义曲线

厍晋鹏
2023-12-01

Scipy是一个用于数学、科学、工程领域的常用软件包,可以处理插值、积分、优化、图像处理、常微分方程数值解的求解、信号处理等问题。它用于有效计算Numpy矩阵,使Numpy和Scipy协同工作,高效解决问题。
scipy.optimize中有curve_fit方法可以拟合自定义的曲线,如指数函数拟合,幂指函数拟合和多项式拟合,也能拟合直线方程函数。
curve_fit是使用非线性最小二乘法将函数f进行拟合,寻找到最优曲线。
下面汇总示例如下:
一、先导入所需要的包
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

plt.rcParams[‘font.family’] = [‘sans-serif’]
plt.rcParams[‘font.sans-serif’] = [‘SimHei’]

二、自定义需要拟合的函数

# =============================================================================
# 指数函数拟合
# =============================================================================
def func(x, a, b ):
    return a*np.exp(-b * x)+1/150

# =============================================================================
# 幂指数函数拟合
# =============================================================================
def func2(x, a, b ):
    return x**a +b

# =============================================================================
# 多项式函数拟合
# =============================================================================
def func3(x, a, b, c ):
    return a*x**2+ b*x +c  

# =============================================================================
# 高斯函数
# =============================================================================
def f_gauss(x, A, B, C, sigma):
    return A*np.exp(-(x-B)**2/(2*sigma**2)) + C


import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize
 
#直线方程函数
def f_1(x, A, B):
    return A*x + B
 
#二次曲线方程
def f_2(x, A, B, C):
    return A*x*x + B*x + C
 
#三次曲线方程
def f_3(x, A, B, C, D):
    return A*x*x*x + B*x*x + C*x + D
 
def plot_test():
 
    plt.figure()
 
    #拟合点
    x0 = [1, 2, 3, 4, 5]
    y0 = [1, 3, 8, 18, 36]
 
    #绘制散点
    plt.scatter(x0[:], y0[:], 25, "red")
 
    #直线拟合与绘制
    A1, B1 = optimize.curve_fit(f_1, x0, y0)[0]
    x1 = np.arange(0, 6, 0.01)
    y1 = A1*x1 + B1
    plt.plot(x1, y1, "blue")
 
    #二次曲线拟合与绘制
    A2, B2, C2 = optimize.curve_fit(f_2, x0, y0)[0]
    x2 = np.arange(0, 6, 0.01)
    y2 = A2*x2*x2 + B2*x2 + C2 
    plt.plot(x2, y2, "green")
 
    #三次曲线拟合与绘制
    A3, B3, C3, D3= optimize.curve_fit(f_3, x0, y0)[0]
    x3 = np.arange(0, 6, 0.01)
    y3 = A3*x3*x3*x3 + B3*x3*x3 + C3*x3 + D3 
    plt.plot(x3, y3, "purple")
 
    plt.title("test")
    plt.xlabel('x')
    plt.ylabel('y')
 
    plt.show()
 
    return

三、进行拟合并画出相应的曲线

if __name__=='__main__':
    data=pd.read_excel('data_p_2009-2018.xlsx')
    xdata=np.array(data['人均GDP(万元)'])
    ydata =np.array(data['期望寿命倒数'])
    #画出真实数据
    plt.plot(xdata,ydata,'b-')

    #指数函数拟合
    popt, pcov = curve_fit(func, xdata, ydata)#popt数组中,三个值分别是待求参数a,b,c
    #预测值
    y_pred = [func(i, popt[0],popt[1]) for i in xdata]
    #画图
    plt.plot(xdata,y_pred,'r--')
    print(popt)
    
    #输出R方
    from sklearn.metrics import r2_score
    r2 = r2_score(ydata , y_pred )
    print('指数函数拟合R方为:',r2)

    
    #幂指数函数拟合
    popt, pcov = curve_fit(func2, xdata, ydata)#popt数组中,三个值分别是待求参数a,b,c
    y_pred2 = [func2(i, popt[0],popt[1]) for i in xdata]
    #画图
    plt.plot(xdata,y_pred2,'g--')
    print(popt)
    #输出R方
    from sklearn.metrics import r2_score
    r2 = r2_score(ydata , y_pred2 )
    print('幂指数函数拟合:',r2)

    #多项式拟合
    popt, pcov = curve_fit(func3, xdata, ydata)#popt数组中,三个值分别是待求参数a,b,c
    y_pred3 = [func3(i, popt[0],popt[1],popt[2]) for i in xdata]
    #画图
    plt.plot(xdata,y_pred3,'y-')
    print(popt)
    #输出R方
    from sklearn.metrics import r2_score
    r2 = r2_score(ydata , y_pred3 )
    print('多项式拟合R方为:',r2)
    
    #添加图例
    plt.legend(['原始数据','指数函数拟合','幂指数函数拟合','多项式拟合']) 


本文转载于:土豆洋芋山药蛋、PHILOS_THU两位大佬的文章,感谢!

 类似资料: