美文网首页Machine Learning & Data Analysis数据挖掘机器学习与数据挖掘
第二十一章 regression算法——线性回归&局部加

第二十一章 regression算法——线性回归&局部加

作者: H2016 | 来源:发表于2017-04-12 17:06 被阅读1063次

    理论部分

    回归是统计学中最有力的工具之一。监督学习算法分为分类算法和回归算法两种,其实就是根据类别标签分布类型为离散型、连续性而定义的。顾名思义,分类算法用于离散型分布预测,如KNN、决策树、朴素贝叶斯、adaboost、SVM、Logistic回归都是分类算法;回归算法用于连续型分布预测,针对的是数值型的样本,使用回归,可以在给定输入的时候预测出一个数值,这是对分类方法的提升,因为这样可以预测连续型数据而不仅仅是离散的类别标签。

    回归的目的就是建立一个回归方程用来预测目标值,回归的求解就是求这个回归方程的回归系数。预测的方法当然十分简单,回归系数乘以输入值再全部相加就得到了预测值。

    1、回归的定义

    回归最简单的定义是,给出一个点集D,用一个函数去拟合这个点集,并且使得点集与拟合函数间的误差最小,如果这个函数曲线是一条直线,那就被称为线性回归,如果曲线是一条二次曲线,就被称为二次回归。

    2、多元线性回归

    假定预测值与样本特征间的函数关系是线性的,回归分析的任务,就在于根据样本X和Y的观察值,去估计函数h,寻求变量之间近似的函数关系。定义:

    其中,n=特征数目;

    xj=每个训练样本第j个特征的值,可以认为是特征向量中的第j个值。

    为了方便,记x0=1,则多变量线性回归可以记为:

    ,(θ、x都表示(n+1,1)维列向量)

    3、广义线性回归

    用广义的线性函数:

    wj是系数,w就是这个系数组成的向量,它影响着不同维度的Φj(x)在回归函数中的影响度,Φ(x)是可以换成不同的函数,这样的模型我们认为是广义线性模型,Φ(x)=x时就是多元线性回归模型。

    线性回归的求解

    说到回归,常常指的也就是线性回归。假设有连续型值标签(标签值分布为Y)的样本,有X={x1,x2,...,xn}个特征,回归就是求解回归系数θ=θ0,θ1,…,θn。那么,手里有一些X和对应的Y,怎样才能找到θ呢? 在回归方程里,求得特征对应的最佳回归系数的方法是最小化误差的平方和。这里的误差是指预测y值和真实y值之间的差值,使用该误差的简单累加将使得正差值和负差值相互抵消,所以采用平方误差(最小二乘法)。平方误差可以写做:

    在数学上,求解过程就转化为求一组θ值使求上式取到最小值,那么求解方法有梯度下降法、NormalEquation等等。梯度下降有如下特点:需要预先选定步长a、需要多次迭代、特征值需要Scaling(统一到同一个尺度范围)。因此比较复杂,还有一种不需要迭代的求解方式--Normal

    Equation,简单、方便、不需要Feature Scaling。NormalEquation方法中需要计算X的转置与逆矩阵,计算量很大,因此特征个数多时计算会很慢,只适用于特征个数小于100000时使用;当特征数量大于100000时使用梯度法。另外,当X不可逆时就有岭回归算法的用武之地了。

    下面就概括一下常用的几种求解算法。

    1、梯度下降法

    根据平方误差,定义该线性回归模型的损耗函数(Cost Function)为:

    ,(系数是为了方便求导展示,此处的系数也可以只是1/2,没有m。)线性回归的损耗函数的值与回归系数θ的关系是碗状的,只有一个最小点。

    2、普通最小二乘法

    Normal Equation算法也叫做普通最小二乘法(ordinary least squares),其特点是:给定输人矩阵X,如果XTX的逆存在并可以求得的话,就可以直接采用该方法求解。其求解理论也十分简单:既然是是求最小误差平方和,另其导数为0即可得出回归系数。

    矩阵X为(m,n+1)矩阵(m表示样本数、n表示一个样本的特征数),y为(m,1)列向量。

    上述公式中包含XTX, 也就是需要对矩阵求逆,因此这个方程只在逆矩阵存在的时候适用。然而,矩阵的逆可能并不存在,后面会讨论处理方法。

    3、局部加权线性回归

    线性回归的一个问题是有可能出现欠拟合现象,因为它求的是具有最小均方误差的无偏估计。显而易见,如果模型欠拟合将不能取得最好的预测效果。所以有些方法允许在估计中引人一些偏差,从而降低预测的均方误差。其中的一个方法是局部加权线性回归(LocallyWeightedLinearRegression,LWLR )。在该算法中,我们给待预测点附近的每个点赋予一定的权重.于是公式变为:

    ,W是(m,m)矩阵,m表示样本数。

    LWLR使用 “核”(与支持向量机中的核类似)来对附近的点赋予更高的权重。核的类型可以自由选择,最常用的核就是高斯核,高斯核对应的权重如下:

    ,k需要优化选择。

    局部加权线性回归也存在一个问题,即增加了计算量,因为它对每个点做预测时都必须使用整个数据集,而不是计算出回归系数得到回归方程后代入计算即可。因此该算法不被推荐。

    标准回归与局部加权回归python2实现

    from numpy import *

    #该函数打开一个用tab键分割的文本文件

    def loadDataSet(fileName): #general function to parse tab -delimited floats

    numFeat = len(open(fileName).readline().split('\t')) - 1 #get number of fields

    dataMat = []; labelMat = []

    fr = open(fileName)

    for line in fr.readlines():

    lineArr =[]

    curLine = line.strip().split('\t')

    for i in range(numFeat):

    lineArr.append(float(curLine[i]))

    dataMat.append(lineArr)

    labelMat.append(float(curLine[-1]))

    return dataMat,labelMat

    def standRegres(xArr,yArr):#该函数用来计算最佳拟合直线

    xMat = mat(xArr); yMat = mat(yArr).T#读入x和y并将它们保存到矩阵中

    xTx = xMat.T*xMat

    if linalg.det(xTx) == 0.0:#判断行列式是否为0,直接调用numpy的linalg线性代数的库来计算行列式

    print "This matrix is singular, cannot do inverse"

    return

    ws = xTx.I * (xMat.T*yMat)#行列式非0,计算系数并返回

    return ws

    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)#lwlrtest函数主要用于调用lwlr函数

    return yHat

    def lwlrTestPlot(xArr,yArr,k=1.0): #same thing as lwlrTest except it sorts X first

    yHat = zeros(shape(yArr)) #easier for plotting

    xCopy = mat(xArr)

    xCopy.sort(0)

    for i in range(shape(xArr)[0]):

    yHat[i] = lwlr(xCopy[i],xArr,yArr,k)

    return yHat,xCopy

    if __name__=="__main__":

    dataMat,labelMat=loadDataSet('C:\Users\HZF\Desktop\machinelearninginaction\Ch08\ex0.txt')

    #print (mat(dataMat[0:2]))[:,1]

    #print (mat(labelMat[0:2])).T[:,0]

    import matplotlib.pyplot as plt#导入matplotlib库用于画散点图进行比较

    fig=plt.figure()

    ax=fig.add_subplot(111)#add_subplot(111)函数也可写成add_subplot(1,1,1),意思是将画布分布在1行1列从左到右从上到下的第一个模块

    ws=standRegres(dataMat,labelMat)#计算系数向量

    #print ws

    yHat=(mat(dataMat))*ws#计算最优回归值

    #以下代码是标准线性回归的散点图与最佳拟合的图像

    #ax.scatter((mat(dataMat))[:,1].flatten().A[0],(mat(labelMat)).T[:,0].flatten().A[0])#数据集散点图

    #xCopy=(mat(dataMat)).copy()

    #xCopy.sort(0)#对点按照升序排序

    #yHat=xCopy*ws#画最佳拟合直线

    #ax.plot(xCopy[:,1],yHat)

    #plt.show()

    pc=corrcoef(yHat.T,labelMat)#计算yHat与labelMat的相关系数,即相关矩阵

    #print pc

    #ws=lwlr(dataMat[0],dataMat,labelMat,k=1.0)

    yHat=lwlrTest(dataMat,dataMat,labelMat,0.02)

    print yHat

    #以下代码是局部线性回归的散点图与最佳拟合的图像

    srtInd=(mat(dataMat))[:,1].argsort(0)

    xSort=(mat(dataMat))[srtInd][:,0,:]

    ax.plot(xSort[:,1],yHat[srtInd])

    ax.scatter((mat(dataMat))[:,1].flatten().A[0],(mat(labelMat)).T.flatten().A[0],s=2,c='red')

    plt.show()

    以上就是标准回归(线性回归)与局部加权回归算法的理论与python2实现过程(主要是针对最小二乘与局部加权的实现),会尽快补充这两种算法的应用与其他回归算法!

    参考文献

    1、机器学习经典算法详解及Python实现--线性回归(Linear Regression)算法

    2、《机器学习实战》(书)

    相关文章

      网友评论

        本文标题:第二十一章 regression算法——线性回归&局部加

        本文链接:https://www.haomeiwen.com/subject/epbmattx.html