一、线性回归介绍

学习目标:

1.理解线性回归是什么?

2.知道一元线性回归和多元线性回归的区别

3.知道线性回归的应用场景

举个栗子

假若有了身高和体重数据,有了牛仔的身高,你能预测播仔体重吗?

这是一个回归问题,该如何求解呢?

思路:先从已知身高X和体重Y中找规律,再预测

•数学问题:用一条线来拟合身高和体重之间的关系,再对新数据进行预测

方程 Y = kX + b

k160 + b = 56.3 – (1)

k166 + b = 60.6 –- (2)

。。。。

k: 斜率 b:截距

若:y = 0.9 x + (-93)

​ 0.9*176 +(-93)= ?

线性回归

线性回归(Linear regression)是利用 回归方程(函数)一个或多个自变量(特征值)和因变量(目标值)之间 关系进行建模的一种分析方式。

在这里插入图片描述
在这里插入图片描述

注意事项:

1 为什么叫线性模型?因为求解的w,都是w的零次幂(常数项)所以叫成线性模型

2 在线性回归中,从数据中获取的规律其实就是学习权重系数w

3 某一个权重值w越大,说明这个权重的数据对房子价格影响越大

线性回归分类

  • 一元线性回归

    • y = kx +b

目标值只与一个因变量有关系

在这里插入图片描述

  • 多元线性回归

在这里插入图片描述

目标值只与多个因变量有关系

在这里插入图片描述

应用场景

在这里插入图片描述

二、线性回归问题的求解

学习目标:

1.知道线性回归API的使用

2.知道损失函数是什么

3.复习导数和矩阵的相关内容

4.理解正规方程法

5.掌握梯度下降算法的内容

线性回归API的应用

预测牛仔身高

已知数据:

在这里插入图片描述

需求:牛仔身高是176,请预测体重?
在这里插入图片描述

# 1- 导包
from sklearn.linear_model import LinearRegression # 线性回归

if __name__ == '__main__':
    # 2- 准备数据
    x = [[160],[166],[172],[174],[180]]
    y = [56.3,60.6,65.1,68.5,75]

    # 3- 创建线性回归的实例化对象
    """
        fit_intercept:是否是要得到截距。默认需要也即是True
    """
    estimator = LinearRegression(fit_intercept=True)

    # 4- 训练模型
    estimator.fit(x, y)

    # 4.1- 查看斜率和解决
    print("斜率是:",estimator.coef_)
    print("截距是:",estimator.intercept_)

    # 5- 使用训练好的模型对未知数据进行预测
    x_unknown = [[176]]
    y_predict = estimator.predict(x_unknown)

    print(f"预测的牛仔体重是:{y_predict}")

通过线性回归API可快速的找到一条红色直线,是怎么求解的呢?

在这里插入图片描述

损失函数

需要设置一个评判标准

在这里插入图片描述

误差概念:用预测值y – 真实值y就是误差

损失函数:衡量每个样本预测值与真实值效果的函数

“红色直线能更好的拟合所有点”也就是误差最小,误差和最小

损失函数数学如何表达呢?又如何求损失函数的最小值呢?
在这里插入图片描述
当损失函数取最小值时,得到k就是最优解

在这里插入图片描述

想求一条直线更好的拟合所有点 y = kx + b

  • ​ 引入损失函数(衡量预测值和真实值效果) Loss(k, b)

  • ​ 通过一个优化方法,求损失函数最小值,得到K最优解

回归的损失函数:

  • 均方误差 (Mean-Square Error, MSE)

  • 平均绝对误差 (Mean Absolute Error , MAE)

在这里插入图片描述

导数和矩阵

常见的数据表述
  • 为什么要学习标量、向量、矩阵、张量?
    • 因机器学习、深度学习中经常用,不要因是数学就害怕
    • 宗旨:用到就学什么,不要盲目的展开、大篇幅学数学
  • 标量scalar :一个独立存在的数,只有大小没有方向
  • 向量vector :向量指一列顺序排列的元素。默认是列向量
    在这里插入图片描述

在这里插入图片描述

  • 矩阵matrix :二维数组

    在这里插入图片描述

  • 张量Tensor :多维数组,张量是基于向量和矩阵的推广

    在这里插入图片描述

导数

当函数y=f(x)的自变量x在一点x0x_0x0上产生一个增量Δx时,函数输出值的增量Δy与自变量增量Δx的比值在Δx趋于0时的极限a如果存在,a即为在x0x_0x0处的导数,记作f′(x0)f^\prime(x_0)f(x0)或df(x0x_0x0)/dx。

导数是函数的局部性质。一个函数在某一点的导数描述了这个函数在这一点附近的变化率。

函数在某一点的导数就是该函数所代表的曲线在这一点上的切线斜率

常见函数的导数:

在这里插入图片描述

导数的四则运算:

在这里插入图片描述

复合函数求导:g(h)是外函数 h(x)是内函数。先对外函数求导,再对内函数求导

导数求极值:导数为0的位置是函数的极值点

偏导

在这里插入图片描述

向量

向量运算:

在这里插入图片描述

矩阵

在这里插入图片描述
在这里插入图片描述

梯度下降算法

【掌握】梯度下降算法思想

什么是梯度下降法

• 求解函数极值还有更通用的方法就是梯度下降法。顾名思义:沿着梯度下降的方向求解极小值 • 举个例子:坡度最陡下山法

在这里插入图片描述

  • 输入:初始化位置S;每步距离为a 。输出:从位置S到达山底
  • 步骤1:令初始化位置为山的任意位置S
  • 步骤2:在当前位置环顾四周,如果四周都比S高返回S;否则执行步骤3
  • 步骤3: 在当前位置环顾四周,寻找坡度最陡的方向,令其为x方向
  • 步骤4:沿着x方向往下走,长度为a,到达新的位置S‘
  • 步骤5:在S‘位置环顾四周,如果四周都比S‘高,则返回S‘。否则转到步骤3

小结:通过循环迭代的方法不断更新位置S (相当于不断更新权重参数w)

梯度下降过程就和下山场景类似
可微分的损失函数,代表着一座山
寻找的函数的最小值,也就是山底

三、回归评估方法

学习目标:

1.掌握常用的回归评估方法

2.了解不同评估方法的特点

为什么要进行线性回归模型的评估

我们希望衡量预测值和真实值之间的差距,

会用到MAE、MSE、RMSE多种测评函数进行评价

平均绝对误差

Mean Absolute Error (MAE)

在这里插入图片描述

  • 上面的公式中:n 为样本数量, y 为实际值, y^\hat{y}y^ 为预测值

  • MAE 越小模型预测约准确

Sklearn 中MAE的API

from sklearn.metrics import mean_absolute_error
mean_absolute_error(y_test,y_predict)

均方误差

Mean Squared Error (MSE)

在这里插入图片描述

  • 上面的公式中:n 为样本数量, y 为实际值, y^\hat{y}y^ 为预测值
  • MSE 越小模型预测约准确

Sklearn 中MSE的API

from sklearn.metrics import mean_squared_error
mean_squared_error(y_test,y_predict)

均方根误差

Root Mean Squared Error (RMSE)

在这里插入图片描述

  • 上面的公式中:n 为样本数量, y 为实际值, y^\hat{y}y^ 为预测值
  • RMSE 越小模型预测约准确

三种指标的比较

我们绘制了一条直线 y = 2x +5 用来拟合 y = 2x + 5 + e. 这些数据点,其中e为噪声

在这里插入图片描述

从上图中我们发现 MAE 和 RMSE 非常接近,都表明模型的误差很低(MAE 或 RMSE 越小,误差越小!)。 但是MAE 和 RMSE 有什么区别?为什么MAE较低?

  • 对比MAE 和 RMSE的公式,RMSE的计算公式中有一个平方项,因此:大的误差将被平方,因此会增加 RMSE 的值

  • 可以得出结论,RMSE 会放大预测误差较大的样本对结果的影响,而 MAE 只是给出了平均误差

  • 由于 RMSE 对误差的 平方和求平均 再开根号,大多数情况下RMSE>MAE

    举例 (1+3)/2 = 2 (12+32)/2=10/2=5=2.236\sqrt{(1^2+3^2)/2 }= \sqrt{10/2} = \sqrt{5} = 2.236(12+32)/2 =10/2 =5 =2.236

我们再看下一个例子

在这里插入图片描述

橙色线与第一张图中的直线一样:y = 2x +5

蓝色的点为: y = y + sin(x)*exp(x/20) + e 其中 exp() 表示指数函数

我们看到对比第一张图,所有的指标都变大了,RMSE 几乎是 MAE 值的两倍,因为它对预测误差较大的点比较敏感

我们是否可以得出结论: RMSE是更好的指标? 某些情况下MAE更有优势,例如:

  • 假设数据中有少数异常点偏差很大,如果此时根据 RMSE 选择线性回归模型,可能会选出过拟合的模型来
  • 在这种情况下,由于数据中的异常点极少,选择具有最低 MAE 的回归模型可能更合适
  • 除此之外,当两个模型计算RMSE时数据量不一致,也不适合在一起比较

四、波士顿房价预测案例

线性回归API

sklearn.linear_model.LinearRegression(fit_intercept=True)
  • 通过正规方程优化
  • 参数:fit_intercept,是否计算偏置
  • 属性:LinearRegression.coef_ (回归系数) LinearRegression.intercept_(偏置)
sklearn.linear_model.SGDRegressor(loss="squared_loss", fit_intercept=True, learning_rate ='constant', eta0=0.01)
  • 参数:loss(损失函数类型),fit_intercept(是否计算偏置)learning_rate (学习率)
  • 属性:SGDRegressor.coef_ (回归系数)SGDRegressor.intercept_ (偏置)

波士顿房价预测

案例背景介绍

数据介绍
在这里插入图片描述

在这里插入图片描述

给定的这些特征,是专家们得出的影响房价的结果属性。我们此阶段不需要自己去探究特征是否有用,只需要使用这些特征。到后面量化很多特征需要我们自己去寻找

案例分析

回归当中的数据大小不一致,是否会导致结果影响较大。所以需要做标准化处理。

  • 数据分割与标准化处理
  • 回归预测
  • 线性回归的算法效果评估
回归性能评估

均方误差(Mean Squared Error, MSE)评价机制:

MSE=1m∑i=1m(yi−y^)2\Large MSE = \frac{1}{m}\sum_{i=1}^{m}(y^i-\hat{y})^2MSE=m1i=1m(yiy^)2

sklearn中的API:sklearn.metrics.mean_squared_error(y_true, y_pred)

  • 均方误差回归损失
  • y_true:真实值
  • y_pred:预测值
  • return:浮点数结果
代码实现
# -*- coding: utf-8 -*-
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.linear_model import SGDRegressor


def linear_model_equation():
    """
    任务需求:通过线性回归预测波士顿房价
    数据源:波士顿房价数据源
    实现步骤:
        1.导包
        2.加载数据集并进行划分
        3.特征工程-标准化
        4.模型实例化并训练(使用解析方法,解方程求解模型参数)
        5.模型预测与评价
    """
    # 1.导包
    # 2.加载数据集并进行划分
    # 2.1加载数据集
    boston_data = load_boston()
    # 2.2数据集划分
    X = boston_data.data
    y = boston_data.target
    x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=22)
    # 3.特征工程-标准化
    # 3.1实例化
    scaler = StandardScaler()
    # 3.2训练集标准化
    x_train = scaler.fit_transform(x_train)
    # 3.3测试集标准化
    x_test = scaler.transform(x_test)
    # 4.模型实例化并训练
    # 4.1模型实例化
    model = LinearRegression()
    # 4.2模型训练
    model.fit(x_train, y_train)
    # 5.模型评价与预测
    # 5.1 查看模型参数
    print(f"线性回归模型的coef:{model.coef_}")
    print(f"线性回归模型的intercept:{model.intercept_}")
    # 5.2模型预测
    y_pred = model.predict(x_test)
    print(f"模型在测试集上的预测结果为:{y_pred}")
    # 5.3模型评价-计算均方误差
    mse = mean_squared_error(y_test, y_pred)
    print(f"模型在测试集上的均方误差为:{mse}")


def linear_model_numerical():
    """
    任务需求:通过线性回归预测波士顿房价
    数据源:波士顿房价数据源
    实现步骤:
        1.导包
        2.加载数据集并进行划分
        3.特征工程-标准化
        4.模型实例化并训练(使用数值方法,利用随机梯度下降法求解模型参数)
        5.模型预测与评价
    """
    # 1.导包
    # 2.加载数据集并进行划分
    # 2.1加载数据集
    boston_data = load_boston()
    # 2.2数据集划分
    X = boston_data.data
    y = boston_data.target
    x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=22)
    # 3.特征工程-标准化
    # 3.1实例化
    scaler = StandardScaler()
    # 3.2训练集标准化
    x_train = scaler.fit_transform(x_train)
    # 3.3测试集标准化
    x_test = scaler.transform(x_test)
    # 4.模型实例化并训练
    # 4.1模型实例化
    model = SGDRegressor()
    # 4.2模型训练
    model.fit(x_train, y_train)
    # 5.模型评价与预测
    # 5.1 查看模型参数
    print(f"线性回归模型的coef:{model.coef_}")
    print(f"线性回归模型的intercept:{model.intercept_}")
    # 5.2模型预测
    y_pred = model.predict(x_test)
    print(f"模型在测试集上的预测结果为:{y_pred}")
    # 5.3模型评价-计算均方误差
    mse = mean_squared_error(y_test, y_pred)
    print(f"模型在测试集上的均方误差为:{mse}")


if __name__ == '__main__':
    linear_model_equation()
    linear_model_numerical()

五、正则化

学习目标:

1.掌握过拟合、欠拟合的概念

2.掌握过拟合、欠拟合产生的原因

3.知道什么是正则化,以及正则化的方法

欠拟合与过拟合

过拟合:一个假设 在训练数据上能够获得比其他假设更好的拟合, 但是在测试数据集上却不能很好地拟合数据 (体现在准确率下降),此时认为这个假设出现了过拟合的现象。(模型过于复杂)

欠拟合:一个假设 在训练数据上不能获得更好的拟合,并且在测试数据集上也不能很好地拟合数据 ,此时认为这个假设出现了欠拟合的现象。(模型过于简单)

过拟合和欠拟合的区别:

欠拟合在训练集和测试集上的误差都较大

过拟合在训练集上误差较小,而测试集上误差较大

通过代码认识过拟合和欠拟合

目的:借助线性回归模型,演示不同特征数据情况下的模型欠拟合、恰好拟合、过拟合效果
  • 导包
import numpy as np
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
import matplotlib.pyplot as plt
  • 欠拟合
def under_fitting_method():
    """
    演示欠拟合:
        1.构造数据
        2.模型实例化
        3.模型训练
        4.模型预测
        5.模型评价
        6.画图
    """
    # 1.构造数据
    np.random.seed(555)
    x = np.random.uniform(-3, 3, size=100)
    y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
    # 2.模型实例化
    model = LinearRegression()
    # 3.模型训练
    X = x.reshape(-1, 1)
    model.fit(X, y)
    # 4.模型预测
    y_pred = model.predict(X)
    # 5.模型评价
    mse = mean_squared_error(y, y_pred)
    print(f"模型预测的均方误差:{mse}")
    # 6.画图
    plt.scatter(x, y)
    plt.plot(np.sort(x), y_pred[np.argsort(x)], c='r')
    plt.show()

在这里插入图片描述

  • 正好拟合

添加二次项,绘制图像

def fitting_method():
    """
    演示正好拟合:
        1.构造数据
        2.模型实例化
        3.模型训练
        4.模型预测
        5.模型评价
        6.画图
    """

    # 1.构造数据
    np.random.seed(555)
    x = np.random.uniform(-3, 3, size=100)
    y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
    # 2.模型实例化
    model = LinearRegression()
    # 3.模型训练
    X = x.reshape(-1, 1)
    X = np.hstack([X, X ** 2])
    model.fit(X, y)
    # 4.模型预测
    y_pred = model.predict(X)
    # 5.模型评价
    mse = mean_squared_error(y, y_pred)
    print(f"模型预测的均方误差:{mse}")
    # 6.画图
    plt.scatter(x, y)
    plt.plot(np.sort(x), y_pred[np.argsort(x)], c='r')
    plt.show()

在这里插入图片描述

  • 过拟合

再次加入高次项,绘制图像,观察均方误差结果

def over_fitting():
    """
    演示过拟合:
        1.构造数据
        2.模型实例化
        3.模型训练
        4.模型预测
        5.模型评价
        6.画图
    """

    # 1.构造数据
    np.random.seed(555)
    x = np.random.uniform(-3, 3, size=100)
    y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
    # 2.模型实例化
    model = LinearRegression()
    # 3.模型训练
    X = x.reshape(-1, 1)
    X = np.hstack([X, X ** 2, X ** 3, X ** 4, X ** 5, X ** 6, X * 7, X ** 8, X ** 9, X ** 10])
    model.fit(X, y)
    # 4.模型预测
    y_pred = model.predict(X)
    # 5.模型评价
    mse = mean_squared_error(y, y_pred)
    print(f"模型预测的均方误差:{mse}")
    # 6.画图
    plt.scatter(x, y)
    plt.plot(np.sort(x), y_pred[np.argsort(x)], c='r')
    plt.show()

在这里插入图片描述

通过上述观察发现,随着加入的高次项越来越多,拟合程度越来越高,均方误差也随着加入越来越小。说明已经过拟合了。

原因以及解决办法

欠拟合产生原因: 学习到数据的特征过少

解决办法:

1)添加其他特征项,有时出现欠拟合是因为特征项不够导致的,可以添加其他特征项来解决

2)添加多项式特征,模型过于简单时的常用套路,例如将线性模型通过添加二次项或三次项使模型泛化能力更强

过拟合产生原因: 原始特征过多,存在一些嘈杂特征, 模型过于复杂是因为模型尝试去兼顾所有测试样本

解决办法:

1)重新清洗数据,导致过拟合的一个原因有可能是数据不纯,如果出现了过拟合就需要重新清洗数据。

2)增大数据的训练量,还有一个原因就是我们用于训练的数据量太小导致的,训练数据占总数据的比例过小。

3)正则化

4)减少特征维度

正则化

正则化是什么:在损失函数上加上一些限制,减少甚至删除某些特征的影响,避免模型过于复杂。

在解决回归过拟合中,我们选择正则化。但是对于其他机器学习算法如分类算法来说也会出现这样的问题,除了一些算法本身作用之外(决策树、神经网络),我们更多的也是去自己做特征选择,包括之前说的删除、合并一些特征

在这里插入图片描述

在学习的时候,数据提供的特征有些影响模型复杂度或者这个特征的数据点异常较多,所以算法在学习的时候尽量减少这个特征的影响(甚至删除某个特征的影响),这就是正则化

注:调整时候,算法并不知道某个特征影响,而是去调整参数得出优化的结

L1正则化
  • 假设𝐿(𝑊)是未加正则项的损失,𝜆是一个超参,控制正则化项的大小。
  • 则最终的损失函数:𝐿=𝐿(𝑊)+λ∗∑i=1n∣wi∣𝐿=𝐿(𝑊)+ \lambda*\sum_{i=1}^{n}\lvert w_i\rvertL=L(W)+λi=1nwi

作用:用来进行特征选择,主要原因在于L1正则化会使得较多的参数为0,从而产生稀疏解,可以将0对应的特征遗弃,进而用来选择特征。一定程度上L1正则也可以防止模型过拟合。

L1正则为什么可以产生稀疏解(可以特征选择)

稀疏性:向量中很多维度值为0

  • 对其中的一个参数 $ w_i $ 计算梯度,其他参数同理,α是学习率,sign(wi)是符号函数。

L1的梯度:

𝐿=𝐿(𝑊)+λ∗∑i=1n∣wi∣𝐿=𝐿(𝑊)+ \lambda*\sum_{i=1}^{n}\lvert w_i\rvertL=L(W)+λi=1nwi

∂L∂wi=∂L(W)∂wi+λsign(wi)\frac{\partial L}{\partial w_{i}} = \frac{\partial L(W)}{\partial w_{i}}+\lambda sign(w_{i})wiL=wiL(W)+λsign(wi)

LASSO回归: from sklearn.linear_model import Lasso

在这里插入图片描述

L2正则化
  • 假设𝐿(𝑊)是未加正则项的损失,𝜆是一个超参,控制正则化项的大小。
  • 则最终的损失函数:𝐿=𝐿(𝑊)+λ∗∑i=1nwi2𝐿=𝐿(𝑊)+ \lambda*\sum_{i=1}^{n}w_{i}^{2}L=L(W)+λi=1nwi2

作用:主要用来防止模型过拟合,可以减小特征的权重

优点:越小的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象

L2正则为什么可以减小特征权重

  • 对于之前梯度下降讲到的损失函数来说,在代价函数后面加上一个正则化项

在这里插入图片描述

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐