博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数学建模方法 — 【05】 拟合方法之leastsq
阅读量:3943 次
发布时间:2019-05-24

本文共 5725 字,大约阅读时间需要 19 分钟。

拟合方法——leastsq

1. 概念:

scipy官网对该方法介绍是: 最小化一组方程的平方和

x = arg ⁡ min ⁡ y ( ∑ ( ( f u n c ( y ) ) 2 , a x i s = 0 ) ) x =\arg \min\limits_{y}(\sum((func(y))^2,axis=0)) x=argymin(((func(y))2axis=0))
简单介绍一下leastsq的参数:
scipy.optimize.leastsq(func,x0,args = (),Dfun = None,full_output = 0,col_deriv = 0,ftol = 1.49012e-08,xtol = 1.49012e-08,gtol = 0.0,maxfev = 0,epsfcn = None,factor = 100,diag = None)

# 参数:func: 所求平方和最小值的函数,一般都用于拟合时传入残差函数,当然也有其他用途,比如求函数的最小等等x0: ndarray  一般为参数的初始值args: 元组,可选,可以传入(x, y)其中x,y都是数组,作为求解传入的参数
# 返回值leastsq的返回值是一个元组,里面包含了很多信息,如果是用作拟合的话,返回值的索引值为0的元素即为我们所求函数参数

有兴趣的读者可以自己看看官网介绍:

2. 使用:

1. 求最小值

比如求 2 ( x − 3 ) 2 + 1 2(x-3)^2+1 2(x3)2+1的最小值:

from scipy.optimize import leastsqdef func(x):    return 2*(x-3)**2+1print(leastsq(func, 0))   # 0为x的初始值,初始值可以由自己定,改成任意一个随机值都可以

结果为:

(array([2.99999999]), 1)

x = 2.99999999 ≈ 3 x=2.99999999\approx3 x=2.999999993时,函数最小值为1

2. 拟合

为了和上一篇文章形成一个比较,我们这里也进行1-5阶的多项式拟合。

  1. 定义要拟合的函数关系式 (因为我们这里函数关系式是多项式,所以就用np.ploy1d获取了多项式了)
    from scipy.optimize import leastsq# 拟合数据集x = [4, 8, 10, 12, 25, 32, 43, 58, 63, 69, 79]y = [20, 33, 50, 56, 42, 31, 33, 46, 65, 75, 78]x_arr = np.array(x)y_arr = np.array(y)def fitting_func(p, x):   """   获得拟合的目标数据数组   :param p: array[int] 多项式各项从高到低的项的系数数组   :param x: array[int] 自变量数组   :return: array[int] 拟合得到的结果数组   """   f = np.poly1d(p)    # 获得拟合后得到的多项式   return f(x)         # 将自变量数组带入多项式计算得到拟合所得的目标数组
    如果想要拟合的是其他函数,那只需要将 f = np.poly1d(p)改为你想要拟合的函数关系式即可。
  2. 定义残差计算函数
    def error_func(p, x, y):"""计算残差:param p: array[int] 多项式各项从高到低的项的系数数组:param x: array[int] 自变量数组:param y: array[int] 原始目标数组(因变量):return: 拟合得到的结果和原始目标的差值"""err = fitting_func(p, x) - yreturn err
    残差有很多计算方法,这里因为leastsq方法本身就会将我们的残差函数平方,所以这里我们直接相减,在经过leastsq方法的平方后就变为了最小二乘法了。
  3. 获取参数
    def n_poly(n, x, y):   """   n 次多项式拟合函数   :param n: 多项式的项数(包括常数项),比如n=3的话最高次项为2次项   :return: 最终得到的系数数组   """   p_init = np.random.randn(n)   # 生成 n个随机数,作为各项系数的初始值,用于迭代修正   parameters = leastsq(error_func, p_init, args=(np.array(x), np.array(y)))    # 三个参数:误差函数、函数参数列表、数据点   return parameters[0]	# leastsq返回的是一个元组,元组的第一个元素时多项式系数数组[wn、...、w2、w1、w0]
  4. 函数定义好后,就可以进行拟合了(这里计算拟合优度的方法goodness_of_fit在我前面的文章有: )
    一阶
    para_2 = n_poly(2, x_arr, y_arr)  # 一阶print("系数为:", para_2)print("多项式为:", np.poly1d(para_2))print("拟合值为:", fitting_func(para_2, x_arr))print("拟合优度为:", goodness_of_fit(fitting_func(para_2, x_arr), y_arr))
    二、三、四、五阶:
    para_3 = n_poly(3, x_arr, y_arr)  # 二阶para_4 = n_poly(4, x_arr, y_arr)  # 三阶para_5 = n_poly(5, x_arr, y_arr)  # 四阶para_6 = n_poly(6, x_arr, y_arr)  # 五阶
    这里解释一下为什么一阶传入n=2,二阶传入n=3…。因为这里的n表示的不是多项式的阶数,而是表示多项式的项数,比如二阶的多项式有 x 2 、 x x^2、x x2x还有常数项三项,所以传入的n=3。
  5. 得到拟合的数据后就可以作图了
    figure = plt.figure(figsize=(8,6))  plt.plot(x_arr, fitting_func(para_2, x_arr), color="#72CD28", label='一阶拟合曲线')  plt.plot(x_arr, fitting_func(para_3, x_arr), color="#EBBD43", label='二阶拟合曲线')  plt.plot(x_arr, fitting_func(para_4, x_arr), color="#50BFFB", label='三阶拟合曲线')  plt.plot(x_arr, fitting_func(para_5, x_arr), color="gold", label='四阶拟合曲线')  plt.plot(x_arr, fitting_func(para_6, x_arr), color="#13EAC9", label='五阶拟合曲线')  plt.scatter(x, y, color='#50BFFB', marker="p", label='原始数据')    plt.title("leastsq拟合", fontsize=13)  plt.xlabel('x', fontsize=13)  plt.ylabel('y', fontsize=13)  plt.legend(loc=4, fontsize=11)    # 指定legend的位置右下角  plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签  plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号  plt.show()
    这里我只输出了一阶的拟合结果,结果为:
    系数为: [ 0.5000123  29.77227653]多项式为:  0.5 x + 29.77拟合值为: [31.77232574 33.77237495 34.77239955 35.77242415 42.27258408 45.77267019		 51.27280552 58.77299004 61.27305155 64.27312537 69.27324839]拟合优度为: 0.5207874477394239
    结果图为:
    leasteq拟合

全部代码为:

from scipy.optimize import leastsq# 拟合数据集x = [4, 8, 10, 12, 25, 32, 43, 58, 63, 69, 79]y = [20, 33, 50, 56, 42, 31, 33, 46, 65, 75, 78]x_arr = np.array(x)y_arr = np.array(y)def fitting_func(p, x):    """    获得拟合的目标数据数组    :param p: array[int] 多项式各项从高到低的项的系数数组    :param x: array[int] 自变量数组    :return: array[int] 拟合得到的结果数组    """    f = np.poly1d(p)    # 获得拟合后得到的多项式    return f(x)         # 将自变量数组带入多项式计算得到拟合所得的目标数组def error_func(p, x, y):    """    计算残差    :param p: array[int] 多项式各项从高到低的项的系数数组    :param x: array[int] 自变量数组    :param y: array[int] 原始目标数组(因变量)    :return: 拟合得到的结果和原始目标的差值    """    err = fitting_func(p, x) - y    return errdef n_poly(n, x, y):    """    n 次多项式拟合函数    :param n: 多项式的项数(包括常数项),比如n=3的话最高次项为2次项    :return: 最终得到的系数数组    """    p_init = np.random.randn(n)   # 生成 n个随机数,作为各项系数的初始值,用于迭代修正    parameters = leastsq(error_func, p_init, args=(np.array(x), np.array(y)))    # 三个参数:误差函数、函数参数列表、数据点    return parameters[0]	# leastsq返回的是一个元组,元组的第一个元素时多项式系数数组[wn、...、w2、w1、w0]para_2 = n_poly(2, x_arr, y_arr)  # 一阶print("系数为:", para_2)print("多项式为:", np.poly1d(para_2))print("拟合值为:", fitting_func(para_2, x_arr))print("拟合优度为:", goodness_of_fit(fitting_func(para_2, x_arr), y_arr))para_3 = n_poly(3, x_arr, y_arr)  # 二阶para_4 = n_poly(4, x_arr, y_arr)  # 三阶para_5 = n_poly(5, x_arr, y_arr)  # 四阶para_6 = n_poly(6, x_arr, y_arr)  # 五阶figure2 = plt.figure(figsize=(8,6))plt.plot(x_arr, fitting_func(para_2, x_arr), color="#72CD28", label='一阶拟合曲线')plt.plot(x_arr, fitting_func(para_3, x_arr), color="#EBBD43", label='二阶拟合曲线')plt.plot(x_arr, fitting_func(para_4, x_arr), color="#50BFFB", label='三阶拟合曲线')plt.plot(x_arr, fitting_func(para_5, x_arr), color="gold", label='四阶拟合曲线')plt.plot(x_arr, fitting_func(para_6, x_arr), color="#13EAC9", label='五阶拟合曲线')plt.scatter(x_arr, y_arr, color='#50BFFB', marker="p", label='原始数据')plt.title("leastsq拟合", fontsize=13)plt.xlabel('x', fontsize=13)plt.ylabel('y', fontsize=13)plt.legend(loc=4, fontsize=11)    # 指定legend的位置右下角plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号plt.show()

转载地址:http://xfiwi.baihongyu.com/

你可能感兴趣的文章
写代码就像写作文
查看>>
常用shell特殊符号变量一览
查看>>
如何做事
查看>>
架构实践 - 1. 架构风格
查看>>
架构实践 - 3. 基于事件系统的demo
查看>>
架构实践 - 4. 架构设计之进程通信(独立构件风格)
查看>>
架构实践 - 5. 基于进程通信的demo
查看>>
sys/time.h 和 time.h的区别
查看>>
1、蓝牙概述
查看>>
2 系统架构师 - 知识框架
查看>>
Linux下 socket-tcp通信
查看>>
小米笔记本解决风扇异响
查看>>
Linux下 socket-udp通信
查看>>
Linux - 守护进程-1
查看>>
syslog 和 rsyslog
查看>>
Linux下,write/read,recv/send, recvfrom/sendto的区别
查看>>
ubuntu下 rc.local的脚本不运行
查看>>
Linux下简单Makefile文件的编写
查看>>
linux下配置JDK JAVA环境
查看>>
解决Ubuntu 14.04 grub选择启动项10秒等待时间
查看>>