前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >机器学习 学习笔记(5) 线性回归

机器学习 学习笔记(5) 线性回归

作者头像
发布2018-09-03 18:14:55
7940
发布2018-09-03 18:14:55
举报
文章被收录于专栏:WD学习记录WD学习记录

线性回归

给定数据集D={(x1,y1),(x2,y2),...,(xm,ym)},其中xi=(xi1;xi2;xi3;...;xid),yi是实数。线性回归试图学得一个线性模型以尽可能准确地预测实值输出标记。

对离散属性,若属性值之间存在“序”关系,可通过连续化将其转化为连续值;若属性值之间不存在序关系,假定有k个属性值,则通常转化为k维向量。

线性回归试图学得

f(x_i)=wx_i+b
f(x_i)=wx_i+b

,使得

f(x_i)\simeq y_i
f(x_i)\simeq y_i

要确定w和b,使得均方误差最小化:

(w^*,b^*)=\arg \min \limits_{(w,b)} \sum_{i=1}^m(f(x_i)-y_i)^2=\arg \min \limits_{(w,b)} \sum_{i=1}^m(y_i-wx_i-b)^2
(w^*,b^*)=\arg \min \limits_{(w,b)} \sum_{i=1}^m(f(x_i)-y_i)^2=\arg \min \limits_{(w,b)} \sum_{i=1}^m(y_i-wx_i-b)^2

用均方误差最小化来进行模型求解的方法称为“最小二乘法”。在线性回归中,最小二乘法就是试图找到一条直线,使所有样本到直线上的欧式距离之和最小。

求解w和b使得

E_{(w,b)}=\sum_{i=1}^m(y_i-wx_i-b)^2
E_{(w,b)}=\sum_{i=1}^m(y_i-wx_i-b)^2

最小化的过程,称为线性回归模型的最小二乘参数估计,可以将E(w,b)分别对w和b求导,得到

\frac {\partial E_{(w,b)}}{\partial w}=2(w \sum_{i=1}^mx^2_i- \sum_{i=1}^m(y_i-b)x_i)
\frac {\partial E_{(w,b)}}{\partial w}=2(w \sum_{i=1}^mx^2_i- \sum_{i=1}^m(y_i-b)x_i)

\frac{\partial E_{(w,b)}}{\partial b}=2(mb-\sum_{i=1}^2(y_i-wx_i))
\frac{\partial E_{(w,b)}}{\partial b}=2(mb-\sum_{i=1}^2(y_i-wx_i))

,令这两个式子都为0,得到w和b的闭式解。

w=\frac{\sum_{i=1}^my_i(x_i-\bar x)}{\sum_{i=1}^mx^2_i-\frac{1}{m}(\sum_{i=1}^mx_i)^2}
w=\frac{\sum_{i=1}^my_i(x_i-\bar x)}{\sum_{i=1}^mx^2_i-\frac{1}{m}(\sum_{i=1}^mx_i)^2}

b=\frac{1}{m} \sum_{i=1}^m(y_i-wx_i)
b=\frac{1}{m} \sum_{i=1}^m(y_i-wx_i)

其中

\bar x
\bar x

为x的均值。

当每个x有若干个属性时 ,试图学得

f(x_i)=w^Tx_i+b
f(x_i)=w^Tx_i+b

最小化损失函数为:

w^*=\arg \min \limits_{w} (y-Xw)^T(y-Xw)
w^*=\arg \min \limits_{w} (y-Xw)^T(y-Xw)

,求导得

\frac{\partial E_w}{\partial w}=2X^T(Xw-y)
\frac{\partial E_w}{\partial w}=2X^T(Xw-y)

,最终得到

w^*=(X^TX)^{-1}X^Ty
w^*=(X^TX)^{-1}X^Ty

但是当XX^T不是满秩矩阵时,会求出多个w,选择哪一个解作为输出将由学习算法的归纳偏好决定,常见的做法是引入正则化。

代码语言:javascript
复制
# 代码和数据集源自于机器学习实战,可见https://github.com/AnnDWang/MachineLearning/blob/master/thirdbook/ch8/regression.py
from numpy import *

def loadDataSet(fileName):
    numFeat=len(open(fileName).readline().split('\t'))-1
    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 standRgres(xArr,yArr):
    xMat=mat(xArr)
    yMat=mat(yArr).T
    xTx=xMat.T*xMat
    if linalg.det(xTx)==0.0:
        print('the matrix is singular, cannot do inverse')
        return
    ws=xTx.I*(xMat.T*yMat)
    return ws

xArr,yArr=loadDataSet('ex0.txt')
ws=standRgres(xArr,yArr)
print(ws)
xMat=mat(xArr)
yMat=mat(yArr)
yHat=xMat*ws

# 绘制出数据集散点图和最佳拟合直线图
import  matplotlib.pyplot as plt
fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(xMat[:,1].flatten().A[0],yMat.T[:,0].flatten().A[0])
xCopy=xMat.copy()
xCopy.sort(0)
yHat=xCopy*ws
ax.plot(xCopy[:,1],yHat)
plt.show()

实验结果如图:

局部加权线性回归

线性回归的一个问题是可能出现欠拟合现象,因为它求得是具有最小均方误差的无偏估计,如果模型欠拟合将不能取得最好的预测效果。所以有些方法允许在估计中引入一些偏差,从而降低预测的均方误差。

其中的一个方法是局部加权线性回归(Locally Weighted Linear Regression,LWLR),在该计算方法中,给每个点赋予一定的权重,在这个子集上基于最小均方误差来进行普通的回归。这种算法每次预测均需要事先取出对应的数据子集,该算法解出的回归系数w形式如下:

w=(X^TWX)^{-1}X^TWy
w=(X^TWX)^{-1}X^TWy

W
W

是一个矩阵,用来给每个数据点赋予权重。

LWLR使用“核”来对附近的点赋予更高的权重,核的类型可以自由选择,最常用的就是高斯核,高斯核对应的权重如下:

w(i,i)=exp(\frac{|x^{(i)}-x|}{-2k^2})
w(i,i)=exp(\frac{|x^{(i)}-x|}{-2k^2})

这样就构成了一个只包含对角元素的权重矩阵,点x与x(i)越近,w(i,i)越大。k决定了对附近的点赋予多大的权重,是使用LWLR时唯一需要考虑的参数。

代码如下:

代码语言:javascript
复制
# 代码和数据集源自于机器学习实战
# 局部加权线性回归函数
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

xArr,yArr=loadDataSet('ex0.txt')
print(lwlr(xArr[0],xArr,yArr,1.0))
print(lwlr(xArr[0],xArr,yArr,0.001))
yHat=lwlrTest(xArr,xArr,yArr,0.003)
xMat=mat(xArr)
srtInd=xMat[:,1].argsort(0)
xSort=xMat[srtInd][:,0,:]

fig=plt.figure()
ax=fig.add_subplot(111)
ax.plot(xSort[:,1],yHat[srtInd])
ax.scatter(xMat[:,1].flatten().A[0],mat(yArr).T.flatten().A[0],s=2,c='red')
plt.show()

结果如图:

局部加权线性回归存在的问题,增加了计算量,因为对每个点做预测时都需要用到整个数据集

岭回归

简单来说,岭回归就是在

X^TX
X^TX

上增加一个

\lambda I
\lambda I

使得矩阵非奇异,从而能够进行求逆,矩阵I大小为mxm,对角线上元素为1,其他元素全为0。岭回归的计算公式为:

w=(X^TX+\lambda I)^{-1}X^Ty
w=(X^TX+\lambda I)^{-1}X^Ty

岭回归最先用来处于特征多于样本数的情况,现在也用于在估计中加入偏差,从而得到更高的估计,这里通过引入

\lambda
\lambda

来限制了所有的w的和,通过引入该惩罚项,能够减少不重要的参数,这个技术在统计学中也叫做缩减。缩减方法可以去掉不重要的参数,因此能够更好地理解数据。

代码如下:

代码语言:javascript
复制
# 代码和数据集主要源自于机器学习实战
# 岭回归

# 用于计算回归系数,
# 实现了给定了lambda下的岭回归求解
# 如果没有指定lambda,默认为0.2
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

# 用于在一组lambda上测试结果
# 为了使用岭回归和缩减技术,首先需要对特征进行标准化处理
# 具体的做法是所有特征都减去各自的均值并处以方差
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
    wMat=zeros((numTestPts,shape(xMat)[1]))
    for i in range(numTestPts):
        ws=ridgeRegres(xMat,yMat,exp(i-10))
        wMat[i,:]=ws.T
    return wMat
abX,abY=loadDataSet('abalone.txt')
ridgeWeights=ridgeTest(abX,abY)

fig=plt.figure()
ax=fig.add_subplot(111)
ax.plot(ridgeWeights)
plt.show()

岭回归的系数变化图如下:

图像为回归系数与

\lambda
\lambda

的关系,

\lambda
\lambda

最小时,系数的原始值和线性回归一样,

\lambda
\lambda

非常大时,系数全部缩减为0,在中间某部分的某值可以取得最好的预测效果。为了定量找到最佳预测值,还需要进行交叉验证。

还有梯度下降法求解线性回归方程。

梯度下降和正规方程对比:

梯度下降法:

需要选择学习率

\alpha
\alpha

,需要多次迭代,特征值范围相差太大时,需要进行特征缩放,当特征数n很大时,能够工作地很好。

正规方程对比:

不需要选择学习率

\alpha
\alpha

,不需要多次迭代,不需要进行特征缩放,当n很大时,运算很慢,因为矩阵的时间复杂度是

O(N^3)
O(N^3)
O(N^3)
O(N^3)

O(N^3)。

参考:

  1. 《机器学习》
  2. 《机器学习实战》
  3. 机器学习:线性回归(Linear Regression)小项目
  4. 机器学习之线性回归、多项式回归
  5. 线性回归原理和实现基本认识
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年08月11日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 线性回归
  • 局部加权线性回归
  • 岭回归
  • 梯度下降和正规方程对比:
  • 参考:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档