评论
线性回归
算法概述
开始之前,先大概说一下有监督机器学习的本质是什么?简单点来说,我们经常解决的一类问题就是给定一个函数f(x)和输入数据集X,然后求解输入数据集的各个样本数据在经过函数的映射计算后的输出数据集Y,而机器学习大部分解决的问题就是在给定输入数据集X和输出数据集Y,来获知函数f(x),以方便我们利用计算好的f(x)去对其他输入数据进行映射计算。然而现实是由于受限于函数本身的复杂度、数据的噪声影响、数据集的规模、计算f(x)所需代价等一系列因素,我们往往不会获得完全正确的f(x),所以很多情况下,我们只是在不断求解一个最接近真实f(x)的最优解,并且让它具备一定的泛化能力,即在真正拿来用的其他数据集上也具备一样好的特性。 线性回归(Linear Regression)试图学得一个通过n个属性的线性组合来进行预测的函数。简单来说,线性模型就是用线性方程拟合样本点,根据样本点数据,得出一条直线或一个超平面能够尽可能的代表这些数据的总体情况,这个直线或者超平面就是我们要求解的f(x)。即: $$ f(x)=theta_1x_1+theta_2x_2+…+theta_nx_n+b $$ 通常用向量形式写成:$$ f(x)=theta^Tx+b $$ 其中,\(theta ^{ T }=(theta _{ 1 },theta _{ 2 },theta _{ 3 },…,theta _{ n }),quad xin R^{ n } \)(x是n维向量)。 更简洁的,我们把截距项b也吸收入向量形式,我们还是用θ表示,表示为: $$ f(x)=theta^Tx $$ 注意,因为加了一项,这个时候 \(xin R^{ n+1 } \)(x是n+1维向量,有时候为了表达方便,也会直接说是n维),最后一个元素恒置为1。 如果此时的数据集有m个样本,n个属性值,则此时的数据集可以用矩阵的形式表示为: $$ X_{mtimes{(n+1})}=left[ begin{matrix} x_{ 11 } & x_{ 12 } & cdots & x_{ 1n } & 1 \ x_{ 21 } & x_{ 22 } & cdots & x_{ 2n } & 1 \ vdots & vdots & ddots & vdots & vdots \ x_{ m1 } & x_{ m2 } & cdots & x_{ mn } & 1 end{matrix} right] =left[ begin{matrix} x^{ T }_{ 1 } & 1 \ x^{ T }_{ 2 } & 1 \ vdots & 1 \ x^{ T }_{ m } & 1 end{matrix} right] $$ 再把标记值也记为向量形式,\(y=(y_{ 1 };y_{ 2 };…;y_{m}) \),我们的目的是求出合适的θ。算法推导
损失函数
最小二乘法意义下的损失函数
刚才说到我们尝试学得一个f(x)使得它能够尽量接近真实情况,但是如何度量呢?线性回归中最常用的性能度量就是均方误差,均方误差有非常好的几何意义,它对应了常用的欧式距离,我们的目的是让均方误差最小化,因此损失函数为:
$$ J(theta)=frac{1}{2}sum_{i=1}^m{(h_theta(x^{(i)})-y^{(i)})^2} $$ 其中,\(h_theta(x^{(i)}) \)表示样本的估计值,\(y^{(i)} \)表示样本的观测值,前面的\(frac{1}{2} \)是故意构造出来的,因为不会对整体产生影响,但可以使后面的求导过程中约去平方项,这样做只是为了数学上的便利。直观理解上面的目标函数,均方误差最小化就是试图找到一条直线或者超平面使所有样本到直线上的欧式距离之和最小。这种基于均方误差最小化来进行模型求解的方法称为最小二乘法( Ordinary Least Square,OLS,一般指普通最小二乘法)。
极大似然估计意义下的损失函数
假设每一个样本的估计值和观测值之间都存在误差,存在着下面的关系: $$ y^{(i)}=theta^Tx^{(i)}+epsilon^{(i)} $$ 这个误差可能是多个不同的原因共同造成的,可能有建模的时候没有考虑到比较细的特征,可能有观测设备或者仪器产生的误差等,各种不同的细小随机分布综合叠加,最后反应出来的就是\(epsilon^{(i)} \)。依据中心极限定理,假设误差\(epsilon^{(i)}(1le ile m) \)是独立同分布的,服从均值为为0,方差为某定值\(sigma^{2} \)的高斯分布。
@中心极限定理
定义:在客观实际中有一些随机变量,它们是由大量的独立随机因素的综合影响所形成的,而其中每一个别因素在总的影响中所起的作用都是微小的,这种随机变量往往近似地服从正态分布。 举例: 城市耗电量:大量用户的耗电量总和 测量误差:许多观察不到的、微小误差的总和注:应用前提是多个随机变量的和,有些问题是乘性误差,则需要鉴别或者取对数后再使用。
我们先来整体梳理一下思路,假设某一个\(x^{(i)} \)在没有任何误差的情况下对应的真值是10,它是唯一的定值(标量),但实际情况中的观测值\(y^{(i)} \)并不是真值,它会受到误差的影响,所以观测值有可能是10,也有可能是在10附近的一些值,这个范围取决于误差的影响大小,所以观测值\(y^{(i)} \)其实是一个随机变量。我们假设观测值受到影响的误差服从均值为0,方差为4的正态分布,那么某一个样本\(x^{(i)} \)对应的观测值\(y^{(i)} \)的可能取值及其概率分布如下图所示:参数优化
已经知道了算法的损失函数,我们接下来要进行的就是$theta$解析式求解过程,下面将介绍两种方法。最小二乘法直接求解
将损失函数写成向量的形式: $$J(theta)=frac{1}{2}sum_{i=1}^m(h_theta(x^{(i)}) – y^{(i)})^2=frac{1}{2}(Xtheta-y)^T(Xtheta-y)$$ 对$theta$求一阶导得到梯度: $$ begin{equation}begin{split} nabla_{theta} J(theta) &= nabla_{theta} (frac{1}{2}(Xtheta-y)^T(Xtheta-y)) \ &= nabla_{theta} (frac{1}{2}(theta^TX^T-y^T)(Xtheta-y)) \ &=nabla_{theta}(frac{1}{2} ( theta^T X^T X theta – theta^T X^T y – y^TXtheta + y^Ty) ) \ &=frac{1}{2}(2X^TXtheta – X^Ty – (y^TX)^T) \ &= X^TXtheta-X^Ty end{split}end{equation} \$$ 上式求导用到了矩阵求偏导的公式,参考下面的公式,可将其他无关的矩阵项看成是A,θ看成是公式中的x。 @常用的矩阵向量求导公式: $$frac { partial Ax }{ partial x } =A^T$$ $$frac { partial x^TA }{ partial x } =A$$ $$frac { partial x^TA x}{ partial x } =(A^T+A)x$$ $$frac { partial x^T x}{ partial x } =2x$$ 因为$J(theta)$是存在极小值的凸函数,当然梯度为0的时候可取得最小值: 令$X^TXtheta-X^Ty = 0$,得: $$X^TXtheta=X^Ty$$ 若$X^TX$可逆,则得到参数的解析式: $$theta = (X^TX)^{-1}X^Ty$$ 注意,上式有个问题,就是必须要求$X^TX$可逆,才能解出唯一$theta$,也就是说要求$X^TX$必须满秩。然而现实任务中$X^TX$往往不是满秩矩阵,例如在许多任务中我们会遇到大量的变量其数目甚至超过样例数,导致X的列数多于行数,如基因和文本分类问题。此时可解出多个解,它们都能使均方误差最小化,究竟选择哪一个解作为输出呢?一种办法是由学习算法的归纳偏好决定。 归纳偏好可看作学习算法自身在一个可能很庞大的假设空间中对假设进行选择的启发式或“价值观”,然后在训练集上“等效”的几个模型中识别出“泛化能力更强的”还是“更独特的”,然后根据需要选择更好的模型。按照“奥卡姆剃刀”(Occam’s razor)原则虽然可以选择一个最简单的模型,以使得泛化能力更强,但是有时候效果并不理想,第一,“简单”的模型很多时候并不能够直观确定,第二,有时候需解决的问题场景复杂,必须按照实际情况具体讨论,奥卡姆剃刀有可能并不适用,所以,归纳偏好不足以解决我们的问题。 那如何解决这个问题呢?更常用的办法是引入正则化(regularization)项。正则化
关于正则化的类型、原理、优点等请参看《正则化总结》 正则化可以理解为模型的复杂度惩罚因子,在原有损失函数中加入对参数的限制项,组成新的目标函数,使得参数的值不会太大,从而降低模型的复杂度。 我们将线性回归的损失函数增加参数的平方和损失: $$J(theta )=frac { 1 }{ 2 } sum _{ i=1 }^{ m }{ (h_{ theta }(x^{ (i) })-y^{ (i) })^{ 2 } } +lambda sum _{ j=1 }^{ n }{ theta_j^2 }$$ 写成向量形式: $$J(theta)=frac{1}{2}(Xtheta-y)^T(Xtheta-y)+lambda theta^Ttheta)$$ 对$theta$求偏导,$ lambdatheta^Ttheta $求偏导后为$2lambda theta$,加到原损失函数求导结果的后面: $$nabla_{theta} J(theta)=frac{1}{2}(2X^TXtheta-X^Ty-(y^TX)^T+2lambdatheta)$$ 同样令$J(theta)$等于0,化简得到$theta$的解析式: $$theta = (X^TX+lambda I)^{-1}X^Ty$$ 通过证明$X^TX+lambda I$正定,可证明$X^TX+lambda I$是可逆的,证明过程略。 上门的参数平方和损失项,就是正则化的一种方式,称为L2范数(norm)或岭回归(Ridge Regression)。正则化还有其他的方式,如下对比: L1-norm,Lasso: $$J(theta )=frac { 1 }{ 2 } sum _{ i=1 }^{ m }{ (h_{ theta }(x^{ (i) })-y^{ (i) })^{ 2 } } +lambda sum _{ j=1 }^{ n }{ |theta _{ j }|}$$ L2-norm,Ridge: $$J(theta )=frac { 1 }{ 2 } sum _{ i=1 }^{ m }{ (h_{ theta }(x^{ (i) })-y^{ (i) })^{ 2 } } +lambda sum _{ j=1 }^{ n }{ theta _{ j }^{ 2 } }$$ Elastic Net,弹性网络: $$J(theta )=frac { 1 }{ 2 } sum _{ i=1 }^{ m }{ (h_{ theta }(x^{ (i) })-y^{ (i) })^{ 2 } } +lambda left( rho cdot sum _{ j=1 }^{ n }{ |theta _{ j }|+(1-rho ) } cdot sum _{ j=1 }^{ n }{ theta_j^2} right) $$ 注:上式中,$lambda$是调节因子,用来控制正则项的惩罚力度,要求$lambda >0$。第三种方式弹性网络是上面两种方式的结合,通过权重因子$rho$来调节配置两种正则化方式的权重,要求$rho in [0, 1]$。如何求超参数λ:
λ是参数的参数,称为超参数,一般会先验地给定一个范围,然后使用交叉验证法(Cross-validation)得出,超参数无法通过样本直接算出,而是通过验证数据来选一个使得模型性能最好的拿来用。交叉验证法详见《交叉验证法》。
对三种正则化作一个小小对比:英文名 | 中文翻译 | 范数 | 约束方式 | 优点 |
LASSO | 最小绝对衰减和选择子 | L1 | 绝对值和 | 特征选择 |
Ridge | 岭回归 | L2 | 平方和 | 性能稍好,方便计算 |
Elastic Net | 弹性网络 | L1、L2 | 绝对值和、平方和 | 结合LASSO和Ridge的优点 |
梯度下降
求最优参数解析式的另外一种办法是不直接求出θ,而是通过梯度下降(Gradient Descent)的方法不断学习θ。关于梯度下降的原理、类型、优点,请参看《梯度下降总结》。 虽然通过最小二乘法加正则项可以解除非常理想的θ的解析式,但在实际场景更多还是会用梯度下降法来求参数解析式,原因有以下几方面: 1)如果X特征维度特别大,比如是上千上万维的,那最小二乘法的计算量是非常大的,因为涉及矩阵求逆,其算法复杂度是O(N^3),N为特征数目。还有就是如果特征数目大于样本数目,没有正则项会出现不可逆的情况,而梯度下降则不会; 2)我们没有办法直接离线的拿到足够的数据,我们可以不断输入新的数据不断提高性能,而不用一次性拿到所有的数据; 3)直接求逆,然后带公式,或者SVD来求伪逆这些传统的办法已经不现实了,同时,机器学习也是一门计算机科学,不是纯粹的数学,我们更希望θ是不断迭代学习来的,而不是直接算出来的。 4)在机器学习中,梯度下降算法随处可见,几乎所有的优化算法都可以用梯度下降算法来实现,包括简单线性回归以及复杂的深度学习。 梯度下降又称最速下降法,思路很简单,对任意一个目标函数,先给定一个初始θ,比如随机初始化,然后沿着梯度的负方向下降一点得到新的θ,通过这种方式不断迭代,最终得到θ使目标函数最小。表达式如下: $$theta=theta-alphacdotfrac{partial J(theta)} {partial theta}$$ 其中α是学习率、步长,需要人为设置,往往给一个稍小的值,比0.01,0.001。 利用梯度下降求解θ,因为求梯度只和当前$theta_j$有关系,所以先把Σ忽略点,求梯度方向过程如下: $$begin{equation} begin{split} frac { partial J(theta ) }{ partial theta _{ j } } & =frac { partial }{ partial theta _{ j } } frac { 1 }{ 2 } (h_{ theta }(x)-y)^{ 2 } \ & =2cdot frac { 1 }{ 2 } (h_{ theta }(x)-y)cdot frac { partial }{ partial theta _{ j } } (h_{ theta }(x)-y) \ & =(h_{ theta }(x)-y)cdot frac { partial }{ partial theta _{ j } } (sum _{ i=0 }^{ n }{ theta _{ i }x_{ i } } -y) \ & =(h_{ theta }(x)-y)x_j end{split} end{equation} $$ 有了梯度方向,接下来就是沿着梯度方向不断更新θ: $$theta _{ j }:=theta _{ j }-alpha frac { partial J(theta ) }{ partial theta _{ j } } =theta _{ j }-alpha (h_{ theta }(x)-y)x_{ j }$$ 整个更新过程可以理解成:$theta_j$沿着梯度下降最快的方向进行递减的过程。左边的$theta_j$表示更新之前的值,等式右边表示沿着梯度方向减少的量,不断更新θi的值直到J(θ)收敛,可以通过比较J(θ)的前后两个值是否有发生变化(继续下降),当没有发生变化时表示已经达到了最小值(可能是局部最小值)。 参数设置问题: 初始值和学习速度都是是人工设置的,而梯度下降法对这些参数又是敏感的。 初始值的设置会影响到最终J(θ)的最小值,它可能是局部最小值,也可能是全局最小值。 学习速度的设置也会影响到梯度下降的性能和结果: 1)当设置过小时,由于沿着最陡峭方向每次迈进的步伐太小,而导致收敛时间过长; 2)当设置过大时,很有可能会直接越过最小值,而无法得到J(θ)的最小值。 如何设置学习速率呢? 1)如果训练数据规模很大,开始学习率可以稍微大点,经过100次迭代或者1000次迭代,学习率降一点,比如降十分之一,再经过100次迭代或者1000次迭代,学习率再降十分之一,如此重复。变更学习率的迭代次数按照实际数据的规模来考虑。 2)对于不是很复杂的模型,固定一个比较小的学习率。算法延伸
线性回归虽然简单,但拟合过程往往有些“耿直”,对于一些非线性关系的数据可能出现欠拟合现象,因为他求的是具有最小均方误差的无偏估计。如何才能够让线性回归也能拟合非线性关系的数据呢?下面提供三种思路。多项式回归
本小节开始之前,必须了解一个事情,就是所谓线性模型,只是针对参数而言的线性关系,但样本关系可以是非线性的。多项式回归(Polynomial Regression)主要通过特征的多项式映射来实现的,特征的多项式映射属于训练模型前特征工程中的特征预处理工作,一个非常简单的步骤,不过它可以在输入数据中增加非线性特征从而有效的提高模型的复杂度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
In [1]: import numpy as np In [2]: from sklearn import preprocessing In [3]: X = np.arange(16).reshape(4,4) In [4]: poly = preprocessing.PolynomialFeatures(3) # degree=3 In [5]: poly.fit_transform(X) Out[5]: array([[ 1., 0., 1., 2., 3., 0., 0., 0., 0., 1., 2., 3., 4., 6., 9., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 2., 3., 4., 6., 9., 8., 12., 18., 27.], [ 1., 4., 5., 6., 7., 16., 20., 24., 28., 25., 30., 35., 36., 42., 49., 64., 80., 96., 112., 100., 120., 140., 144., 168., 196., 125., 150., 175., 180., 210., 245., 216., 252., 294., 343.], [ 1., 8., 9., 10., 11., 64., 72., 80., 88., 81., 90., 99., 100., 110., 121., 512., 576., 640., 704., 648., 720., 792., 800., 880., 968., 729., 810., 891., 900., 990., 1089., 1000., 1100., 1210., 1331.], [ 1., 12., 13., 14., 15., 144., 156., 168., 180., 169., 182., 195., 196., 210., 225., 1728., 1872., 2016., 2160., 2028., 2184., 2340., 2352., 2520., 2700., 2197., 2366., 2535., 2548., 2730., 2925., 2744., 2940., 3150., 3375.]]) |
局部加权线性回归
既然传统线性回归是最小均方误差的无偏估计,也就是预测模型是系统误差为零的估计,所以有些方法允许在估计中引入一些偏差,从而降低预测的均方误差。 其中的一个方法是局部加权线性回归(Locally Weighted Linear Regression,LWLR)。在该算法中,我们给待预测点附近的每个点赋予一定的权重,与kNN一样,这种算法每次预测均需要事先选取出对应的数据子集,然后在这个子集上基于最小均方差来进行普通的回归。 局部加权线性回归的损失函数为: $$J(theta)=frac{1}{2}sum_{i=1}^m w^{(i)}(y^{(i)}-theta^Tx^{(i)})^2$$ 从上式可以看出,与普通的线性回归相比,LWLR仅是在每个数据点加了一个权值$w^{(i)}$,当$w^{(i)}$很大时,很难使得$(y^{(i)}-theta^Tx^{(i)})^2$小,而$w^{(i)}$很小,则它所产生的的影响也就很小。 损失函数解出回归系数θ的形式如下: $$theta=(X^TWX)^{-1}X^TWy$$ 其中,W是由各个样本点权值构成的矩阵。 LWLR使用“核”(与SVM中的核函数类似)来对附近的点赋予更高的权重(与kNN一样,该加权模型认为样本点距离越近,越可能符合同一个线性模型)。核的类型可以自由选择,最常用的核就是高斯核,高斯核对应的权重如下: $$w{(i,i)}=exp(-frac{(x^{(i)}-x)^2}{2k^2})$$ 这样就构建了一个只含对角元素的权重矩阵W,并且点x与$x^{(i)}$越近,$w(i,i)$将会越大。上述公式包含一个需要用户指定的参数k,k称为带宽,它控制着训练样本随着与$x^{(i)}$距离的衰减速率,决定了对附近的点赋予多大的权重,这也是使用LWLR时唯一需要考虑的参数,下图可以看到参数k与权重的关系:- $w^{(i)}$的形式跟高斯函数很像,但是它和高斯函数一点关系都没有,参数也不一样。k是带宽参数,k越小,表示控制的样本窗口范围越小(近);k越大,表示控制的样本窗口范围越大(远)。
- 局部加权回归在每一次预测新样本时都会重新的确定参数,从而达到更好的预测效果当数据规模比较大的时候计算量很大,学习效率很低。并且局部加权回归也不是一定就是避免underfitting。
- 对于线性回归算法,一旦拟合出适合训练数据的参数θ,保存这些参数θ,对于之后的预测,不需要再使用原始训练数据集,所以是参数学习算法。
- 对于局部加权线性回归算法,每次进行预测都需要全部的训练数据(每次进行的预测得到不同的参数θ),没有固定的参数θ,所以是非参数算法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
def lwlr(testPoint,xArr,yArr,k=1.0): xMat = mat(xArr); yMat = mat(yArr).T m = shape(xMat)[0] weights = mat(eye((m))) for j in range(m): #next 2 lines create weights matrix diffMat = testPoint - xMat[j,:] # weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2)) xTx = xMat.T * (weights * xMat) if linalg.det(xTx) == 0.0: print "This matrix is singular, cannot do inverse" return ws = xTx.I * (xMat.T * (weights * yMat)) return testPoint * ws def lwlrTest(testArr,xArr,yArr,k=1.0): #loops over all the data points and applies lwlr to each one m = shape(testArr)[0] yHat = zeros(m) for i in range(m): yHat[i] = lwlr(testArr[i],xArr,yArr,k) return yHat |
广义线性模型
广义线性模型(Generalize Llinear Model,GLM)是线性模型的扩展,通过联结函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。上面讲过的标准线性回归假设误差和因变量y服从正态分布的,而广义线性模型实质上是将正态分布拓展到了指数族分布中,可以根据实际问题选择适合的分布然后选择相应的连接函数以建立相应的广义线性模型。 广义线性模型的其他分布和相应的连接函数(来自Wiki):算法优缺点
线性回归(OLS)
优点:- 模型简单,建模速度快,不需要很复杂的计算,在数据量大的情况下依然运行速度很快。
- 根据系数可知道各个属性在预测中的重要程度,具备很好的可解释性,一定程度可用来辅助做特征选择
- 对异常值很敏感
- 对非线性关系的数据性能稍差,容易欠拟合
岭回归
优点:- 性能比LASSO回归稍好,也方便求导计算得到解析解
- 岭回归的平方偏差因子向模型中引入了少量偏差,但大大减少了方差,使得模型更稳定
- 领回归的假设和最小平方回归相同,但是在最小平方回归的时候我们假设数据服从高斯分布使用的是极大似然估计(MLE),在领回归的时候由于添加了偏差因子,即θ的先验信息,使用的是极大后验估计(MAP)来得到最终的参数
- 岭回归没有特征选择功能
LASSO回归
优点:- 具有特征选择能力,这是L2范数没有的特点,L1范数的解具有稀疏性,可产生稀疏稀疏,达到特征选择的结果。
- L1范数没有解析解,因此计算效率上比L2差。
弹性网络回归
优点:- 弹性网络回归是Lesso回归和岭回归技术的混合体,它使用了L1和L2正则化,也具备了两种技术各自的优点。
- 在进行特征选择过程中出现一些高度相关的变量时,弹性网络更容易考虑到特征的群体效应,而不像Lasso那样将其中一些置为0。所以当某个特征和另一个特征高度相关的时候弹性网络非常有用。Lasso倾向于随机选择其中一个,而弹性网络倾向于选择两个。 所以弹性网络对所选变量的数量没有限制(多重共线性变量可以是多个)。
多项式回归
优点:- 能够拟合非线性可分的数据,更加灵活的处理复杂的关系
- 因为需要设置变量的指数,所以它是完全控制变量的建模
- 需要一些数据的先验知识才能选择最佳指数
- 如果指数选择不当容易出现过拟合
局部加权回归
优点:- 可以拟合非线性关系的数据
- 局部加权回归在每一次预测新样本时都会重新的确定参数,从而达到更好的预测效果。当数据规模比较大的时候计算量很大,学习效率很低。
- 如果带宽参数选择不当容易出现欠拟合或者过拟合
广义线性模型
优点:- 广义线性的响应变量Y可以是不服从正态分布的
- 广义线性模型是线性模型的拓展,可以做很多线性回归不太好实现的东西,比如可以利用广义线性模型更好的实现分类
- 拥有众多可选择的连接函数,根据具体的问题选择合适的连接函数,能够灵活构造各种各样的模型
- 通过极大似然估计计算最优解
- 要求响应变量Y必须是相互独立的
- 系统组件中仅能存在一个线性预测器
[/捂脸]之前服务器到期没提醒,资源释放,好多数据和修改的网站代码丢失了,还没备份,正在尽力一点点恢