其中a = 0.5, b = 3。我们选取高斯噪声标准差为5,通过如下代码模拟数据并绘制二维散点图:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize
a = 0.5 # coefficient
b = 3 # intercept
noiseVar = 1 # noise的标准差
x = np.arange(1, 100, 0.1)
# generate data
y = a * x + b + noiseVar* np.random.randn(x.size)
print(x.size)
plt.plot(x, y, 'o', color='r')
def lossfun(params):
# params是个(2,)的数组, 第一个是斜率,第二个是截距
a = params[0]
b = params[1]
y_pred = a * x + b
return ((y-y_pred)**2).sum() # 计算squared error作为损失函数
随后我们来最优化这个损失函数:
from scipy.optimize import minimize
res = minimize(fun=lossfun, x0=(1, 1))
print('Linear coefficient is', res.x[0])
print('Intercept is', res.x[1])
结果显示a = 0.5009765933689194, b = 2.9547084373733297。这个数值解与我们的真模型的参数已经非常相近了。
x2 = np.vstack((x, np.ones(x.size))) # x2的第二排都是1
# 因为numpy都是横向量,我们划成列向量
x2 = x2.T # x2 is 99 x 2
y_hat = y[:, np.newaxis].copy() # y is 99 x 1
res = np.linalg.inv(x2.T @ x2) @ x2.T @ y_hat
print('Coefficient is ',res[0][0])
print('Intercept is ',res[1][0])
结果显示a = 0.5009766233665898, b = 2.954706934764938。可以看到,这个结果同样也是比较精确的。
方法三:利用算法包直接求解。
有些算法包已经提供了对于特定模型的专用优化函数,我们可以直接调用这些函数来得到最优解。
具体操作步骤如下:
x2 = np.vstack((x, np.ones(x.size))) # x2的第二排都是1
# 利用lstsq函数求解
res = np.linalg.lstsq(x2.T, y, rcond=None)[0]
print('Coefficient is ',res[0])
print('Intercept is ',res[1])
结果显示a = 0.5009766233665904, b = 2.9547069347648884。同样得到了较为不错的结果。