zoukankan      html  css  js  c++  java
  • 机器学习听课 | 线性回归 | 06

    线性回归简介

    什么是线性回归

    线性回归(Linear regression)是利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模的一种分析方式.
    特点: 只有一个自变量的情况称为单变量回归,多于一个自变量情况的叫做多元回归.

    如何理解线性回归呢? 下面来看几个例子
    (1) 期末成绩 = 0.7×考试成绩+0.3×平时成绩
    (2) 房子价格 = 0.02×中心区域的距离 + 0.04×城市一氧化氮浓度 + (-0.12×自住房平均房价) + 0.254×城镇犯罪率
    上面两个例子: 我们看到特征值与目标值之间建立了一个关系,这个关系可以理解为线性模型.

    线性回归的特征与目标的关系分析

    线性回归当中主要有两种模型: 一种是线性关系,另一种是非线性关系.
    线性关系: y=wx+b 单变量回归
    非线性关系: y=w1x1+w2x2+...+b 多元回归

    线性回归api初步使用

    from sklearn.linear_model import LinearRegression
    estimator = LinearRegression()
    # LinearRegression.coef_:回归系数
    
    

    案例: 最终成绩预测

    给定平时成绩,期末成绩,预测最终成绩.
    本质是通过线性回归模型,自动把权重向量给提取出来

    步骤分析:
    1.获取数据集
    2.数据基本处理(该案例中省略)
    3.特征工程(该案例中省略)
    4.机器学习
    5.模型评估(该案例中省略)

    数学:求导

    常见函数的导数

    导数的四则运算

    练习

    矩阵(向量)求导

    线性回归的损失和优化

    假设刚才的房子例子,真实的数据之间存在这样的关系.

    真实关系:真实房子价格 = 0.02×中心区域的距离 + 0.04×城市一氧化氮浓度 + (-0.12×自住房平均房价) + 0.254×城镇犯罪率
    

    那么现在呢,随意指定一个关系(猜测)

    随机指定关系:预测房子价格 = 0.25×中心区域的距离 + 0.14×城市一氧化氮浓度 + 0.42×自住房平均房价 + 0.34×城镇犯罪率
    

    请问这样的话,会发生什么?
    真实结果与我们预测的结果之间是不是存在一定的误差呢? 类似下图

    上图中,红色线是真实的房价,而绿色的线是自己构造的, 显然是由误差的,因为一开始的权重参数就是随机赋值的.

    既然存在这个误差,那我们就将这个误差给衡量出来.

    损失函数

    总损失定义为:

    (1) (y_i): 第i个训练样本的真实值
    (2) (h(x_i)): 第i个训练样本特征值组合预测函数
    (3) 上面的损失函数又称为最小二乘法

    如何去减少这个损失,使我们预测的更加准确些?
    既然存在了这个损失,我们一直说机器学习有自动学习的功能,在线性回归这里更是能够体现.
    这里可以通过一些优化方法去优化(其实是数学当中的求导功能)回归的总损失!!

    如何去求模型当中的W,使得损失最小?(目的是找到最小损失对应的W值)

    线性回归中经常使用两种算法:

    (1) 正规方程
    (2) 梯度下降

    正规方程

    什么是正规方程?

    理解: X为特征值矩阵,y为目标值矩阵,直接求得最好的结果.
    缺点: 当特征过多复杂时,求解速度太慢并且得不到结果.

    下图是正规方程求解举例:

    梯度下降

    什么是梯度下降

    梯度下降的基本过程和下山的场景很类似.

    首先,我们有一个可微分的函数,这个函数就代表着一座山.

    我们的目标就是找到这个函数的最小值,也就是山底.

    根据之前的场景假设,最快的下山方式就是找到当前位置最陡峭的方向,然后沿着此方向向下走,对应到函数中,就是找到给定点的梯度,然后朝着梯度相反的方向,就能让函数值下降的最快! 因为梯度的方向就是函数变化最快的方向. 所以我们重复利用这个方法,反复求梯度,最后就能到大局部的最小值,这就类似我们下山的过程,而求取梯度确定了最陡峭的方向.

    梯度的概念

    梯度是微积分中一个很重要的概念.

    在单变量函数中,梯度其实就是函数的微分,代表着函数在某个给定点的斜线的斜率.

    在多变量函数中, 梯度是一个向量,向量有方向,梯度的方向就指出了函数在给定点的上升最快的方向.

    这也就说明了为什么我们需要千方百计的求取梯度! 我们需要到达上帝,就需要每一步观测到此时最陡峭的地方,梯度就恰巧告诉了我们这个方向. 梯度的方向是函数在给定点上升最快的点,那么梯度的反方向就是给定点下降最快的点,这正是我们所需要的!

    梯度下降公式

    学习率α

    α在梯度下降算法中被称为学习率或者步长,意味着我们可以通过α来控制每一步走的距离.

    α不能太大,不然走太快会错过最低点,α而不能太小,不然走的太慢. 所以α的选择在梯度下降算法中往往是非常重要的!

    为什么梯度要乘以一个负号

    梯度前加一个负号,就意味着朝着梯度相反的方向前进! 我们在前文中提到,梯度的方向实际就是函数在此点上升最快的方向,而我们需要朝着下降最快的方向走,自然就是负的梯度的方向,所以此处需要加上负号.

    所以有了梯度下降这样一个优化算法,回归就有了"自动学习"的能力.

    梯度下降法计算举例

    梯度下降和正规方程对比

    梯度下降法方法介绍

    对于线性回归的损失和优化,判断损失这里使用的最小二乘法,优化使用的正规方程和梯度下降.
    正规方程作为了解,最重要的优化方式是梯度下降.
    可以说只要入了人工智能的门,从头到尾都一直在学习各种梯度下降...

    前面介绍了最基本的梯度下降算法实现流程,常见的梯度下降算法有:
    (1) 全梯度下降算法 Full gradient descent
    (2) 随机梯度下降算法 Stochastic gradient descent
    (3) 随机平均梯度下降算法 Stochastic average gradient descent
    (4) 小批量梯度下降算法 Mini-batch gradient descent
    它们都是为了正确地调节权重向量,使目标函数尽可能最小化,差别在于样本的使用方式不同.

    全梯度下降算法 FGD

    随机梯度下降算法 SGD

    小批量梯度下降算法 mini-bantch

    随机平均梯度下降算法 SAG

    算法比较

    (1) FG方法由于它每轮更新都要使用全体数据集,故花费的时间成本最多,内存存储最大.
    (2) SAG在训练初期表现不佳,优化速度较慢. 这是因为我们常常将初始梯度设为0,而SAG每轮梯度更新都结合了上一轮梯度值.
    (3) 综合考虑迭代次数和运行时间,SGD的表现性能都很好,能在训练初期快速摆脱初始梯度值,快速将平均损失函数降到很低. 但要注意,在使用SGD方法时要慎重选择步长,否则容易错过最优解.
    (4) mini-batch结合了SGD的"胆大"和FG的"心细",它的表现也正好居于SGD和FG二者之间. 在机器学习领域,mini-batch是使用最多的梯度下降算法,正是因为它避开了FG运算效率低成本大和SG收敛效果不稳定的缺点.

    线性回归api再介绍

    通过正规方程优化的线性回归

    sklearn.liner_model.LinearRegression(fit_intercept=True)
    # fit_intercept: 是否计算偏执
    
    LinearRegression.coef_: 回归系数
    LinearRegression.intercept_: 偏置
    

    通过随机梯度下降算法优化的线性回归

    sklearn.linear_model.SGDRegrssor(loss="squared_loss",fit_intercept=True,learning_rate="iinvscaling",eta0=0.01)
    # SGDRegrssor使用了SGD来优化,它支持不同的loss函数和正则化惩罚项来拟合线性回归模型
    # loss: 损失类型 loss="squared_loss"是普通最小二乘法
    # fit_intercept: 是否计算偏置
    # learning_rate: string,optional  
    # 学习率填充
    
    
    SGDRegressor.coef_:回归系数
    SGDRegressor.intercept_:偏置
    
    

    案例: 波士顿房价预测

    数据集介绍

    回归性能评估

    均方误差API

    sklearn.metrics.mean_squared_error(y_true,y_pred)
    # 均方误差回归损失
    # y_true: 真实值
    # y_pred: 预测值
    # 返回浮点数结果,数字越小,回归性能越好
    

    欠拟合和过拟合

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

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


    上图很好的说明了,随着模型复杂度提升,训练误差和测试误差的变化.

    欠拟合原因及解决方法

    原因: 学习到数据的特征过少
    解决方法:
    (1) 添加其他特征项,有时候我们模型出现欠拟合的时候是因为特征项不够导致的,可以添加其他特征项来很好地解决.
    (2) 添加多项式特征, 这个在机器学习算法里面很普遍,例如将线性模型通过添加二次项或三次项使模型泛化能力更强.

    过拟合原因及解决方法

    原因: 原始特征过多,存在一些嘈杂特征,模型过于复杂使因为模型尝试去兼顾各个测试数据点.
    解决方法:
    (1) 重新清洗数据,导致过拟合的一个原因也有可能使数据不纯导致的,如果出现了过拟合就需要我们重新清洗数据.
    (2) 增大数据的训练量,还有一个原因就是我们用于训练的数据量太小导致的,训练数据占总数居的比例过小.
    (3) 正则化
    (4) 减少特征维度,防止维灾难.

    正则化

    什么是正则化

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

    在学习的时候,数据提供的特征有些影响模型复杂度或者这个特征的异常点较多,所以算法在学习的时候尽量减少这个特征的影响(甚至删除某个特征的影响),这就是正则化.
    注意: 调整的时候,算法并不知道某个特征影响,而是去调整参数得出优化的结果.

    正则化类别

    L2正则化
    作用: 可以使得其中一些W的值很小,都接近于0,削弱某个特征的影响
    Ridge回归

    L1正则化
    作用: 可以使得其中一些W的直接为0,删除这个特征的影响.
    LASSO回归

    正则化线性模型

    Ridge Regression(岭回归)

    岭回归时线性回归的正则化版本,即在原来的线性回归的cost function中添加正则项regularization term

    以达到在拟合数据的同时,使模型权重尽可能小的目的.
    岭回归代价函数:

    注意: α=0,岭回归退化为线性回归

    Lasso Regression(Lasso 回归)

    Elastic Net(弹性网络)

    小结

    一般来说,我们应该避免使用朴素线性回归,而应对模型进行一定的正则化处理,那如何选择正则化方法呢?

    常用: 岭回归
    假设只有少部分的特征是有用的:
    (1) 弹性网络
    (2) Lasso
    一般来说,弹性网络的使用更为广泛. 因为在特征维度高于训练样本数,或者特征是强相关的情况下,Lasso回归的表现不太稳定.

    相关正则化的api

    from sklearn.linear_model import Ridge, ElasticNet, Lasso
    

    线性回归的改进 -- 岭回归

    岭回归API

    sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True,solver="auto", normalize=False)
    # 具有L2正则化的线性回归
    # alpha: 正则化力度
    # solver: 会根据数据自动选择优化方法(即SAG,SGD等...)
    # normalize: 数据是否进行标准化(一般都是在之前已经使用StandardScaler进行了标准化了)
    
    Ridge.coef_: 回归权重
    Ridge.intercept_:回归偏置
    
    sklearn.linear_model.RidgeCV(_BaseRidgeCV, RegressorMixin)
    # 具有L2正则化的线性回归,可以进行交叉验证
    
    

    Ridge方法相当于SGDRegressor(penalty='l2', loss="squared_loss"),只不过SGDRegressor实现了一个普通的随机梯度下降学习,推荐使用Ridge(实现了SAG)

    观察正则化程度的变化,对结果的影响?

    正则化力度越大,权重系数会越小
    正则化力度越小,权重系数会越大

    下面的代码部分其实本质上和之前的代码没有什么差别,只是选择了不同的模型而已.

    from sklearn.linear_model import Ridge,RidgeCV
    
    ...
    estimator = Ridge()
    estimator = RidgeCV()
    ...
    

    模型的保存和加载

    sklearn模型的加载和保存API

    from sklearn.externals import joblib
    保存:joblib.dump(estimator, 'test.pkl')
    加载:estimator = joblib.load('test.pkl')
    
  • 相关阅读:
    Python之路【第八篇】(一)python基础 之计算机操作系统发展史
    Python之路【第六篇】python基础 之异常处理
    Python之路【第七篇】python基础 之socket网络编程
    Python之路【第六篇】python基础 之面向对象进阶
    Python之路【第六篇】python基础 之面向对象(一)
    Fastdfs 部署干货
    Mysql 优化配置2
    Elk 进阶部署
    Elk
    python pickle
  • 原文地址:https://www.cnblogs.com/Rowry/p/14336141.html
Copyright © 2011-2022 走看看