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两位大佬的文章,感谢!