当前位置:   article > 正文

从一开始的深度学习——线性回归篇_给予线性回归分析csdn

给予线性回归分析csdn

参考来源:

动手深度学习(第二版)

一、线性回归基本步骤和原理

1、引言

       回归regression)是能为一个或多个自变量与因变量之间关系建模的一类方法。而线性回归是一种利用线性模型对连续变量进行预测的方法,其中自变量和因变量之间存在线性关系。常见的例子包括:预测价格(房屋、股票等)、预测住院时间(针对住院病人等)、 预测需求(零售销量等)。

2、线性回归的优缺点

优点:

  1. 易于理解和实现:线性回归是最基础、最简单的回归方法之一,易于理解和实现。

  2. 适用范围广:线性回归可用于连续型数据预测和分析。它在统计学和机器学习中都有很广泛的应用,例如金融、医疗、物流和销售预测等领域。

  3. 可解释性强:由于其线性关系,线性回归得到的模型很容易进行解释。

  4. 鲁棒性强:线性回归模型对噪声有一定的鲁棒性,噪声不会导致太大的影响。

缺点:

  1. 对非线性关系敏感:线性回归对自变量与因变量之间存在明显的线性关系时表现很好,但当数据集呈现出复杂的非线性关系时就会遇到困难。

  2. 容易受离群点影响:离群点可以对线性回归结果产生较大的影响,对离群点的处理需要特别注意。离群点可能尤其需要在预处理阶段被去除。

  3. 受自相关、异方差和多重共线性等问题的影响:在某些情况下,线性回归分析可能会受到数据集中存在自相关、异方差和多重共线性等问题的影响而产生误差。

  4. 限制较大:线性回归适用于一些灵活程度较低的问题,如简单的拟合,然而对于一些需要更高灵活度的问题,线性模型就不再合适。

3、基本步骤

  • 收集数据:首先需要收集实际数据集,包含相关自变量和因变量。以预测房价为例,相应的数据可能包括房屋面积、楼层数、年龄、位置等信息和其对应房屋价格。
  • 数据处理:清洗、处理并探索这些数据,填充缺失值或者丢弃有问题的数据,剔除离群点,并且特征归一化等等。
  • 模型训练:使用线性回归模型(如最小二乘法)去拟合数据并计算出最优参数(θ_0 和θ_1等),因此 回归方程 Y = θ_0 + θ_1 * X 将会被确定下来。
  • 模型评估:将测试数据集带入模型计算后将得到预测结果,通过可视化方式,将模型预测结果和实际值进行比对来评估线性回归的预测能力。可以使用常用的指标,例如均方误差(MSE)、平均绝对误差(MAE)等来评估预测的准确性。
  • 模型应用:用训练好的模型去预测新的数据集的结果。

4、线性模型

       我们把试图预测的目标(比如预测房屋价格)称为标签(label)或目标(target)。 预测所依据的自变量(面积和房龄)称为特征(feature)或协变量(covariate)。通常,我们使用n来表示数据集中的样本数。 

                                    

         wi 称为权重(weight),权重决定了每个特征对我们预测值的影响。 b称为偏置(bias)、偏移量(offset)或截距(intercept)。 偏置是指当所有特征都取值为0时,预测值应该为多少。 即使现实中不会有任何房子的面积是0或房龄正好是0年,我们仍然需要偏置项。 如果没有偏置项,我们模型的表达能力将受到限制。线性回归模型是一个仿射函数,仿射变换的特点是通过加权和对特征进行线性变换(linear transformation), 并通过偏置项来进行平移(translation)。

         将上式中的wi向量放在一起形成矩阵X,X∈R(n×d),每一行是一个样本,每一列是一种特征。这时便可以得到矩阵-向量乘法表示的预测值推导式。在代码实现中,一般将偏置b合并到参数w中,合并方法是在包含所有参数的矩阵中附加一列。

                                               

5、损失函数 

         损失函数的作用是去确定一个拟合程度的度量,量化目标的实际值与预测值之间的差距。通常我们会选择非负数作为损失,且数值越小表示损失越小,完美预测时的损失为0。 回归问题中最常用的损失函数是平方误差函数。 当样本i的预测值为y^(i),其相应的真实标签为y(i)时, 平方误差可以定义为以下公式:

                                   

       这里的1/2用于之后求导使得常系数为1,为了计算方便。为了度量模型在整个数据集上的质量,我们需计算在训练集n个样本上的损失均值(也等价于求和)。白话来讲,就是求和后除以样本数,使得损失更加精确与科学。

        在训练模型时,我们希望寻找一组参数(w∗,b∗), 这组参数能最小化在所有训练样本上的总损失。

                                             

 6、解析解

       我们的目的是最小化‖y−Xw‖2。 这在损失平面上只有一个临界点,这个临界点对应于整个区域的损失极小点。 将损失关于w的导数设为0,得到解析解:

                                                 

7、随机梯度下降

        虽然解析解得到的式子十分简洁明了,但不是所有的模型都可以得到解析解。这时候我们就需要更加普遍性的方法——随机梯度下降法。这种方法几乎可以优化所有深度学习模型。 它通过不断地在损失函数递减的方向上更新参数来降低误差。

        在计算损失函数(数据集中所有样本的损失均值) 关于模型参数的导数(在这里也可以称为梯度)时,我们往往要遍历整个数据集,这会极大的增加我们的训练代价。所以我们在每次计算时只使用一小部分样本,这种方法称为小批量随机梯度下降。

算法的主体步骤为下:

(1)初始化模型参数的值,如随机初始化;

(2)从数据集中随机抽取小批量样本且在负梯度的方向上更新参数,并不断迭代这一步骤。

 |B|表示每个小批量中的样本数,这也称为批量大小(batch size)。 η表示学习率(learning rate)。 批量大小和学习率的值通常是手动预先指定,而不是通过模型训练得到的。 这些可以调整但不在训练过程中更新的参数称为超参数(hyperparameter)。调参(hyperparameter tuning)是选择超参数的过程。 超参数通常是我们根据训练迭代结果来调整的, 而训练迭代结果是在独立的验证数据集(validation dataset)上评估得到的。

调参的过程至关重要:

1、batchsize越大,在同样的训练数目的前提下,会减少训练的时间,提高计算的稳定性 ,训练出来的曲线更加平滑

2、batchsize越小,泛化的能力就会得到提升,因为适当的噪音能提高模型的鲁棒能力,减少出现过拟合的可能性。

3、学习率lr过大时 ,损失函数会出现震荡的现象,没法收束在一个定值,而取的过小的时候,训练代价又太大了

4、lr和batchsize大小正相关,对于一个固定的lr,存在一个最优的batchsize能够最大化测试精度。lr应该尽量稍大一些,更有利于提高泛化能力。

 梯度下降法的具体推导可以看这篇博客:

随机梯度下降法(stochastic gradient descent,SGD)_柠檬上神的博客-CSDN博客

8、评估方法

 PR曲线,ROC曲线

9.代码实现

原理复杂版版

  1. import random
  2. import torch
  3. from d2l import torch as d2l
  4. def synthetic_data(w, b, num_examples): #@save
  5. """生成y=Xw+b+噪声"""
  6. X = torch.normal(0, 1, (num_examples, len(w)))
  7. y = torch.matmul(X, w) + b
  8. y += torch.normal(0, 0.01, y.shape)
  9. return X, y.reshape((-1, 1))
  10. true_w = torch.tensor([2, -3.4])
  11. true_b = 4.2
  12. features, labels = synthetic_data(true_w, true_b, 1000)
  13. print('features:', features[0],'\nlabel:', labels[0])
  14. d2l.set_figsize()
  15. d2l.plt.scatter(features[:, 1].detach().numpy(), labels.detach().numpy(), 1);
  16. def data_iter(batch_size, features, labels):
  17. num_examples = len(features)
  18. indices = list(range(num_examples))
  19. # 这些样本是随机读取的,没有特定的顺序
  20. random.shuffle(indices)
  21. for i in range(0, num_examples, batch_size):
  22. batch_indices = torch.tensor(
  23. indices[i: min(i + batch_size, num_examples)])
  24. yield features[batch_indices], labels[batch_indices]
  25. batch_size = 10
  26. for X, y in data_iter(batch_size, features, labels):
  27. print(X, '\n', y)
  28. break
  29. w = torch.normal(0, 0.01, size=(2,1), requires_grad=True)
  30. b = torch.zeros(1, requires_grad=True)
  31. def linreg(X, w, b): #@save
  32. """线性回归模型"""
  33. return torch.matmul(X, w) + b
  34. def squared_loss(y_hat, y): #@save
  35. """均方损失"""
  36. return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2
  37. def sgd(params, lr, batch_size): #@save
  38. """小批量随机梯度下降"""
  39. with torch.no_grad():
  40. for param in params:
  41. param -= lr * param.grad / batch_size
  42. param.grad.zero_()
  43. lr = 0.03
  44. num_epochs = 3
  45. net = linreg
  46. loss = squared_loss
  47. for epoch in range(num_epochs):
  48. for X, y in data_iter(batch_size, features, labels):
  49. l = loss(net(X, w, b), y) # X和y的小批量损失
  50. # 因为l形状是(batch_size,1),而不是一个标量。l中的所有元素被加到一起,
  51. # 并以此计算关于[w,b]的梯度
  52. l.sum().backward()
  53. sgd([w, b], lr, batch_size) # 使用参数的梯度更新参数
  54. with torch.no_grad():
  55. train_l = loss(net(features, w, b), labels)
  56. print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')
  57. print(f'w的估计误差: {true_w - w.reshape(true_w.shape)}')
  58. print(f'b的估计误差: {true_b - b}')

调库简单版

  1. import numpy as np
  2. import torch
  3. from torch.utils import data
  4. from d2l import torch as d2l
  5. true_w = torch.tensor([2, -3.4])
  6. true_b = 4.2
  7. features, labels = d2l.synthetic_data(true_w, true_b, 1000)
  8. def load_array(data_arrays, batch_size, is_train=True): #@save
  9. """构造一个PyTorch数据迭代器"""
  10. dataset = data.TensorDataset(*data_arrays)
  11. #每次从dataset随机挑选batch个样本
  12. return data.DataLoader(dataset, batch_size, shuffle=is_train)
  13. batch_size = 10
  14. #做成一个list
  15. data_iter = load_array((features, labels), batch_size)
  16. # nn是神经网络的缩写
  17. from torch import nn
  18. #输入维度2和输出维度1
  19. net = nn.Sequential(nn.Linear(2, 1))
  20. #使用正态分布来替换掉data的值
  21. net[0].weight.data.normal_(0, 0.01)
  22. #偏差设为0
  23. net[0].bias.data.fill_(0)
  24. #定义损失函数
  25. loss = nn.MSELoss()
  26. #net.parameters为所有参数w和b,随机梯度下降法
  27. trainer = torch.optim.SGD(net.parameters(), lr=0.03)
  28. num_epochs = 3
  29. for epoch in range(num_epochs):
  30. for X, y in data_iter:
  31. l = loss(net(X) ,y)
  32. #梯度清零
  33. trainer.zero_grad()
  34. l.backward()
  35. #模型更新
  36. trainer.step()
  37. l = loss(net(features), labels)
  38. print(f'epoch {epoch + 1}, loss {l:f}')
  39. w = net[0].weight.data
  40. print('w的估计误差:', true_w - w.reshape(true_w.shape))
  41. b = net[0].bias.data
  42. print('b的估计误差:', true_b - b)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/360432
推荐阅读
相关标签
  

闽ICP备14008679号