线性回归介绍

一、线性回归的定义

1.回归

指研究一组随机变量(Y1 ,Y2 ,…,Yi)和另一组(X1,X2,…,Xk)变量之间关系的统计分析方法

2.线性

两个变量之间存在一次方函数关系,就称它们之间存在线性关系

3.线性回归(Linear Regression)

结合以上两个名词,顾名思义就是研究存在着一次函数关系的两组随机变量之间定量关系的统计分析方法

举个例子具体来说什么是线性回归

给定一组房间尺寸和对应房价的数据,我们训练一个模型,再给我们一组房间大小数据,我们就可以预测对应的房价。这里为什么想到线性回归呢?

其实遇到机器学习问题应该①首先判断是监督学习还是非监督学习问题,在这里很明显是监督学习问题,②然后判断是回归问题还是分类问题,这里就是一个回归问题,③最后判断是线性回归还是逻辑回归(Logistic Regression),这个问题中我们需要预测房价,结果应该是连续的输出值,所以是线性回归问题,结合这个问题来看,很明显房间大小和对应之间确实存在着一次函数关系,所以线性回归最合适不过了

总结一下,遇到一个机器学习问题,处理的步骤应该是

当然啦机器学习不止这么简单,比如还有半监督学习等等,这里只给出最常见最基础也最重要的两类问题,通过这张图我们可以清晰的了解不同机器学习问题都有什么特点和区别,那么在遇到问题的时候就可以选择最合适的算法得到我们想要的最优解

二、线性回归的实现

1.算法流程

 

 首先我们把整个线性回归的实现做一个概览,算法的大致流程如上图,首先我们得到一组数据集,将数据集喂给我们的学习算法,拿之间的房价问题举例,在我们得到一个训练好的算法之后,再输入一组房间大小的数据,通过我们的估计函数h(hypothesis fuction),就能算出一个估计的房价,这就是线性回归算法的基本流程。好,那么接下来再展开来讲

2.模型表示(Model Representation)

我们先对线性回归中可能出现的数学符号做一个介绍

X(i)输入变量 \ 输入特征

Y(i):输出变量 \ 目标变量

(X(i),Y(i)):一组训练样本

m:训练集(的大小) 

n:特征的数量

X:输入数据的总体

Y:输出数据的总体

h:预测函数

3.数据处理

(1)设置交叉验证集(Cross Validation Set)和测试集(Test Set)

在监督学习的算法中,我们常用的一个手段就是将数据集划分为

训练集(Training Set):训练机器学习算法(60%)

交叉验证集(Cross Validation Set):若有多个训练好的模型,用交叉验证集来测试各个模型好坏,并选择性能最好的模型作为结果(20%)

测试集(Test Set):评测我们算法的性能好坏(20%)

 

为什么要设置测试集和交叉验证集?

为了能够更精准的选择最好的模型,并最真实的评估模型的好坏,设置CV集和Test集对我们算法有很大的帮助,有人可能有这样的疑问,如果我所有的数据集都拿来做训练,不应该得到更好的算法吗?其实不然,训练集数据多固然是好事,但是要想我们的算法具有鲁棒性(Robust),并能做出很好的表现,划分数据集往往比一股脑把所有数据都拿来训练效果更好

(2)特征缩放(Feature Scaling)

使得特征数据能够处在同一个范围区间,使算法(后面讲到的梯度下降法)执行速度更快,一般来说,我们应用特征缩放使特征大体处于 -1 < Xi < 1的范围为佳

那么什么时候要用到特征缩放呢?

例如在房价预测中,有一个特征房间大小的值大概在100m2左右,而价格这个特征的值在500000¥左右,那么这些特征的数据值差异很大,会对梯度下降收敛速度造成比较大的影响,此时就应该使用特征缩放,使数据值处于同一区间

在这张图中,我们可以清晰的看出,在使用特征缩放后,梯度下降的迭代次数少了很多

(3)归一化(Normalization)

 

均值归一化是一种特征缩放的方法,它和前面基本特征缩放方法的区别在于它使得缩放后特征的均值近乎为0

归一化有两种比较常用的形式:

①线性归一化,线性归一化会把输入数据都转换到[0 1]的范围,公式如下

该方法实现对原始数据的等比例缩放,其中Xnorm为归一化后的数据,X为原始数据,Xmax、Xmin分别为原始数据集的最大值和最小值。

② 0均值标准化,0均值归一化方法将原始数据集归一化为均值为0、方差1的数据集,归一化公式如下

其中,μ、σ分别为原始数据集的均值和方法。该种归一化方式要求原始数据的分布可以近似为高斯分布,否则归一化的效果会变得很糟糕。 

4.训练算法

(1)预测函数(Hypothesis function)

因为是线性回归,所以输出和输入变量间是一次函数关系,如上图表示,我们想要得到最优的预测值,那么就需要选择合适的θ0和θ1,如何选择呢?

(2)代价函数(Cost fuction)

 

我们引入了代价函数,用以判断预测值和真实值之间的误差大小,,那么我们现在的目标就变成了求解θ使得代价函数最小,注意到前面的系数是1/2m,有人就会想为什么是2m,这里其实是为了后面的函数求导方便,马上就会讲到

这里给出一个预测函数和代价函数得例子,可以看出,当不断变化θ时,预测函数对应的直线在不断的变化位置,而代价函数的值先减小后又增大,这也比较容易理解,当不断变化预测函数的位置时,总有一个位置能最贴合我们的数据,并得到最小的误差,那么如何找到这个位置并计算出对应的θ呢?

现在我们可以大致理一理思路,我们的预测函数是h,参数为θ,对应的代价函数是J,我们的目标是求解出一个向量θ,使得J取到最小值

 

(3)梯度下降法(Gradient Descent)

 

这里的α是学习速率(Learning Rate),代表着梯度下降的速度,后面会讲到,那么算法的意思就是,使得所有θ同时不断减去α乘以代价函数的导数函数的值,知道θ保持不变(或减小的非常非常慢),这样我们就得到了最优的θ

这里用也用一个例子来解释为什么可以这样做

这是一个代价函数的三维图,我们想要找到使得代价函数取值最小的点,并由此得到对应的θ,所以我们想到借助导数知识,因为某一点的导数的方向是沿这一点下降最快的方向,所以就像是一个人下山,每一选择一个最陡的方向往下走,最后就能到达山底(也就是我们要的最优解位置),首先我们先初始化一组θ,并得到代价函数,对应着图中的随机一个点开始,每次θ会减小一个值,对应代价函数就会下降,最终到达最优解位置。

聪明的你可能会想到,不同的起始位置,可能会最终会走到不同的地方呀,那么怎么保证我能得到最优解呢?

是的确实会有这样的问题,这种情况我们叫做局部最优解(local optima),当然我们希望能得到全局最优解(global optima),但是事实上线性回归并不会存在这种问题,因为线性回归的预测函数是一次函数,对应的代价函数是一个二次函数,也就是抛物线,所以并不会出现局部最优的情况,代价函数只有一个最优解,我们无论从何处开始,最终总能走到全局最优的位置。那么对于其他情况,我们也有办法处理,以后碰到我们再去详细说明。

下面我们在讨论一下学习速率α的问题,我们说α越大,下降越快,那么是不是α越大越好呢?实则不然,当α过大时,我们的梯度下降可能走不到最优解位置,甚至误差越来越大!

那么是不是为了保险,α越小越好呢?也不是,当α过于小的时候,梯度下降会走的很慢,导致算法运行速度缓慢,就像你小小小碎步下山,虽然安全,但是下了一天可能都还没下来

所以梯度下架很重要的一点就是确定一个合适的α值

下面这张图就是前面讲的a过小和α过大对于的情况图示

选择合适的学习速率α

两种方法

①不断调试,手动挑选

可以试着尝试 α = 0.001,0.003,0.01,0.03,0.1,0.3,1...,选择一个能够得到最优解并且算法也不会运行的太慢的值即可

②自动测试是否收敛

我们可以规定当梯度下降的差小于一个阈值的时候就判定它收敛,直接取得此时的参数θ

这种方法看似方便,但实际中并不好操作,你又要选择一个合适的阈值,而且很有可能又会平白无故增加误差,越做越麻烦,所以还不如自己选一个合适的α,等他收敛拿到参数θ多方便

这样我们就完成了梯度下降算法,那么还有没有其他算法可以求解θ呢?

(4)正规方程(Normal Equation)

 那么我们就想,既然我们要求最优的θ使J收敛,为什么不直接置偏导项为0,直接解除对应的θ多方便,是的,确实是这样!

我们可以总结出求解θ的公式:

那么如果XTX这一项是不可转置的该怎么办? 不用怕,即使是不可转置的,在编程中我们也能对它进行处理并得到正确的结果

那么什么情况会导致这一项不可转置呢?

①数据中有太多的特征,但是数据量较少:(m <= n)

②存在冗余特征,具体来说就是特征中存在线性相关的特征,比如有一列特征是按美元算的价格,另一列是按人名币算的价格,那么这就是线性相关的两列特征,或者有一列特征是其余两列或几列特征的和,等等

在matlab中,可以使用pinv函数求解逆矩阵,即使矩阵是不可逆的也能解得一个我们期望的结果,这是有严格证明可行且无误的,在这里不再说明

 正规方程和梯度下降的比较

在实际选择算法的时候,当 n > 10000 时我们最好选择梯度下降法而不是正规方程,否则算法会很慢

(5)多项式回归(Polynomial Regression)

在实际中,为了更好的拟合我们的数据,预测函数往往不是一个简单的直线,还有曲线的情况(二次函数,三次函数,根号函数...)

 

比如在房价预测中,我们有两个特征,房子占地的长X1和宽X2,但实际上房价和房子的占地面积呈线性关系,所以我们可以构造一个特征X3 = X1 * X2,这就是多项式回归

那么我们应该如何构造特征呢?

①观察X和Y(可以多画画图助于理解),预测他们之间可能存在什么样的关系,来帮助我们构造新特征

②有些高级的机器学习算法可以自动选择特征构造算法,但也容易出现欠拟合(Underfitting)和过拟合(Overfitting)的问题,所以特征选择是一个比较复杂的工程

 注意:因为多项式回归中会出现高阶参数,所以很容易出现数据范围差异很大的情况,这时候特征缩放就十分重要

(6)正则化(Regularization)

在算法设计中,我们有时会遇到这种情况,算法对于给定的数据集拟合的非常好,甚至可以做到零误差,但是当预测新的数据时,却出现了非常大的误差,这很有可能就是过拟合:过于适应训练集使得算法不具有鲁棒性,还有一种情况是算法对于训练集和测试集都不能做到很好的预测,这是欠拟合问题,两中情况的例子如下图所示

什么原因会引起过拟合呢?

特征过多导致模型不具有普适性,下图中的情况就是有过多的特征,最后导致过拟合

参数中某些θ的权重过大或过小,导致对结果产生影响

那么怎么解决这些问题呢?

减少参数的数量:手动筛选参数,或使用模型选择算法

正则化:通过降低某些参数θ的量级或改变它的值,使得每个特征都对预测结果做出一定贡献而减少偏差。正则化的好处是可以保留所有的特征(即使特征量很大),同时能够使算法具有普适性

实现正则化

通过在代价函数末尾加上一个惩罚项实现正则化,其中λ是正则化参数,控制着惩罚力度,需要注意的是惩罚项是从θ1累加的,因为我们并不希望惩罚θ0(因为θ0本来就是用来调节权重的常数项)

对应的,梯度下降法的形式也会做出相应改变

注意θ0的计算并没有改变,但其余参数的计算稍微有些变化

正则化参数λ

正则化参数控制着惩罚力度,当我们设置的λ越来越小时,正则化的作用也越来越小,当λ过于大时,正则化的影响也越来越大,最后可能无法解决过拟合问题,反而导致欠拟合问题,梯度下降也无法收敛,当λ非常大时,预测函数就会成为一条水平的一次函数

 正规方程实现正则化

注:当正规方程实现正则化后,就不会存在不可转置的情况了

至此我们对线性回归的算法就基本介绍完啦,那么如何评估我们得到的模型并做出调整呢?

三、线性回归的评估

 关于机器学习的算法评估有很多相似性,我再找时间去整理发一个单独的博客哈

四、总结

线性回归是最基础也是最重要的机器学习算法,很多其他算法也是在它之上进行扩展调整而成的,而回归分析本身也具有它的优缺点

首先在数据分析中我们一般要对数据进行一些条件假定:

方差齐性
线性关系
效应累加
变量无测量误差
变量服从多元正态分布
观察独立
模型完整(没有包含不该进入的变量、也没有漏掉应该进入的变量)
误差项独立且服从(0,1)正态分布。
现实数据常常不能完全符合上述假定。因此,统计学家研究出许多的回归模型来解决线性回归模型假定过程的约束。
 
回归分析的主要内容为:
①从一组数据出发,确定某些变量之间的定量关系式,即建立数学模型并估计其中的未知参数。估计参数的常用方法是最小二乘法。
②对这些关系式的可信程度进行检验。
③在许多自变量共同影响着一个因变量的关系中,判断哪个(或哪些)自变量的影响是显著的,哪些自变量的影响是不显著的,将影响显著的自变量加入模型中,而剔除影响不显著的变量,通常用逐步回归、向前回归和向后回归等方法。
④利用所求的关系式对某一生产过程进行预测或控制。回归分析的应用是非常广泛的,统计软件包使各种回归方法计算十分方便。
在回归分析中,把变量分为两类。一类是因变量,它们通常是实际问题中所关心的一类指标,通常用Y表示;而影响因变量取值的的另一类变量称为自变量,用X来表示。
 
回归分析研究的主要问题是
(1)确定Y与X间的定量关系表达式,这种表达式称为回归方程;
(2)对求得的回归方程的可信度进行检验;
(3)判断自变量X对因变量Y有无影响;
(4)利用所求得的回归方程进行预测和控制。
应用回归预测法时应首先确定变量之间是否存在相关关系。如果变量之间不存在相关关系,对这些变量应用回归预测法就会得出错误的结果。
 
正确应用回归分析预测时应注意:
①用定性分析判断现象之间的依存关系;
②避免回归预测的任意外推;
③应用合适的数据资料;
 
在对回归算法和线性回归有了充分了解后,我们就可以用在机器学习应用中大展身手啦(本文纯属个人学习资料,若有不对之处请多多包含和指教)
最后附上其中一些算法的matlab代码
 代价函数(Cost fuction)
function J = computeCostMulti(X, y, theta)
  m = length(y);
  J = 0;
  p =  X * theta - y;
  ans = p.^2;
  J = 1 / (2 * m) * sum(ans);
end

梯度下降(Gradient Descent)

function [theta, J_history] = gradientDescentMulti(X, y, theta, alpha, num_iters)
    m = length(y); 
    J_history = zeros(num_iters, 1);
    for iter = 1:num_iters
        theta = theta - alpha / m * X' * (X * theta - y);
        J_history(iter) = computeCostMulti(X, y, theta);
    end
end

归一化(Normaliaztion)

function [X_norm, mu, sigma] = featureNormalize(X)
    X_norm = X;
    mu = zeros(1, size(X, 2));
    sigma = zeros(1, size(X, 2));
    mu = mean(X_norm);
    sigma = std(X_norm);
    X_norm = X_norm-mu;
    X_norm = X_norm./sigma;
end

正规方程(Normal Equation)

function [theta] = normalEqn(X, y)
    theta = zeros(size(X, 2), 1);
    theta = pinv(X' * X) * X' * y;
end
posted @ 2018-11-25 15:17  boobo  阅读(2745)  评论(0编辑  收藏  举报
^