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

理论部分

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

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

1、回归的定义

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

2、多元线性回归

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

《第二十一章 regression算法——线性回归&局部加权回归算法(上)》

其中,n=特征数目;

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

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

《第二十一章 regression算法——线性回归&局部加权回归算法(上)》

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

3、广义线性回归

用广义的线性函数:

《第二十一章 regression算法——线性回归&局部加权回归算法(上)》

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

线性回归的求解

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

《第二十一章 regression算法——线性回归&局部加权回归算法(上)》

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

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

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

1、梯度下降法

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

《第二十一章 regression算法——线性回归&局部加权回归算法(上)》

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

2、普通最小二乘法

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

《第二十一章 regression算法——线性回归&局部加权回归算法(上)》

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

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

3、局部加权线性回归

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

《第二十一章 regression算法——线性回归&局部加权回归算法(上)》

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

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

《第二十一章 regression算法——线性回归&局部加权回归算法(上)》

,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、《机器学习实战》(书)

    原文作者:H2016
    原文地址: https://www.jianshu.com/p/c47346d85194
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞