预测数值型数据:回归

之前博客中,我有介绍到分类机器学习算法,分类的目标变量是标称型数据,本篇博客将重点对连续型的数据做出预测及回归算法。有些人会问:"回归能用来做什么?"其实回归能够做任何事情。

本文首先介绍线性回归(具体概念解释可以参考CS229,吴恩达讲义的译文:传送门),包括其名称的由来和python实现。在这之后引入了局部平滑技术,分析如何更好地你和数据。接下来,本文将探讨回归在"欠拟合"情况下的shrinkage技术,探讨偏差和方差的概念。

  1. 用线性回归来找到最佳拟合直线

在具体讲解线性回归之前,咱们先来看看从宏观上分析下线性回归。

线性回归

优点

结果易于理解,计算上不复杂

缺点

对非线性的数据拟合的不好

适用数据类型

数值型和标称型数据

说到回归,一般都是指线性回归,所以本文里的回归和线性回归代表同一个意思。需要说明的是,存在另一种称为非线性回归的回归模型,该模型输入与输出的关系与线性模型并不相同。

回归的步骤:

  1. 收集数据
  2. 准备数据:回归需要数值型数据,标称型数据将被转成二值型数据
  3. 分析数据:绘出数据的可视化二维图将有助于对数据做出理解和分析
  4. 训练数据:找到回归系数
  5. 测试算法:分析模型的效果(利用拟合系数corrcoef)
  6. 使用算法:使用回归,本质上是对分类方法的提升,因为这样可以预测来内需型数据而不仅仅是离散的类别标签

标准回归函数的实现:

回归系数w的求解公式如下:

需要注意的是上述公式中包含,也就是需要对矩阵求逆,因此需要在代码中对的逆矩阵是否存在做出判断。

from numpy import *
def standRegres(xArr,yArr):
    xMat = mat(xArr); yMat = mat(yArr).T
    xTx = xMat.T*xMat
    if linalg.det(xTx) == 0.0:
        print "This matrix is singular, cannot do inverse"
        return
    ws = xTx.I * (xMat.T*yMat)
    return ws


1.2 局部加权线性回归(根据数据来局部调整预测)

线性回归的一个问题是有可能出现欠拟合现象,因为它求得是具有最小均方误差的无偏估计。所以有些方法允许在估计中引入一些偏差,从而降低预测的均方误差。其中的一个方法是局部加权线性回归(Locally Weighted Linear Regression , LWLR)。在该算法中,我们给待预测点附近的每个点赋予一定的权重,LWLR使用"核"来对附近的点赋予更高的权重。最常用的核就是高斯核,高斯核对应的权重如下:

这样就构建了一个只含对角元素的权重矩阵w,并且点x与x( i )越近,w(i,i)将会越大。上述公式包含一个需要用户指定的参数k,它决定了对附近的点赋予多大的权重,这也是使用LWLR时唯一需要考虑的参数下图显示了参数k与权重的关系。

预测数值型数据:回归_第1张图片

局部加权线性回归函数的实现:

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


本文到此为止,介绍了提高预测精度的方法:局部加权回归,虽然局部加权回归比普通线性回归有更好的效果,但是由于每做一次预测,都必须使用整个数据集,所以会带来很大的计算量。接下来咱们介绍下另一种提高预测精度的方法,并分析它的优势所在。

1.3缩减系数来"理解"数据

如果数据的特征比样本点还多,会发现使用线性回归和之前的方法来做预测就会出错,因为如果特征比样本点还多(n>m)也就是说输入矩阵x不是满秩矩阵。非满秩矩阵在求逆时会出现问题。

为了解决这个问题,统计学家引入了岭回归(ridge regression)的概念,这就是本节将介绍的第一种缩减方法。接着是lasso法,该方法效果很好但计算复杂,本节最后介绍了第二种缩减方法,称为前向逐步回归,可以得到与lasso差不多的效果,且更容易实现。

岭回归

简单来说,岭回归就是在矩阵上加入一个lI从而使矩阵非奇异,进而能对求逆。其中矩阵I是一个m x m的单位矩阵,对角线上元素全为1,其他元素全为0。而l是一个用户定义的数值,在这种情况下,回归系数的计算公式将变成:

岭回归最先用来处理特征多于样本数的情况,现在也用于在估计中加入偏差,从而得到更好的估计。这里通过引入l来限制了所有w之和,通过引入惩罚项,能够减少不重要的参数,这个技术在统计学中也叫做缩减(shrinkage)。

这里补充个小知识,大家知道岭回归的岭的由来么,岭回归使用了单位矩阵乘以常量l,我们观察其中的单位矩阵,可以看到值1贯穿整个对角线,其余元素全是0。形象地,在0构成的平面上有一条1组成的"岭",这就是岭回归中的"岭"的由来。

缩减方法可以去掉不重要的参数,因此能更好地理解数据。此外,与简单的线性回归相比,缩减法能取得更好的预测效果。

岭回归代码

def ridgeRegres(xMat,yMat,lam=0.2):
    xTx = xMat.T*xMat
    denom = xTx + eye(shape(xMat)[1])*lam
    if linalg.det(denom) == 0.0:
        print "This matrix is singular, cannot do inverse"
        return
    ws = denom.I * (xMat.T*yMat)
    return ws

为了使用岭回归和缩减技术,首先需要对特征做标准化处理。具体做法就是所有的特征都减去各自的均值并除以方差。

还有一些其他的缩减方法,如lasso,LAR,PCA回归以及子集选择等。与岭回归一样,这些方法不敬可以提高预测精确率,而且可以解释回归系数。

Lasso

不难证明,在增加如下约束时,普通的最小二乘法回归会得到与岭回归的一样的公式:

上式限定了所有的回归系数平方和不能大于l。使用普通的最小二乘法回归在当两个或更多的特征相关时,可能会得出一个很大的正系数和很大的复习书。正是因为上述限制条件的存在,使用岭回归可以避免这个问题。

与岭回归类似,另一个缩减方法lasso也对回归系数做了限定,对应的约束条件如下:

为了在新的约束条件下解出回归系数,需要使用二次规划算法,这无疑极大地增加了计算复杂度,下面介绍一个更为简单的方法来得到结果,该方法叫做前向逐步回归。

前向逐步回归

前向逐步回归算法可以得到与lasso差不多的效果,但更简单。它属于一种贪心算法,即每一步都尽可能减少误差。一开始,所有的权重都设为1,然后每一步所做的决策是对某个权重增加或减少一个很小的值。

该算法伪代码:

预测数值型数据:回归_第2张图片

具体的实现算法如下:

def stageWise(xArr,yArr,eps=0.01,numIt=100):
    xMat = mat(xArr); yMat=mat(yArr).T
    yMean = mean(yMat,0)
    yMat = yMat - yMean     #can also regularize ys but will get smaller coef
    xMat = regularize(xMat)
    m,n=shape(xMat)
    #returnMat = zeros((numIt,n)) #testing code remove
    ws = zeros((n,1)); wsTest = ws.copy(); wsMax = ws.copy()
    for i in range(numIt):
        print ws.T
        lowestError = inf; 
        for j in range(n):
            for sign in [-1,1]:
                wsTest = ws.copy()
                wsTest[j] += eps*sign
                yTest = xMat*wsTest
                rssE = rssError(yMat.A,yTest.A)
                if rssE < lowestError:
                    lowestError = rssE
                    wsMax = wsTest
        ws = wsMax.copy()

接下来我们来探讨下偏差与方差的概念

权衡偏差与方差

在我们使用模型时,一旦发现模型和测量值存在差异,就说出现了误差。下图我们给出了训练误差与测试误差的曲线图,上面的曲线就是测试误差,下面的曲线就是训练误差。在前面的实验我们知道当核(k取值)越小,训练误差就会变小,下图,从左到右就表示了核逐渐减小的过程。一般认为,上述两个误差由三个部分组成:偏差、测量误差和随机噪声,前面我们通过引入三个越来越小的核来不断增大模型的方差。这样我们就可以通过实际效果来看偏差和方差间的折中效果。

预测数值型数据:回归_第3张图片

你可能感兴趣的:(机器学习,回归,机器学习,数值型数据,岭回归,前向逐步回归)