Press "Enter" to skip to content

Python 机器学习:线性回归

线性回归是机器学习中最基本的一个算法,但是那些所谓的效果很好的算法也无非是从这些基础算法慢慢演变而来。高中时候的数学老师给我讲过一个乔峰的故事,我今天再添油加醋的给你们说下。天龙八部中,乔峰在聚贤庄大战江湖群雄这个算是经典了,当时各路武林豪杰纷纷使出自家的看门绝学,什么易筋经啊,九阴真经啊,葵花点穴手啊等等,但统统都被乔峰一拳KO,直接秒杀,竟无一人是其敌手,那乔峰用的是什么高深武学呢?其实他用的是拳法当作最为基础的一套拳法,名为长拳,有点拳法方面知识的人都知道,长拳其实一套最最基础的拳法,大家可以把它想成军训时候的匕首操。但就是这么个匕首操把这么多绝世武功都KO了。为啥?因为乔峰小时候在少林寺山脚住的时候,就开始苦练基本功,苦练长拳,并没用刻意的去最求一些更高水平的武学,这才将一套基础拳法发挥得如此淋漓尽致。

(这个故事我也只听了个大概,上面我很大部分都自己瞎写的,我就是要说一个道理。)

第一:基础很重要

第二

:一些简单的东西,学好了不比很多复杂的高深的东西差。

说了这么多,其实就是要引出今天的主题——-线性回归。线性回归我觉得可以当成是机器学习中的长拳。

线性回归

线性回归包括一元线性回归和多元线性回归,一元的是只有一个x和一个y。多元的是指有多个x和一个y。

下面我只讲下一元的,多元只是将变成了

一元线性回归其实就是去找到一条直线,这条直线能以最小的误差(Loss)来拟合数据。

怎么来表示误差呢?

如上图所示,横坐标表示x,纵坐标表示y。我们要找的就是图中的这条直线。我们要去找到这条直线,大家可以想象,我们肯定希望找到的那条线,距离每个点都很近,最好所有的点上都在这条线上,但是一条直线去拟合所有的点都在这条直线上肯定不现实,所以我们希望这些点尽量离这条直线近一点。即去找每个点和直线的距离最小的那条线,为了简单起见,将绝对值转化为平方,那么误差可以表示为

,这里i表示第i个数据,N表示总的样本个数。一般我们还会把Loss求和平均,来当作最终的损失,

怎么去最小化误差?

我们要怎么去找到最能拟合数据的直线?即最小化误差呢?

一般有两个方法:

最小二乘法

上面我们讲了我们定义的损失,其中的x,y,i,N都是已知的,那么我们就可以把这个方程看作是m和b的方程。作为一个m和b的二次方程。那么求Loss最小值的问题就转变成了求极值问题,这个高数学过的都应该知道点。

怎么求极值呢?

令每个变量的偏导数为零,求方程组的解呗,这个是很基础的高数问题了。

我们可以得到下面的方程组

然后就是巴拉巴拉巴拉把m和b求出来,这样就得到我们要的线性方程了。

梯度下降法

没有梯度下降就没有现在的深度学习,这是一个神奇的算法。

最小二乘法可以一步到位,直接算出m和b,但他是有前提的,具体我有点记不清了,好像是需要满秩什么的。梯度下降法和最小二乘不一样,它通过一步一步的迭代,慢慢的去靠近到那条最优直线。

最小二乘法里面我们提到了两个偏导数,分别为

我们要去找Loss这个方程的最小值,最小值怎么求?按数学的求法就是最小二乘法呗,但是大家可以直观的想一下,很多地方都会用一个碗来形容,那我也找个碗来解释吧。

大家把这个Loss函数想象成这个碗,而我们要求的最小值就是碗底。假设我们现在不能用最小二乘法求极小值,但是我们的计算机的计算能量很强,我们可以用计算量换结果,不管我们位于这个碗的什么位置,只要我们想去碗底,就要往下走。

往下走???

这个下不就是往梯度方向走吗,那我们沿着梯度一点一点滑下去呗,反正计算机不嫌累。梯度不就是上面那两个公式呗。现在梯度有了,那每次滑多远呢,一滑划过头了不久白算半天了吗,所以还得定义步长

,用来表示每次滑多长。这样我们就能每次向下走一点点,再定义一个

迭代值

用来表示滑多少次,这样我们就能慢慢的一点点的靠近最小值了,不出意外还是能距离最优值很近的。

顺便把上面这个梯度下降法实现下

每次向下滑要慢慢滑,就是要个步长,我们定义为learning_rate,往往很小的一个值。

向下滑动的次数,就是迭代的次数,我定义为num_iter,相对learning_rate往往很大。

定义好这两个,我们就可以一边求梯度,一边向下滑了。就是去更新m和b。

我这里用了加号,很多人会误以为梯度下降就要减,但是其实梯度本身是有方向的,所以这里直接加就可以。

如下图所示,我们做的初始化

然后就是优化器,优化器就是去做梯度下降

它里面的具体步骤,如下

里面的compute_gradient方法就是去计算梯度做参数更新

线性回归的一般形式

线性回归Python实现

结果如下图所示,

为改进线性回归算法的准确率,有很过改进的算法,其中有局部加权线性回归,如下是各展示

分别在K=1,K=0.1,K=0.01,K=0.003,当K=1为普通的线性回归,当K=0.1变化不明显,当K=0.01是拟合效果较好,当K=0.03时出现过拟合现象

如果数据的特征比样本点还多应该怎么办?统计学家引入岭回归、Lasso、前向逐步回归来解决这个问题。

线性回归中可能遇到的问题

  • 求解损失函数的最小值有两种方法:梯度下降法以及正规方程,两者的对比在附加笔记中有列出。

  • 特征缩放:即对特征数据进行归一化操作,进行特征缩放的好处有两点,一是能够提升模型的收敛速度,因为如果特征间的数据相差级别较大的话,以两个特征为例,以这两个特征为横纵坐标绘制等高线图,绘制出来是扁平状的椭圆,这时候通过梯度下降法寻找梯度方向最终将走垂直于等高线的之字形路线,迭代速度变慢。但是如果对特征进行归一化操作之后,整个等高线图将呈现圆形,梯度的方向是指向圆心的,迭代速度远远大于前者。二是能够提升模型精度。

  • 学习率α的选取:如果学习率α选取过小,会导致迭代次数变多,收敛速度变慢;学习率α选取过大,有可能会跳过最优解,最终导致根本无法收敛。

过拟合问题及其解决方法

  • 问题:以下面一张图片展示过拟合问题

  • 解决方法:(1):丢弃一些对我们最终预测结果影响不大的特征,具体哪些特征需要丢弃可以通过PCA算法来实现;(2):使用正则化技术,保留所有特征,但是减少特征前面的参数θ的大小,具体就是修改线性回归中的损失函数形式即可,岭回归以及Lasso回归就是这么做的。

岭回归与Lasso回归

岭回归与Lasso回归的出现是为了解决线性回归出现的过拟合以及在通过正规方程方法求解θ的过程中出现的x转置乘以x不可逆这两类问题的,这两种回归均通过在损失函数中引入正则化项来达到目的,具体三者的损失函数对比见下图:

其中λ称为正则化参数,如果λ选取过大,会把所有参数θ均最小化,造成欠拟合,如果λ选取过小,会导致对过拟合问题解决不当,因此λ的选取是一个技术活。

岭回归与Lasso回归最大的区别在于岭回归引入的是L2范数惩罚项,Lasso回归引入的是L1范数惩罚项,Lasso回归能够使得损失函数中的许多θ均变成0,这点要优于岭回归,因为岭回归是要所有的θ均存在的,这样计算量Lasso回归将远远小于岭回归。

可以看到,Lasso回归最终会趋于一条直线,原因就在于好多θ值已经均为0,而岭回归却有一定平滑度,因为所有的θ值均存在。

使用线性回归预测房价

1. 预测一下房价

房价是一个很火的话题,现在我们拿到一组数据,是房子的大小(平方英尺)和房价(美元)之间的对应关系,见下表(csv数据文件):

Nosquare_feetprice
11506450
22007450
32508450
43009450
535011450
640015450
760018450

从中可以大致看出,房价和房子大小之间是有相关关系的,且可以大致看出来是线性相关关系。为了简单起见,这里理想化地假设房价只和房子大小有关,那我们在这组数据的基础上,怎样预测任意大小的房子的房价呢?

python 代码如下:

也可以按本文前面提示的方式获取代码。

【输出结果】

coefficient:[ 28.77659574]

predict_value:[ 21915.42553191]

intercept:1771.80851064

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注