zoukankan      html  css  js  c++  java
  • 最小二乘法多项式曲线拟合原理与实现

    概念

    最小二乘法多项式曲线拟合,根据给定的m个点,并不要求这条曲线精确地经过这些点,而是曲线y=f(x)的近似曲线y= φ(x)。

    原理

    [原理部分由个人根据互联网上的资料进行总结,希望对大家能有用]

         给定数据点pi(xi,yi),其中i=1,2,…,m。求近似曲线y= φ(x)。并且使得近似曲线与y=f(x)的偏差最小。近似曲线在点pi处的偏差δi= φ(xi)-y,i=1,2,...,m。 

    常见的曲线拟合方法:

         1.使偏差绝对值之和最小

         

         2.使偏差绝对值最大的最小

         

         3.使偏差平方和最小

         

         按偏差平方和最小的原则选取拟合曲线,并且采取二项式方程为拟合曲线的方法,称为最小二乘法。

    推导过程:

         1. 设拟合多项式为:

              

         2. 各点到这条曲线的距离之和,即偏差平方和如下:

              

         3. 为了求得符合条件的a值,对等式右边求ai偏导数,因而我们得到了: 

              

              

                             .......

              

         4. 将等式左边进行一下化简,然后应该可以得到下面的等式:

              

              

                         .......

              

         5. 把这些等式表示成矩阵的形式,就可以得到下面的矩阵:

              

         6. 将这个范德蒙得矩阵化简后可得到:

              

         7. 也就是说X*A=Y,那么A = (X'*X)-1*X'*Y,便得到了系数矩阵A,同时,我们也就得到了拟合曲线。

    实现

    运行前提:

    1. Python运行环境与编辑环境;
    2. Matplotlib.pyplot图形库,可用于快速绘制2D图表,与matlab中的plot命令类似,而且用法也基本相同。

    代码:

     1     # coding=utf-8  
     2       
     3     ''''' 
     4     程序:多项式曲线拟合算法 
     5     '''  
     6     import matplotlib.pyplot as plt  
     7     import math  
     8     import numpy  
     9     import random  
    10       
    11     fig = plt.figure()  
    12     ax = fig.add_subplot(111)  
    13       
    14     #阶数为9阶  
    15     order=9  
    16       
    17     #生成曲线上的各个点  
    18     x = numpy.arange(-1,1,0.02)  
    19     y = [((a*a-1)*(a*a-1)*(a*a-1)+0.5)*numpy.sin(a*2) for a in x]  
    20     #ax.plot(x,y,color='r',linestyle='-',marker='')  
    21     #,label="(a*a-1)*(a*a-1)*(a*a-1)+0.5"  
    22       
    23     #生成的曲线上的各个点偏移一下,并放入到xa,ya中去  
    24     i=0  
    25     xa=[]  
    26     ya=[]  
    27     for xx in x:  
    28         yy=y[i]  
    29         d=float(random.randint(60,140))/100  
    30         #ax.plot([xx*d],[yy*d],color='m',linestyle='',marker='.')  
    31         i+=1  
    32         xa.append(xx*d)  
    33         ya.append(yy*d)  
    34       
    35     '''''for i in range(0,5): 
    36         xx=float(random.randint(-100,100))/100 
    37         yy=float(random.randint(-60,60))/100 
    38         xa.append(xx) 
    39         ya.append(yy)'''  
    40       
    41     ax.plot(xa,ya,color='m',linestyle='',marker='.')  
    42       
    43       
    44     #进行曲线拟合  
    45     matA=[]  
    46     for i in range(0,order+1):  
    47         matA1=[]  
    48         for j in range(0,order+1):  
    49             tx=0.0  
    50             for k in range(0,len(xa)):  
    51                 dx=1.0  
    52                 for l in range(0,j+i):  
    53                     dx=dx*xa[k]  
    54                 tx+=dx  
    55             matA1.append(tx)  
    56         matA.append(matA1)  
    57       
    58     #print(len(xa))  
    59     #print(matA[0][0])  
    60     matA=numpy.array(matA)  
    61       
    62     matB=[]  
    63     for i in range(0,order+1):  
    64         ty=0.0  
    65         for k in range(0,len(xa)):  
    66             dy=1.0  
    67             for l in range(0,i):  
    68                 dy=dy*xa[k]  
    69             ty+=ya[k]*dy  
    70         matB.append(ty)  
    71        
    72     matB=numpy.array(matB)  
    73       
    74     matAA=numpy.linalg.solve(matA,matB)  
    75       
    76     #画出拟合后的曲线  
    77     #print(matAA)  
    78     xxa= numpy.arange(-1,1.06,0.01)  
    79     yya=[]  
    80     for i in range(0,len(xxa)):  
    81         yy=0.0  
    82         for j in range(0,order+1):  
    83             dy=1.0  
    84             for k in range(0,j):  
    85                 dy*=xxa[i]  
    86             dy*=matAA[j]  
    87             yy+=dy  
    88         yya.append(yy)  
    89     ax.plot(xxa,yya,color='g',linestyle='-',marker='')  
    90       
    91     ax.legend()  
    92     plt.show()

    运行效果: 

     

     

    本文参考自http://blog.csdn.net/JairusChan

  • 相关阅读:
    LeetCode 83. Remove Duplicates from Sorted List (从有序链表中去除重复项)
    LeetCode 21. Merge Two Sorted Lists (合并两个有序链表)
    LeetCode 720. Longest Word in Dictionary (字典里最长的单词)
    LeetCode 690. Employee Importance (职员的重要值)
    LeetCode 645. Set Mismatch (集合不匹配)
    LeetCode 500. Keyboard Row (键盘行)
    LeetCode 463. Island Perimeter (岛的周长)
    115.Distinct Subsequences
    55.Jump Game
    124.Binary Tree Maximum Path Sum
  • 原文地址:https://www.cnblogs.com/ECJTUACM-873284962/p/6838781.html
Copyright © 2011-2022 走看看