需要补充知识:
最小二乘法——非线性拟合推导
1 import numpy as np 2 import matplotlib.pyplot as plt 3 4 5 plt.rcParams['font.sans-serif'] = ['SimHei'] 6 plt.rcParams['axes.unicode_minus'] = False 7 # 处理中文乱码 8 9 10 def init_fx_data(): 11 # f(x)=x^(cosx-0.5) 12 X=np.arange(0,15,0.1) # [0,15) step=0.05 即:300个横坐标 13 I=[np.cos(x)-0.5 for x in X] # index指数 14 Y=np.float_power(X,I) 15 noise=[(np.random.randint(low=-15,high=15)/100) for x in X] 16 Y+=noise 17 return X,Y 18 19 20 def LS_Gaussian(xs,ys,n): 21 X,Y=[],[] 22 for i in range(0,n+1): 23 x_row=[] 24 for j in range(0,n+1): 25 sum=0.0 26 for x in xs: 27 sum+=x**(i+j) 28 x_row.append(sum) 29 X.append(x_row) 30 for i in range(0,n+1): 31 sum=0.0 32 for j in range(len(xs)): 33 sum+=(xs[j]**(i))*ys[j] 34 Y.append(sum) 35 A=np.linalg.solve(np.array(X),np.array((Y))) 36 # 求解XA=Y 37 # 可以写高斯消元,这里调用numpy自带函数 38 return A 39 40 41 def draw_figure(xs,ys,A,n): 42 result_figure=plt.figure().add_subplot(111) 43 X,Y=np.arange(min(xs),max(xs),0.01),[] 44 for i in range(0, len(X)): 45 y=0.0 46 for k in range(0,n+1): 47 y+=A[k]*X[i]**k 48 Y.append(y) 49 result_figure.plot(X,Y,color='r',linestyle='-',marker='',label='多项式拟合曲线') 50 result_figure.plot(xs,ys,color='b',linestyle='',marker='.',label='曲线真实数据') 51 plt.title(s='最小二乘法拟合多项式N={}的函数曲线f(x)'.format(n)) 52 plt.legend(loc="best") # 添加默认图例到合适位置 53 plt.show() 54 55 56 if __name__ == '__main__': 57 X,Y=init_fx_data() 58 order=36 #拟合的多项式项数 59 A=LS_Gaussian(X,Y,order) 60 draw_figure(X,Y,A,order)