线性回归5(岭回归、LAR算法实现LASSO算法实战)---机器学习

版权声明:转载请注明出处: https://blog.csdn.net/weixin_42398658/article/details/83653448

岭回归算法:

岭回归原理不懂的,请先搞懂岭回归的原理在实现,只看代码不懂原理和不学差不多,不懂的请看什么是岭回归,下面直接给出岭回归的优化公式:

经过化简以后的目标公式为:

   原始的最小二乘法的无偏估计优化目标公式为:

                                       \hat{\beta }=(X^TX)^{-1}X^Ty     

  岭估计(有偏估计)的优化目标公式:                                       

                                       \mathbf{\hat{\beta }(\lambda ) = (X^TX+\lambda I)^{-1}X^Ty} 

简单来说就是在 矩阵x^Tx中加入一个\lambda I矩阵,使其得到的矩阵为非奇异的矩阵,进而可以对X^TX+\lambda I矩阵求逆,其中I是对角线为1的对角矩阵,\lambda为用户可以定义的一个参数,详细的原理请看这篇文章什么是岭回归,下面准备开始上代码:

先讲解一下,数据获取后,首先抽取一部分为数据用于测试,剩余的作为训练集用于训练参数\beta,训练完毕后再测试集上测试预测性能,同选取不同的\lambda来重复上述过程,最终得到一个使误差最小的\lambda

# 岭回归
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


def ridgeTest(xArr, yArr):
    xMat = np.mat(xArr)
    yMat = np.mat(yArr).T
    yMean = np.mean(yMat, 0)
    yMat = yMat - yMean  # to eliminate X0 take mean off of Y
    # 数据标准化
    xMeans = np.mean(xMat, 0)  # calc mean then subtract it off
    xVar = np.var(xMat, 0)  # calc variance of Xi then divide by it
    xMat = (xMat - xMeans) / xVar
    numTestPts = 30
    wMat = np.zeros((numTestPts, np.shape(xMat)[1]))
    for i in range(numTestPts):
        ws = ridgeRegres(xMat, yMat, np.exp(i - 10))
        wMat[i, :] = ws.T
    return wMat


# 测试代码
abx, aby = regression.loaddataset('abalone.txt')
ridgeweights = regression.ridgeTest(abx, aby)
print(ridgeweights)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(ridgeweights)

plt.show()

从上图我们发现在lambda为0时就是最小二乘的无偏估计的β,随着lambda的增加,β在逐渐减小,直到减小到零,和前面的理论讲解是吻合的,通过岭迹图可以分析是否存在共线性问题,也可通过岭迹图选择特征,但是效果不是很好,因为没有明确出那个特征可以剔除,这需要使用人员的使用经验进行选择,为了解决这个问题,我们在岭回归的基础引入lasso,原理在前面已经讲解了,这里给出sklearn的代码:

这里需要强调的是lasso的另外一种解法是坐标下降算法,这里不深入讲解,有兴趣的同学可以自行了解,在这里主要通过LAR进行求解lasso的参数。

这是lasso的优化函数,下面介绍一下sklearn的LAR算法:

最小角回归 (LARS) 是对高维数据的回归算法, 由 Bradley Efron, Trevor Hastie, Iain Johnstone 和 Robert Tibshirani 开发完成。 LARS 和逐步回归很像。在每一步,它寻找与响应最有关联的 预测。当有很多预测有相同的关联时,它没有继续利用相同的预测,而是在这些预测中找出应该等角的方向。

LARS的优点:

  • 当 p >> n,该算法数值运算上非常有效。(例如当维度的数目远超点的个数)
  • 它在计算上和前向选择一样快,和普通最小二乘法有相同的运算复杂度。
  • 它产生了一个完整的分段线性的解决路径,在交叉验证或者其他相似的微调模型的方法上非常有用。
  • 如果两个变量对响应几乎有相等的联系,则它们的系数应该有相似的增长率。因此这个算法和我们直觉 上的判断一样,而且还更加稳定。
  • 它很容易修改并为其他估算器生成解,比如Lasso。

LARS 的缺点:

  • 因为 LARS 是建立在循环拟合剩余变量上的,所以它对噪声非常敏感。这个问题,在 2004 年统计年鉴的文章由 Weisberg 详细讨论。

#!/usr/bin/env/python
# -*- coding: utf-8 -*-
# Author: 赵守风
# File name: EX.py
# Time:2018/11/2
# Email:[email protected]


import numpy as np
import matplotlib.pyplot as plt

from sklearn import linear_model
from sklearn import datasets

diabetes = datasets.load_diabetes()
X = diabetes.data
y = diabetes.target

print("Computing regularization path using the LARS ...")
alphas, _, coefs = linear_model.lars_path(X, y, method='lasso', verbose=True)

xx = np.sum(np.abs(coefs.T), axis=1)
xx /= xx[-1]

plt.plot(xx, coefs.T)
ymin, ymax = plt.ylim()
plt.vlines(xx, ymin, ymax, linestyle='dashed')
plt.xlabel('|coef| / max|coef|')
plt.ylabel('Coefficients')
plt.title('LASSO Path')
plt.axis('tight')
plt.show()

 具体请参考源码实现,其中sklearn中实现了很多算法,理论提到的算法,sklearn具有,详情请看sklearn,下面的算法均匀,详情请去官网参考

1.1. 广义线性模型
1.1.1. 普通最小二乘法
1.1.1.1. 普通最小二乘法复杂度
1.1.2. 岭回归
1.1.2.1. 岭回归的复杂度
1.1.2.2. 设置正则化参数:广义交叉验证
1.1.3. Lasso
1.1.3.1. 设置正则化参数
1.1.3.1.1. 使用交叉验证
1.1.3.1.2. 基于信息标准的模型选择
1.1.3.1.3. 与 SVM 的正则化参数的比较
1.1.4. 多任务 Lasso
1.1.5. 弹性网络
1.1.6. 多任务弹性网络
1.1.7. 最小角回归
1.1.8. LARS Lasso

猜你喜欢

转载自blog.csdn.net/weixin_42398658/article/details/83653448