最小二乘法-非线性拟合-正则化-python实现
需要一些数学推导
Lambda的确定不太清楚,0.001是试出来的
当函数发生变化时,或者拟合函数最高系数变化时,Lambda的取值都应当相应变化
1 import numpy as np 2 import matplotlib.pyplot as plt 3 4 plt.rcParams['font.sans-serif'] = ['SimHei'] 5 plt.rcParams['axes.unicode_minus'] = False 6 # 处理中文乱码 7 8 9 def init_fx_data(): 10 X = np.arange(0, 1, 0.1) 11 Y = [np.sin(2.0*np.pi*x) + (np.random.randint(low=-30, high=30) / 100) for x in X] 12 return X, Y 13 14 15 def filling_X_Y(xs, ys, m): 16 X, Y = [], [] 17 for x in xs: 18 row = [x ** (i + 1) for i in range(m)] 19 X.append(row) 20 for y in ys: 21 Y.append(y) 22 return np.array(X), np.array(Y) 23 24 25 def draw_figure(xs, ys, A, n): 26 p = plt.figure().add_subplot(111) 27 X, Y = np.arange(min(xs), max(xs), 0.01), [] 28 for i in range(0, len(X)): 29 y = 0.0 30 for k in range(0, n): 31 y += A[k] * X[i] ** (k + 1) 32 Y.append(y) 33 p.plot(X, Y, color='r', linestyle='-', marker='', label='多项式拟合曲线') 34 p.plot(xs, ys, color='b', linestyle='', marker='.', label='曲线真实数据') 35 plt.title(s='最小二乘法拟合多项式N={}的函数曲线f(x)'.format(n)) 36 plt.legend(loc="best") # 添加默认图例到合适位置 37 plt.show() 38 39 40 if __name__ == '__main__': 41 x, y = init_fx_data() 42 order = 10 43 Lambda = 0.001 44 X, Y = filling_X_Y(x, y, order) 45 46 W1 = np.linalg.inv(X.T @ X) @ X.T @ Y 47 P1 = draw_figure(x, y, W1, order) 48 49 W2 = np.linalg.inv(X.T @ X + Lambda * np.eye(order)) @ X.T @ Y 50 P2 = draw_figure(x, y, W2, order)
~~Jason_liu O(∩_∩)O