机器学习实战 第八章 预测数值型数据:回归

第八章 预测数值型数据:回归

  • 8.1用线性回归找到最佳拟合直线
  • 8.2局部加权线性回归
  • 8.3示例:预测鲍鱼的年龄
  • 8.4缩减系数来“理解”数据
    • 8.4.1岭回归
    • 8.4.2lasso
    • 8.4.3前向逐步回归
  • 8.5权衡偏差和方差
  • 8.6小结

    前面我们介绍了分类,分类的目标变量是标称型数据,本章将会对连接型的数据作出预测。

8.1用线性回归找到最佳拟合直线

线性回归的优缺点:

优点:结果易于理解,计算上不复杂。
缺点:对非线性的数据拟合不好。
适用数据类型:数值型和标称型数据。

回归的一般方法:

1、收集数据:采用任意方法收集数据。
2、准备数据:回归需要数值型数据,标称型数据将被转成二值型数据。
3、分析数据:绘出数据的可视化二维图将有助于对数据作出理解和分析,在采用缩减发求得新回归系数之后,可以将新拟合线绘在图上作为对比。
4、训练算法:找到回归系数。
5、测试算法:使用R2或者预测值和数据的拟合度,来分析模型的效果。
6、使用算法:使用回归,可以在给定输入的时候预测出一个数值,这是对分类方法的提升,因为这样可以预测连续型数据而不仅仅是离散的类别标签。

    回归的目的是预测数值型的目标值。最直接的方法就是找到回归方程 Y 1 = X 1 T w Y_{1}=X_{1}^{T}w Y1=X1Tw。其中 w w w称作回归系数,求这些回归系数的过程就是回归。一个常用的方法就是找出使误差最小的 w w w。这里的误差是指预测 y y y值和真实 y y y值之间的平方差值。由于使用该误差的简单累加将使得正差值和负差值相互抵消,所以我们采用平方误差。
    平方误差可以写做:
∑ i = 1 m ( y i − x i T w ) 2 \sum_{i=1}^{m}(y_{i}-x_{i}^{T}w)^{2} i=1m(yixiTw)2
    用矩阵表示还可以写做 ( y − X w ) T ( y − X w ) (y-Xw)^{T}(y-Xw) (yXw)T(yXw)。如果对 w w w求导,得到 X T ( y − X w ) X^{T}(y-Xw) XT(yXw),令其等于零,解出 w w w如下:
w ^ = ( X T X ) − 1 X T y \widehat{w}=(X^{T}X)^{-1}X^{T}y w =(XTX)1XTy
    这个式子表示是当前可以估计出的w的最优解。这样我们就可以从最初始w的值,计算预测u的值,然后计算误差,再通过上式计算一轮新的w值,然后再预测u的值,再计算误差…如此迭代(这样的迭代求最优解一般用在梯度下降或上升算法里)。如果训练集可以直接用上式得到最优解,那么他将不需要迭代,直接与输入训练集相乘即可得到预测值。
    从现有数据上估计出的w可能并不是数据中的真实w值,所以这里使用了一个"帽"符号来表示它仅是w的一个最佳估计。值得注意的是,上述公式中包含逆矩阵,也就是说,这个方程只在逆矩阵存在的时候使用,也即是这个矩阵是一个方阵,并且其行列式不为0。
    上述的最佳w求解是统计学中的常见问题,除了矩阵方法外还有很多其他方法可以解决。通过调用NumPy库里的矩阵方法,我们可以仅使用几行代码就完成所需功能。该方法也称作OLS, 意思是“普通小二乘法”(ordinary least squares)。

    下图为一组数据的散点图,接下来学习如何给出这组数据的最佳拟合曲线。
机器学习实战 第八章 预测数值型数据:回归_第1张图片

创建一个regression.py文件,添加下列代码:

import matplotlib.pyplot as plt
import numpy as np

def loadDataSet(fileName):
    """
    函数说明:加载数据
    Parameters:
        fileName - 文件名
    Returns:
        xArr - x数据集
        yArr - y数据集
    """
    numFeat = len(open(fileName).readline().split('\t')) - 1
    xArr = []; yArr = []
    fr = open(fileName)
    for line in fr.readlines():
        lineArr =[]
        curLine = line.strip().split('\t')
        for i in range(numFeat):
            lineArr.append(float(curLine[i]))
        xArr.append(lineArr)
        yArr.append(float(curLine[-1]))
    return xArr, yArr

def standRegres(xArr,yArr):
    """
    函数说明:计算回归系数w
    Parameters:
        xArr - x数据集
        yArr - y数据集
    Returns:
        ws - 回归系数
    """
    xMat = np.mat(xArr); yMat = np.mat(yArr).T
    xTx = xMat.T * xMat                            #根据文中推导的公示计算回归系数
    if np.linalg.det(xTx) == 0.0:
        print("矩阵为奇异矩阵,不能求逆")
        return
    ws = xTx.I * (xMat.T*yMat)
    return ws

def plotRegression():
    """
    函数说明:绘制回归曲线和数据点
    Parameters:
        无
    Returns:
        无
    """
    xArr, yArr = loadDataSet('ex0.txt')                                    #加载数据集
    ws = standRegres(xArr, yArr)                                        #计算回归系数
    xMat = np.mat(xArr)                                                    #创建xMat矩阵
    yMat = np.mat(yArr)                                                    #创建yMat矩阵
    xCopy = xMat.copy()                                                    #深拷贝xMat矩阵
    xCopy.sort(0)                                                        #排序
    yHat = xCopy * ws                                                     #计算对应的y值
    fig = plt.figure()
    ax = fig.add_subplot(111)                                            #添加subplot
    ax.plot(xCopy[:, 1], yHat, c = 'red')                                #绘制回归曲线
    ax.scatter(xMat[:,1].flatten().A[0], yMat.flatten().A[0], s = 20, c = 'blue',alpha = .5)                #绘制样本点
    plt.title('DataSet')                                                #绘制title
    plt.xlabel('X')
    plt.show()

测试代码:

import regression
import numpy as np

regression.plotRegression()
xArr, yArr = regression.loadDataSet('ex0.txt')
print("x的前两条数据:\n",xArr[:2])
ws = regression.standRegres(xArr,yArr)
print("ws:\n",ws)
xMat = np.mat(xArr)
yMat = np.mat(yArr)      
yHat = xMat * ws
print("相关系数:\n",np.corrcoef(yHat.T,yArr))

结果:
机器学习实战 第八章 预测数值型数据:回归_第2张图片
机器学习实战 第八章 预测数值型数据:回归_第3张图片
分析:
    程序中使用了NumPy库提供的相关系数计算方法( corrcoef()函数 )来计算预测值和真实值的相关性。可以看到,对角线上的数据是1.0,因为yMat和自己的匹配是完美的,而YHat和yMat的相关系数为0.98。
    最佳拟合直线方法将数据视为直线进行建模,具有十分不错的表现。数据当中似乎还存在其他的潜在模式。那么如何才能利用这些模式呢?我们可以根据数据来局部调整预测,下面就会介绍这种方法。

8.2局部加权线性回归

    线性回归的一个问题是有可能出现欠拟合现象,因为它求的是具有小均方误差的无偏估计。显而易见,如果模型出现欠拟合,将不能取得好的预测效果。所以有些方法允许在估计中引入一些偏差,从而降低预测的均方误差。
    其中的一个方法是局部加权线性回归(Locally Weighted Linear Regression,LWLR)。在该方法中,我们给待预测点附近的每个点赋予一定的权重。与kNN一样,这种算法每次预测均需要事先选取出对应的数据子集。该算法解出回归系数W的形式如下:
w ^ = ( X T W X ) − 1 X T W y \widehat{w}=(X^{T}WX)^{-1}X^{T}Wy w =(XTWX)1XTWy
    其中W是一个矩阵,这个公式跟上面推导的公式的区别就在于W,它用来给每个点赋予权重。
    局部加权线性回归使用“核”(与支持向量机中的核类似)来对附近的点赋予更高的权重。核的类型可以自由选择,最常用的核就是高斯核,高斯核对应的权重如下:
w ( i , i ) = e x p ( ∣ x ( i ) − x ∣ − 2 k 2 ) w(i,i)=exp(\frac{\left | x^{(i)}-x\right |}{-2k^{2}}) w(i,i)=exp(2k2 x(i)x )
    下图可以看到参数k与权重的关系:
机器学习实战 第八章 预测数值型数据:回归_第4张图片

    根据上述公式,我们可以通过改变k的值,调节回归效果。
在regression.py中添加下列代码:

"""
函数说明:使用局部加权线性回归计算回归系数w
Parameters:
    testPoint - 测试样本点
    xArr - x数据集
    yArr - y数据集
    k - 高斯核的k,自定义参数
Returns:
    ws - 回归系数
"""
def lwlr(testPoint, xArr, yArr, k = 1.0):
    xMat = np.mat(xArr); yMat = np.mat(yArr).T
    m = np.shape(xMat)[0]
    weights = np.mat(np.eye((m)))                                        #创建权重对角矩阵,200行
    for j in range(m):                                                  #遍历数据集计算每个样本的权重
        diffMat = testPoint - xMat[j, :]
        weights[j, j] = np.exp(diffMat * diffMat.T/(-2.0 * k**2))
    xTx = xMat.T * (weights * xMat) #按照公式进行计算
    if np.linalg.det(xTx) == 0.0:
        print("矩阵为奇异矩阵,不能求逆")
        return
    ws = xTx.I * (xMat.T * (weights * yMat))                            #计算回归系数
    return testPoint * ws

"""
函数说明:局部加权线性回归测试
Parameters:
    testArr - 测试数据集
    xArr - x数据集
    yArr - y数据集
    k - 高斯核的k,自定义参数
Returns:
    ws - 回归系数
"""
def lwlrTest(testArr, xArr, yArr, k=1.0):
    m = np.shape(testArr)[0]                                            #计算测试数据集大小,200行
    #print(m)
    yHat = np.zeros(m)
    for i in range(m):                                                    #对每个样本点进行预测
        yHat[i] = lwlr(testArr[i],xArr,yArr,k)#第一个参数testArr[i]表示训练集中的每一行,每次拿一个样本进行预测
    return yHat

"""
    函数说明:绘制多条局部加权回归曲线
"""

def plotlwlrRegression():
    #font = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=14)
    xArr, yArr = loadDataSet('ex0.txt')                                    #加载数据集
    yHat_1 = lwlrTest(xArr, xArr, yArr, 1.0)                            #核k=1.0时,根据局部加权线性回归计算yHat
    yHat_2 = lwlrTest(xArr, xArr, yArr, 0.01)                           #核k=0.01时,根据局部加权线性回归计算yHat
    yHat_3 = lwlrTest(xArr, xArr, yArr, 0.003)                          #核k=0.003时,根据局部加权线性回归计算yHat
    xMat = np.mat(xArr)                                                    #创建xMat矩阵
    yMat = np.mat(yArr)                                                    #创建yMat矩阵
    srtInd = xMat[:, 1].argsort(0)                                        #排序,返回索引值
    xSort = xMat[srtInd][:,0,:]
    fig, axs = plt.subplots(nrows=3, ncols=1,sharex=False, sharey=False, figsize=(10,8))
    axs[0].plot(xSort[:, 1], yHat_1[srtInd], c = 'red')                        #绘制回归曲线
    axs[1].plot(xSort[:, 1], yHat_2[srtInd], c = 'red')                        #绘制回归曲线
    axs[2].plot(xSort[:, 1], yHat_3[srtInd], c = 'red')                        #绘制回归曲线
    axs[0].scatter(xMat[:,1].flatten().A[0], yMat.flatten().A[0], s = 20, c = 'blue', alpha = .5)                #绘制样本点
    axs[1].scatter(xMat[:,1].flatten().A[0], yMat.flatten().A[0], s = 20, c = 'blue', alpha = .5)                #绘制样本点
    axs[2].scatter(xMat[:,1].flatten().A[0], yMat.flatten().A[0], s = 20, c = 'blue', alpha = .5)                #绘制样本点
    #设置标题,x轴label,y轴label
    axs0_title_text = axs[0].set_title(u'k=1.0')
    axs1_title_text = axs[1].set_title(u'k=0.01')
    axs2_title_text = axs[2].set_title(u'k=0.003')
    plt.setp(axs0_title_text, size=8, weight='bold', color='red')
    plt.setp(axs1_title_text, size=8, weight='bold', color='red')
    plt.setp(axs2_title_text, size=8, weight='bold', color='red')
    plt.xlabel('X')
    plt.show()


# 定义预测误差函数,用于分析预测误差的大小
def rssError(yArr, yHat):
    return ((yArr - yHat) ** 2).sum()

测试代码:

import regression

regression.plotlwlrRegression()
xArr,yArr = regression.loadDataSet('ex0.txt')
#局部加权线性回归预测结果展示:
y0 = regression.lwlr(xArr[0],xArr,yArr,1.0)
y1 = regression.lwlr(xArr[0],xArr,yArr,0.001)
print("y0:\n",y0)
print("y1:\n",y1)

#比较一下k=1.0,0.01,0.003时的拟合效果
#k=1.0
yHat1 =regression.lwlrTest(xArr,xArr,yArr,1.0)
print("k=1.0时,预测误差:",regression.rssError(yArr,yHat1))
#k=0.01
yHat2 = regression.lwlrTest(xArr,xArr,yArr,0.01)
print("k=0.01时,预测误差:",regression.rssError(yArr,yHat2))
#k=0.003
yHat3 = regression.lwlrTest(xArr,xArr,yArr,0.003)
print("k=0.03时,预测误差:",regression.rssError(yArr,yHat3))

结果:
机器学习实战 第八章 预测数值型数据:回归_第5张图片
机器学习实战 第八章 预测数值型数据:回归_第6张图片
分析:
    可以看到,k=1.0时,模型效果与最小二乘法差不多,k=0.01时,可以挖出数据的潜在规律,而k=0.003时,则考虑了太多的噪声,进而导致了过拟合。
    局部加权线性回归同样存在一个问题,即增加了计算量,因为它对每一个点做预测时都必须使用整个数据集,k=0.01时可以得到很好的估计,但是,从图中也可以看出,大多数数据点的权重都接近0,若是可以避免这些计算,则可以减少程序运行时间从而缓解因计算量增加带来的问题。

8.3示例:预测鲍鱼的年龄

测试代码:

import regression
import numpy as np

abX, abY = regression.loadDataSet('abalone.txt')
print('训练集与测试集相同:局部加权线性回归,核k的大小对预测的影响:')
yHat01 = regression.lwlrTest(abX[0:99], abX[0:99], abY[0:99], 0.1)
yHat1 = regression.lwlrTest(abX[0:99], abX[0:99], abY[0:99], 1)
yHat10 = regression.lwlrTest(abX[0:99], abX[0:99], abY[0:99], 10)
print('k=0.1时,误差大小为:',regression.rssError(abY[0:99], yHat01.T))
print('k=1  时,误差大小为:',regression.rssError(abY[0:99], yHat1.T))
print('k=10 时,误差大小为:',regression.rssError(abY[0:99], yHat10.T))
print('')
print('训练集与测试集不同:局部加权线性回归,核k的大小是越小越好吗?更换数据集,测试结果如下:')
yHat01 = regression.lwlrTest(abX[100:199], abX[0:99], abY[0:99], 0.1)
yHat1 = regression.lwlrTest(abX[100:199], abX[0:99], abY[0:99], 1)
yHat10 = regression.lwlrTest(abX[100:199], abX[0:99], abY[0:99], 10)
print('k=0.1时,误差大小为:',regression.rssError(abY[100:199], yHat01.T))
print('k=1  时,误差大小为:',regression.rssError(abY[100:199], yHat1.T))
print('k=10 时,误差大小为:',regression.rssError(abY[100:199], yHat10.T))
print('')
print('训练集与测试集不同:简单的线性归回与k=1时的局部加权线性回归对比:')
print('k=1时,误差大小为:', regression.rssError(abY[100:199], yHat1.T))
ws = regression.standRegres(abX[0:99], abY[0:99])
yHat = np.mat(abX[100:199]) * ws
print('简单的线性回归误差大小:', regression.rssError(abY[100:199], yHat.T.A))

结果:
机器学习实战 第八章 预测数值型数据:回归_第7张图片

分析:
    可以看到,当k=0.1时,训练集误差小,但是应用于新的数据集之后,误差反而变大了。这就是经常说道的过拟合现象。
    我们训练的模型要保证测试集准确率高,这样训练出的模型才可以应用于新的数据,也就是要加强模型的普适性。可以看到,当k=1时,局部加权线性回归和简单的线性回归得到的效果差不多。这也表明一点,必须在未知数据上比较效果才能选取到最佳模型。那么最佳的核大小是10吗?或许是,但如果想得到更好的效果,应该用10个不同的样本集做10次测试来比较结果。
    本示例展示了如何使用局部加权线性回归来构建模型,可以得到比普通线性回归更好的效果。局部加权线性回归的问题在于,每次必须在整个数据集上运行。也就是说为了做出预测,必须保存所有的训练数据。训练的模型要在测试集比较它们的效果,而不是在训练集上。

8.4缩减系数来“理解”数据

    如果特征比样本点还多(n>m),也就是说输入数据的矩阵 X X X不是满秩矩阵。非满秩矩阵在求逆时会出现问题,即在计算 ( X T X ) − 1 (X^{T}X)^{-1} (XTX)1的时候会出错。因此不可以使用线性回归和之前的方法来做预测。
    为了解决这个问题,统计学家引入了岭回归的概念。

8.4.1岭回归

    简单说来,岭回归就是在矩阵 X T X X^{T}X XTX上加一个 λ I \lambda I λI从而使得矩阵非奇异,进而能对 X T X + λ I X^{T}X+\lambda I XTX+λI求逆。其中矩阵 I I I是一个m*n的单位矩阵, λ \lambda λ是一个用户定义的数值。这样,回归系数的计算公式就变成:
w ^ = ( X T X + λ I ) − 1 X T y \widehat{w}=(X^{T}X+\lambda I)^{-1}X^{T}y w =(XTX+λI)1XTy
    通过引入 λ \lambda λ来限制所有 w w w之和,通过引入该惩罚项,能够减少不重要的参数,这个技术在统计学中也叫做缩减。
    通过预测误差最小化得到 λ \lambda λ:数据获取之后,首先抽一部分数据用于测试,剩余的作为训练集用于训练参数 w w w。训练完毕后在测试集上测试预测性能。通过选取不同的 λ \lambda λ来重复上述测试过程,最终得到一个使预测误差最小的 λ \lambda λ

岭回归中的岭是什么?

    岭回归使用了单位矩阵乘以常量 λ \lambda λ,我们观察其中的单位矩阵 I I I,可以看到值1贯穿整个对角线,其余元素全是0。形象地,在0构成的平面上有一条1组成的“岭”,这就是岭回归中“岭”的由来。

在regression.py中添加下列代码:

def ridgeRegres(xMat, yMat, lam = 0.2):
    """
    函数说明:岭回归
    Parameters:
        xMat - x数据集
        yMat - y数据集
        lam - 缩减系数
    Returns:
        ws - 回归系数
    """
    xTx = xMat.T * xMat
    denom = xTx + np.eye(np.shape(xMat)[1]) * lam
    if np.linalg.det(denom) == 0.0:
        print("矩阵为奇异矩阵,不能转置")
        return
    ws = denom.I * (xMat.T * yMat)
    return ws

def ridgeTest(xArr, yArr):
    """
    函数说明:岭回归测试
    Parameters:
        xMat - x数据集
        yMat - y数据集
    Returns:
        wMat - 回归系数矩阵
    """
    xMat = np.mat(xArr); yMat = np.mat(yArr).T
    #数据标准化
    yMean = np.mean(yMat, axis = 0)                        #行与行操作,求均值,也就是求最后一列训练集真实值的平均值
    yMat = yMat - yMean                                    #数据减去均值,每一行y结果减去平均值
    xMeans = np.mean(xMat, axis = 0)                    #行与行操作,求均值
    xVar = np.var(xMat, axis = 0)                        #行与行操作,求方差
    xMat = (xMat - xMeans) / xVar                        #数据减去均值除以方差实现标准化
    numTestPts = 30                                        #30个不同的lambda测试
    wMat = np.zeros((numTestPts, np.shape(xMat)[1]))    #初始回归系数矩阵
    for i in range(numTestPts):                            #改变lambda计算回归系数
        ws = ridgeRegres(xMat, yMat, np.exp(i - 10))    #lambda以e的指数变化,最初是一个非常小的数,
        wMat[i, :] = ws.T                                 #计算回归系数矩阵
    return wMat

def plotwMat():
    """
    函数说明:绘制岭回归系数矩阵
    """
    abX, abY = loadDataSet('abalone.txt')
    redgeWeights = ridgeTest(abX, abY)
    print(redgeWeights)
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot(redgeWeights)
    ax_title_text = ax.set_title(u'The relationship between log(lambada) and regression coefficient')
    ax_xlabel_text = ax.set_xlabel(u'log(lambada)')
    ax_ylabel_text = ax.set_ylabel(u'regression coefficient')
    plt.setp(ax_title_text, size = 20, weight = 'bold', color = 'red')
    plt.setp(ax_xlabel_text, size = 10, weight = 'bold', color = 'black')
    plt.setp(ax_ylabel_text, size = 10, weight = 'bold', color = 'black')
    plt.show()

测试代码:

import regression

regression.plotwMat()

结果:
机器学习实战 第八章 预测数值型数据:回归_第8张图片
分析:
    在最左边,即λ最小时,可以得到所有系数的原始值(与线性回归一致);而在右边,系数全部缩减成0;在中间部分的某个位置,将会得到最好的预测结果。想要得到最佳的λ参数,可以使用交叉验证的方式获得。

8.4.2lasso

    不难证明,在增加如下约束时,普通的最小二乘法回归会得到与岭回归的一样的公式:
∑ k = 1 n w k 2 ≤ λ \sum_{k=1}^{n} w_{k}^{2}≤\lambda k=1nwk2λ
机器学习实战 第八章 预测数值型数据:回归_第9张图片

8.4.3前向逐步回归

    前向逐步回归算法可以得到与lasso差不多的效果,但更加简单。它属于一种贪心算法,即每一步都尽可能减少误差。一开始,所有的权重都设为1,然后每一步所做的决策是对某个权重增加或减少一个很小的值。
该算法的伪代码如下所示:
机器学习实战 第八章 预测数值型数据:回归_第10张图片
在regression.py中添加下列代码:

def regularize(xMat, yMat):
        """
        函数说明:数据标准化
        Parameters:
            xMat - x数据集
            yMat - y数据集
        Returns:
            inxMat - 标准化后的x数据集
            inyMat - 标准化后的y数据集
        """
        inxMat = xMat.copy()  # 数据拷贝
        inyMat = yMat.copy()
        yMean = np.mean(yMat, 0)  # 行与行操作,求均值
        inyMat = yMat - yMean  # 数据减去均值
        inMeans = np.mean(inxMat, 0)  # 行与行操作,求均值
        inVar = np.var(inxMat, 0)  # 行与行操作,求方差
        inxMat = (inxMat - inMeans) / inVar  # 数据减去均值除以方差实现标准化
        return inxMat, inyMat


def stageWise(xArr, yArr, eps=0.01, numIt=100):
        """
        函数说明:前向逐步线性回归
        Parameters:
            xArr - x输入数据
            yArr - y预测数据
            eps - 每次迭代需要调整的步长
            numIt - 迭代次数
        Returns:
            returnMat - numIt次迭代的回归系数矩阵
        """
        xMat = np.mat(xArr);
        yMat = np.mat(yArr).T  # 数据集
        xMat, yMat = regularize(xMat, yMat)  # 数据标准化
        m, n = np.shape(xMat)
        returnMat = np.zeros((numIt, n))  # 初始化numIt次迭代的回归系数矩阵
        ws = np.zeros((n, 1))  # 初始化回归系数矩阵
        wsTest = ws.copy()
        wsMax = ws.copy()
        for i in range(numIt):  # 迭代numIt次
            # print(ws.T)                                                                    #打印当前回归系数矩阵
            lowestError = float('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  # 记录numIt次迭代的回归系数矩阵
        return returnMat

def plotstageWiseMat():
        """
        函数说明:绘制岭回归系数矩阵
        """
        xArr, yArr = loadDataSet('abalone.txt')
        returnMat = stageWise(xArr, yArr, 0.005, 1000)
        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.plot(returnMat)
        ax_title_text = ax.set_title(u'The relationship between iterations and regression coefficient')
        ax_xlabel_text = ax.set_xlabel(u'iterations')
        ax_ylabel_text = ax.set_ylabel(u'regression coefficient')
        plt.setp(ax_title_text, size=15, weight='bold', color='red')
        plt.setp(ax_xlabel_text, size=10, weight='bold', color='black')
        plt.setp(ax_ylabel_text, size=10, weight='bold', color='black')
        plt.show()

测试代码:

import regression

regression.plotstageWiseMat()

结果:
机器学习实战 第八章 预测数值型数据:回归_第11张图片
分析:
    可以看到,有些系数从始至终都是约为0的,这说明它们不对目标造成任何影响,也就是说这些特征很可能是不需要的。逐步线性回归算法的优点在于它可以帮助人们理解现有的模型并做出改进。当构建了一个模型后,可以运行该算法找出重要的特征,这样就有可能及时停止对那些不重要特征的收集。
    缩减方法(逐步线性回归或岭回归),就是将一些系数缩减成很小的值或者直接缩减为0。这样做,就增大了模型的偏差(减少了一些特征的权重),通过把一些特征的回归系数缩减到0,同时也就减少了模型的复杂度。消除了多余的特征之后,模型更容易理解,同时也降低了预测误差。但是当缩减过于严厉的时候,就会出现过拟合的现象,即用训练集预测结果很好,用测试集预测就糟糕很多。

8.5权衡偏差和方差

    任何时候,一旦发现模型和测量值之间存在差异, 就说出现了误差。当考虑模型中的“ 噪声“或者说误差时,必须考虑其来源。你可能会对复杂的过程进行简化,这将导致在模型和测量值之间出现“ 噪声”或误差,若无法理解数据的真实生成过程,也会导致差异的发生。另外,测量过程本身也可能产生“ 噪声”或者问题。

8.6小结

    1、回归与分类一样,回归也是预测目标值的过程。回归与分类的不同点在于,前者预测连续类型变量,而后者预测离散类型变量。
    2、岭回归是缩减法的一种,相当于对回归系数的大小施加了限制。另一种很好的缩减法是lasso。lasso难以求解,但可以使用计算简便的逐步线性回归方法求的近似解。
    3、缩减法还可以看做是对一个模型增加偏差的同时减少方法。

你可能感兴趣的:(机器学习,回归,人工智能)