Ubuntu Zookeeper 设计模式 Linux软件安装 Synchnorized 程序设计 LeetCode php pdf nginx视频教程 angularjs教程 jq遍历对象 jquery获取dom对象 svn默认安装路径 linux查看mysql进程 base64转16进制 mysql汉化包 centos查看python版本 java上传图片 idea开发python linux重启mysql mysql学习 python搭建环境 python中index的用法 python安装 java得到当前时间 java架构 javascript实例 groupby 摩斯电码翻译器 java分布式开发 刷机工具下载 js数组移除指定元素 3dmax插件神器 三维看图软件 ip地址转换器 mysql时间比较 圆角矩形工具改变弧度 ppt格式刷怎么用 c4d挤压
当前位置: 首页 > 学习教程  > 编程语言

数学建模方法 — 【05】 拟合方法之leastsq

2020/8/31 13:16:24 文章标签:

拟合方法——leastsq

1. 概念:

scipy官网对该方法介绍是: 最小化一组方程的平方和
x=argminy(((func(y))2axis=0))x =\arg \min\limits_{y}(\sum((func(y))^2,axis=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(x3)2+12(x-3)^2+1的最小值:

from scipy.optimize import leastsq

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

结果为:

(array([2.99999999]), 1)

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

2. 拟合

为了和上一篇文章数学建模方法—【04】拟合方法之np.polyfit、np.poly1d形成一个比较,我们这里也进行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) - y
    return 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在我前面的文章有: 数学建模方法—【03】拟合优度的计算(python计算))
    一阶
    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表示的不是多项式的阶数,而是表示多项式的项数,比如二阶的多项式有x2xx^2、x还有常数项三项,所以传入的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拟合

本文链接: http://www.dtmao.cc/news_show_150067.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?