天天看點

最小二乘法多項式曲線拟合原理與實作 zz     

 給定資料點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. 各點到這條曲線的距離之和,即偏差平方和如下:

                    .......

     4. 将等式左邊進行一下化簡,然後應該可以得到下面的等式:

                .......

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

     6. 将這個範德蒙得矩陣化簡後可得到:

     7. 也就是說 運作前提:

Python運作環境與編輯環境;

Matplotlib.pyplot圖形庫,可用于快速繪制2D圖表,與matlab中的plot指令類似,而且用法也基本相同。

# coding=utf-8  

''''' 

作者:Jairus Chan 

程式:多項式曲線拟合算法 

'''  

import matplotlib.pyplot as plt  

import math  

import numpy  

import random  

fig = plt.figure()  

ax = fig.add_subplot(111)  

#階數為9階  

order=9  

#生成曲線上的各個點  

x = numpy.arange(-1,1,0.02)  

y = [((a*a-1)*(a*a-1)*(a*a-1)+0.5)*numpy.sin(a*2) for a in x]  

#ax.plot(x,y,color='r',linestyle='-',marker='')  

#,label="(a*a-1)*(a*a-1)*(a*a-1)+0.5"  

#生成的曲線上的各個點偏移一下,并放入到xa,ya中去  

i=0  

xa=[]  

ya=[]  

for xx in x:  

    yy=y[i]  

    d=float(random.randint(60,140))/100  

    #ax.plot([xx*d],[yy*d],color='m',linestyle='',marker='.')  

    i+=1  

    xa.append(xx*d)  

    ya.append(yy*d)  

'''''for i in range(0,5): 

    xx=float(random.randint(-100,100))/100 

    yy=float(random.randint(-60,60))/100 

    xa.append(xx) 

    ya.append(yy)'''  

ax.plot(xa,ya,color='m',linestyle='',marker='.')  

#進行曲線拟合  

matA=[]  

for i in range(0,order+1):  

    matA1=[]  

    for j in range(0,order+1):  

        tx=0.0  

        for k in range(0,len(xa)):  

            dx=1.0  

            for l in range(0,j+i):  

                dx=dx*xa[k]  

            tx+=dx  

        matA1.append(tx)  

    matA.append(matA1)  

#print(len(xa))  

#print(matA[0][0])  

matA=numpy.array(matA)  

matB=[]  

    ty=0.0  

    for k in range(0,len(xa)):  

        dy=1.0  

        for l in range(0,i):  

            dy=dy*xa[k]  

        ty+=ya[k]*dy  

    matB.append(ty)  

matB=numpy.array(matB)  

matAA=numpy.linalg.solve(matA,matB)  

#畫出拟合後的曲線  

#print(matAA)  

xxa= numpy.arange(-1,1.06,0.01)  

yya=[]  

for i in range(0,len(xxa)):  

    yy=0.0  

        for k in range(0,j):  

            dy*=xxa[i]  

        dy*=matAA[j]  

        yy+=dy  

    yya.append(yy)  

ax.plot(xxa,yya,color='g',linestyle='-',marker='')  

ax.legend()  

plt.show()  

本文轉自莫水千流部落格園部落格,原文連結:http://www.cnblogs.com/zhoug2020/p/7628668.html,如需轉載請自行聯系原作者