一元线性回归
线性模型试图学得一个通过属性的线性组合来进行预测的函数。
使用向量形式可表示为
f(x)=wTx+b
这里需要注意的是,线性模型可以是用曲线拟合样本,但是分类的决策边界一定是直线的,例如logistics模型。
原理
线性回归试图学得
f(xi)=wxi+b, 使得f(xi)≈yi
这里引入均方误差**(MSE)**来对回归任务的性能进行度量,通过让MSE最小使预测值尽可能接近真实值。如公式2所示
(w∗,b∗)=argw,bmin2m1i=1∑m(wxi+b−yi)2
均方误差有非常好的几何意义。它对应了"欧氏距离" (Euclidean distance)。基于均方误差最小化来进行模型求解的方法称为"最小二乘法" 。
在线性回归中,最小二乘法就是试图找到一条直线,使所有样本到直线上的欧氏距离之和最小。
∂w∂E(w,b)=i=1∑m2(wxi+b−yi)xi=2(wi=1∑mxi2−i=1∑m(yi−b)xi)
∂b∂E(w,b)=i=1∑m2(wxi+b−yi)=2(wi=1∑mxi+mb−i=1∑myi)
我们对参数w和b求导,即式(3)(4),然后使导数为0求得最优解。
实现
这里我们使用租金预测的数据集举例(关于数据集的情况可以查看回归综述的文章):
1 2 3 4
| x_data = np.array([[1.0], [2.0], [3.0]]) y_data = np.array([[2.0], [4.0], [6.0]])
|
使用sklearn进行一元线性回归:
1 2 3 4 5 6 7 8 9 10
| from sklearn import linear_model import numpy as np model = linear_model.LinearRegression() x_data = np.array([[1.0], [2.0], [3.0]]) y_data = np.array([[2.0], [4.0], [6.0]]) model.fit(x_data, y_data) print("w=",model.intercept_[0]) print("b=",model.coef_[0][0]) a = model.predict([[12]]) print("预测结果为:{:.5f}".format(model.predict([[4.0]])[0][0]))
|
输出情况:
1 2 3
| w= 1.3322676295501878e-15 b= 1.9999999999999993 预测结果为:8.00000
|
使用Pytorch进行一元线性回归
步骤
使用Pytorch构建线性模型主要分为以下4步,这4步也是未来构建复杂模型的基础。
- 处理数据集
- 使用Class定义模型
- 定义损失和优化器
- 进行迭代(前向,反向,更新)
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import torch
x_data = torch.Tensor([[1.0], [2.0], [3.0]]) y_data = torch.Tensor([[2.0], [4.0], [6.0]])
class LinearModel(torch.nn.Module): def __init__(self): super(LinearModel, self).__init__() self.linear = torch.nn.Linear(1, 1) def forward(self, x): y_pred = self.linear(x) return y_pred model = LinearModel()
criterion = torch.nn.MSELoss(reduction="sum") optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
for epoch in range(1000): y_pred = model(x_data) loss = criterion(y_pred, y_data) if epoch%100 == 0: print(epoch, loss.item()) optimizer.zero_grad() loss.backward() optimizer.step() print('w = ', model.linear.weight.item()) print('b = ', model.linear.bias.item()) x_test = torch.Tensor([[4.0]]) y_test = model(x_test) print('y_pred = ', y_test.data)
|
输出情况:
0 45.2210693359375
100 0.16480454802513123
200 0.0387517511844635
300 0.00911199301481247
400 0.0021425874438136816
500 0.0005037992377765477
600 0.00011845995322801173
700 2.7853518986376002e-05
800 6.548188139277045e-06
900 1.5404962141474243e-06
w = 1.9995964765548706
b = 0.0009174233418889344
y_pred = tensor([[7.9993]])
上述代码构建了一个完整的线性模型,并进行回归预测任务。这里有几个需要注意的地方:
- 构建模型类时需要继承torch.nn.Module.这个类是 PyTorch 中所有 neural network module 的基类,
自己创建的网络模型都是这个类的子类。
- 在子类中要实现init和forward这两个函数,其余函数可以暂不实现。
- 反向传播前要对梯度进行清0,否则梯度会累积
参考
- 周志华-《机器学习》
- B站-《PyTorch深度学习实践》