python-最小二乘法-拟合非线性函数

需要补充知识:

  最小二乘法——非线性拟合推导

 

 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)

 

posted @ 2021-03-21 19:26  墨鳌  阅读(814)  评论(0编辑  收藏  举报