机器学习算法学习---处理回归问题常用算法(一)

1、线性回归

优点:结果易于理解,计算上不复杂。

缺点:对非线性的数据拟合不好。

适用数据:数值型、标称型。

回归的目的是预测数值型的目标值。最直接的办法是依据输入写出一个目标值的计算公式;这就是回归方程,其中的未知系数称作回归系数,求这些回归系数的过程就是回归。

线性回归意味着可以将输入项分别乘以一些常量,再将结果加起来得到输出。

Y=XTw如何求w,常用方法就是找出使误差最小的w。

平方误差可以写做:sum(yi-xiTw)2

用矩阵表示:(y-Xw)T(y-Xw),对w求导,得到XT(Y-Xw),令其等于0,求解出w如:w'=(XTX)-1XTy。该方法也称作OLS(普通最小二乘法)。

模型效果可以通过计算预测值和真实值的相关系数来衡量,numpy库的corrcoef(yEstimate,yActual)可以计算;相关性越高,模型效果越好。

代数求解:

 

第一:用所给样本求出两个相关变量的(算术)平均值:
x_=(x1+x2+x3+...+xn)/n
y_=(y1+y2+y3+...+yn)/n    

第二:分别计算分子和分母:(两个公式任选其一)
分子=(x1y1+x2y2+x3y3+...+xnyn)-nx_Y_
分母=(x1^2+x2^2+x3^2+...+xn^2)-n*x_^2

第三:计算b:b=分子/分母

python实现:

 

 

普通最小二乘回归
from numpy import *
#数据导入
def loadDataSet(filename):
numFeat=len(open(filename).readline().split())-1
dataMat=[]
labelMat=[]
f=open(filename)
lines=f.readlines()
for line in lines:
temp=[]
line=line.strip().split()
for i in range(numFeat):
temp.append(float(line[i]))
dataMat.append(temp)
labelMat.append(float(line[-1]))
return dataMat,labelMat
#标准回归函数
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

 

2、局部加权线性回归

线性回归的问题:可能出现欠拟合现象;原因:求的是具有最小均方误差的无偏估计;解决:引入一些偏差。

LWLR算法:给待预测点附近的每个点赋予一定的权重,然后在这个子集上基于最小均方差来进行普通的回归。

 

w'=(XTWX)-1XTWy,其中W是一个矩阵,用来给每个数据点赋予权重。

LWLR使用“核”来对附近的点赋予更高的权重。最常用的核是高斯核,其对应权重如下:

w(i,i)=exp(|x(i)-x|/(-2k2)),其中x(i)是预测点,k是唯一考虑的参数,决定了对附近点赋予多大的权重。

如果k取值较大,和标准回归类似,可能出现欠拟合现象;若k取值较小,则可能出现过拟合现象。

 

局部线性回归的问题:增加了计算量(因为其对每个点预测时都必须使用整个数据集)。

python实现:

 

局部加权线性回归
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):
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):
m=shape(testArr)[0]
yHat=zeros(m)
for i in range(m):
yHat[i]=lwlr(testArr[i],xArr,yArr,k)
return yHat

 

3、岭回归

如果特征比样本点还多,用前面的方法不可行,因为输入数据矩阵不再是满秩矩阵,求逆会出错。

岭回归就是在矩阵XTX上加一个λI从而使其非奇异,回归系数的计算公式变成:

 

w'=(XTX+λI)-1XTy

岭回归最先用于处理特征数多于样本数的情况,现在也应用于在估计中加入偏差,从而得到更好的估计。

通过引入λ来限制了所有w之和,通过引入该惩罚项,能够减少不重要的参数,该技术在统计学中也叫做缩减。

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

λ非常小时,系数与普通回归一样;而λ非常大时,所有回归系数缩减为0;可以在中间某处找到使得预测结果最好的λ值。

python实现:

 

 

岭回归
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
def ridgeTest(xArr,yArr):
xMat=mat(xArr);yMat=mat(yArr).T
yMean = mean(yMat,0)
yMat=yMat - yMean
xMeans=mean(xMat,0)
xVar=var(xMat,0)
xMat=(xMat - xMeans)/xVar
numTestPts=30#30个不同的lambda值进行测试,选最优
wMat=zeros((numTestPts,shape(xMat)[1]))
for i in range(numTestPts):
ws=ridgeRegres(xMat,yMat,exp(i-10))
wMat[i,:]=ws.T
return wMat

 

4、lasso(另一个缩减方法)

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

sum(wk2)<=λ

lasso方法也对回归系数做了限定,对应的约束条件如下:

sum(|wk|)<=λ

这个约束条件使用绝对值取代平方和。在λ足够小的时候,一些系数会因此被迫缩减到0,这个特性可以帮助我们更好地理解数据。

缺点:计算复杂。

5、前向逐步回归

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

python实现:

 

前向逐步回归
#误差
def rssError(yArr,yHatArr):
return ((yArr - yHatArr)**2).sum()
def stageWise(xArr,yArr,eps=0.01,numIt=100):#eps表示每次迭代需要调整的步长;numIt表示迭代次数
xMat=mat(xArr);yMat=mat(yArr).T
yMean=mean(yMat,0)
yMat=yMat - yMean
xMat=regularize(xMat)
m,n=shape(xMat)
returnMat=zeros((numIt,n))
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()
returnMat[i,:]=ws.T
return returnMat

 

 

6、权衡偏差与方差

https://blog.csdn.net/qq_30490125/article/details/52401773 

posted @ 2019-05-08 17:14  2048的渣渣  阅读(2914)  评论(0编辑  收藏  举报