岭回归算法的原理和代码实战

岭回归算法的原理和代码实战

前言

学过吴恩达老师的机器学习入门课程都应该知道,在逻辑回归那一讲,吴老师提到了使用正则化来防止逻辑回归模型过拟合。而岭回归在这里的作用是一样的,同样也是防止模型过拟合。这两者的区别在于,同样在使用差平方作为所损失值后,前者使用梯度下降法进行参数优化,而后者使用最小二乘法计算参数。

岭回归原理

1. 前情回顾

前面咱们写过一篇博客,主要说的是使用最小二乘法解决一般线性回归问题,如果大家没有看过,请看一下。线性回归算法拟合数据原理分析以及源代码解析

不想看没关系,咱们在这里把重要推导公式再写一遍:

直线方程:

img

损失值函数:

img

向量书写:

img

式子展开:

img

求导:

img

令导数为零,求出α:

img

2. 岭回归公式推导

看完一般线性回归推导式后,我们对上面的式子稍微做一些改变。

首先我们在损失函数上添加惩罚项,与文首咱们说的正则化项基本一致。

img

对于λ,其值越大,对整个损失函数的惩罚就越大,换句话意思就是λ值越大,对α参数的变化就更加敏感。我们假设λ为10的时候,α²有0.1的变化,整理就会产生1的变化。如果λ为10000,α²有0.1的变化,整体就有1000的变化。

接着我们把公式进行向量化:

img

我们对其进行求导:

img

我们令其导数为零,可以求出来α,

img

好了,到这里我们就得出来这个参数α了,其中I是常向量E。

α新式子另一个优势

img

我们知道这个式子里面X代表数据。

如果我们数据的属性要大于数据量,那么这个X矩阵则是奇异矩阵(矩阵的模为0),即表示X矩阵不可逆。所以XTX这个求解的矩阵,也会存在不可逆的情况。此时我们添加了一个λI,可以避免不可逆现象的出现。

岭回归代码实战

1. 数据集的加载

我们先来看一下数据集的属性有哪些:

image-20200624113916873

图中最座标红色方块是数据的常数1,用来求解常量,对应着就是我们前面公式的b。

中间黄色的是我们的属性值α1.

最右边白色的是我们数据的值,也就是y值。

我们来看一下数据的分布情况:

image-20200624115800582

def LoadData(filename):
    dataMat = []
    labelMat = []
    with open(filename) as f:
        numFeat = len(f.readline().split('\t'))-1#这里会导致忽略第一个数据
        for line in f.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

这里将text数据集分别放入到两个数组中

2. 主函数,计算模型参数

## 主函数,计算模型参数
def ridgeRegres(xMat,yMat,lam=0.2):
    xTx = xMat.T*xMat
    denom = xTx+np.eye(np.shape(xMat)[1])*lam
    if np.linalg.det(denom)==0.0:
        print("This matrix is singular ,cannot do inverse")
        return
    ws = denom.I*(xMat.T*yMat)
    return ws

这一部分是整个代码中最关键的部分,用来计算模型参数。

代码中的ws对应着公式中的α。

denom.I 表示对denom取逆。

3. 交叉验证,选择合适的λ

def Cross_validation(xMat,yMat,ridgeWeights,lamudas):
    yMat = np.array(yMat).reshape((len(yMat),1))
    lossvalue = []
    for i in range(9):
        yHat = xMat*np.mat(ridgeWeights[i]).T
        lossvalue.append(np.sum(np.abs(yHat-yMat)))
    lossvalue = np.array(lossvalue)
    result = lossvalue.argmin()
    return lamudas[result]

这个函数,我们主要是通过比较不同λ产生的预测值与原标签值的损失值,选择可以使损失值达到最小的λ值。

这里为了计算的方便,我们使用了绝对值代替的平方,但是最终产生的结果都是一样的。

结果分析

首先我们先输出不同λ对应的不同图像,我将这九个图形放在了一张图形中,方便我们去比较,观察。

image-20200702215005388

经交叉验证输出,最优的λ取值是1.0.

从图中我们可以看出,随着λ的增大,我们所拟合的直线模型逐渐偏移数据。从另一个层面来讲,λ的增大,使得模型精度逐渐减少,同样也会减少模型的过拟合,使得模型更加符合整个数据的趋势。

总结

岭回归只是缩减法的一种,其作用就是能够减少模型的拟合度,防止过拟合。咱们前几篇文章也有说到关于防止欠拟合的方法,如果大家感兴趣的话,可以将两者方法结合起来,说不定模型的效果会更好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章