回归 (Regression) 是一种建模任务,涉及在给定输入的情况下预测数值。
线性回归是回归的标准算法,它假定输入和目标变量之间存在线性关系。线性回归的扩展包括在训练期间向损失函数添加惩罚项,鼓励具有较小系数值的更简单的模型。这些扩展被称为正则化线性回归或惩罚线性回归。
Lasso回归是一种流行的正则化线性回归,它包含L1惩罚。这会缩小对预测任务贡献不大的输入变量的系数。
最小角度回归(Least Angle Regression),简称LARS,提供了一种替代的、高效的拟合Lasso正则化回归模型的方法,该方法不需要任何超参数。
在本教程中,您将学习如何在Python中开发和评估LARS回归模型。
完成本教程后,您将了解:
- LARS回归提供了一种替代方法来训练Lasso正则化线性回归模型,该模型在训练期间向损失函数添加惩罚项。
- 如何评估LARS回归模型并使用最终模型对新数据进行预测。
- 如何通过该估计器的交叉验证版本自动配置LARS回归模型以适应新数据集。
让我们开始吧。

如何在Python中开发LARS回归模型
照片由 Nicolas Raymond拍摄,保留部分权利。
教程概述
本教程分为三个部分;它们是:
- LARS回归
- LARS回归示例
- 调整LARS超参数
LARS回归
线性回归是指一个假设输入变量和目标变量之间存在线性关系的模型。
对于单个输入变量,这种关系是一条直线;对于高维度,这种关系可以被认为是连接输入变量和目标变量的超平面。模型的系数是通过一个优化过程找到的,该过程旨在最小化预测值(yhat)和期望目标值(y)之间的均方误差。
- loss = sum i=0 to n (y_i – yhat_i)^2
线性回归的一个问题是,模型估计的系数可能很大,导致模型对输入敏感,并且可能不稳定。对于观测值(样本)很少或输入预测变量(p)多于变量(n)的问题,尤其如此(所谓的 p >> n 问题)。
解决回归模型稳定性的一种方法是修改损失函数,为具有大系数的模型添加额外的成本。在训练期间使用这些修改后的损失函数的线性回归模型统称为惩罚线性回归。
一种流行的惩罚方法是根据系数绝对值之和来惩罚模型。这被称为L1惩罚。L1惩罚最小化所有系数的大小,并允许某些系数被最小化到零值,从而将预测变量从模型中移除。
- l1_penalty = sum j=0 to p abs(beta_j)
L1惩罚最小化所有系数的大小,并允许任何系数减小到零值,从而有效地从模型中移除输入特征。这是一种自动特征选择方法。
… 惩罚绝对值的一个结果是,对于某些lambda值,一些参数实际上被设置为0。因此,Lasso可以同时使用正则化来改进模型和进行特征选择。
— 第125页,《应用预测建模》,2013年。
这种惩罚可以添加到线性回归的成本函数中,被称为 最小绝对收缩和选择算子(Least Absolute Shrinkage And Selection Operator),简称“Lasso”(大写L)。
Lasso使用最小二乘法损失训练过程来训练模型。
最小角度回归(Least Angle Regression),简称LAR或LARS,是解决拟合惩罚模型优化问题的另一种方法。从技术上讲,LARS是回归的向前逐步特征选择版本,可以适应Lasso模型。
与Lasso不同,它不需要控制损失函数中惩罚权重大小的超参数。相反,LARS会自动发现权重。
… 最小角度回归(LARS)是一个广泛的框架,它包含了Lasso及类似模型。LARS模型可以更有效地拟合Lasso模型,尤其是在高维问题中。
— 第126页,《应用预测建模》,2013年。
现在我们熟悉了LARS惩罚回归,让我们来看一个实际的例子。
LARS回归示例
在本节中,我们将演示如何使用LARS回归算法。
首先,让我们引入一个标准的回归数据集。我们将使用住房数据集。
住房数据集是一个标准的机器学习数据集,包含 506 行数据,其中有 13 个数值输入变量和一个数值目标变量。
使用重复10折交叉验证(重复三次)的测试框架,朴素模型可以达到约6.6的平均绝对误差(MAE)。在本相同的测试框架下,表现最佳的模型可以达到约1.9的MAE。这为该数据集的预期性能提供了界限。
该数据集涉及根据美国波士顿郊区的房屋细节来预测房价。
无需下载数据集;我们将在工作示例中自动下载它。
下面的示例下载并以 Pandas DataFrame 的形式加载数据集,并总结了数据集的形状和前五行数据。
1 2 3 4 5 6 7 8 9 10 |
# 加载和汇总住房数据集 from pandas import read_csv from matplotlib import pyplot # 加载数据集 url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.csv' dataframe = read_csv(url, header=None) # 总结形状 print(dataframe.shape) # 总结前几行 print(dataframe.head()) |
运行示例,确认了 506 行数据和 13 个输入变量以及一个数值目标变量(共 14 个)。我们还可以看到所有输入变量都是数值型的。
1 2 3 4 5 6 7 8 9 |
(506, 14) 0 1 2 3 4 5 ... 8 9 10 11 12 13 0 0.00632 18.0 2.31 0 0.538 6.575 ... 1 296.0 15.3 396.90 4.98 24.0 1 0.02731 0.0 7.07 0 0.469 6.421 ... 2 242.0 17.8 396.90 9.14 21.6 2 0.02729 0.0 7.07 0 0.469 7.185 ... 2 242.0 17.8 392.83 4.03 34.7 3 0.03237 0.0 2.18 0 0.458 6.998 ... 3 222.0 18.7 394.63 2.94 33.4 4 0.06905 0.0 2.18 0 0.458 7.147 ... 3 222.0 18.7 396.90 5.33 36.2 [5 行 x 14 列] |
scikit-learn Python机器学习库通过 Lars 类提供了LARS惩罚回归算法的实现。
1 2 3 |
... # 定义模型 model = Lars() |
我们可以使用 重复10折交叉验证 来评估房屋数据集上的LARS回归模型,并报告数据集上的平均平均绝对误差(MAE)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# 在数据集上评估LARS回归模型 from numpy import mean from numpy import std from numpy import absolute from pandas import read_csv from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedKFold from sklearn.linear_model import Lars # 加载数据集 url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.csv' dataframe = read_csv(url, header=None) data = dataframe.values X, y = data[:, :-1], data[:, -1] # 定义模型 model = Lars() # 定义模型评估方法 cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1) # 评估模型 scores = cross_val_score(model, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1) # 将分数强制为正数 scores = absolute(scores) print('平均MAE: %.3f (%.3f)' % (mean(scores), std(scores))) |
运行此示例将评估LARS回归算法在房屋数据集上的表现,并报告10折交叉验证(重复三次)的平均MAE。
鉴于学习算法的随机性,您的具体结果可能会有所不同。可以尝试运行几次示例。
在这种情况下,我们可以看到模型实现的MAE约为3.432。
1 |
平均MAE: 3.432 (0.552) |
我们可以决定使用LARS回归作为我们的最终模型,并对新数据进行预测。
这可以通过在所有可用数据上拟合模型并调用 predict() 函数来实现,传入新的数据行。
我们可以用一个完整的示例来演示这一点,如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# 使用LARS回归模型对数据集进行预测 from pandas import read_csv from sklearn.linear_model import Lars # 加载数据集 url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.csv' dataframe = read_csv(url, header=None) data = dataframe.values X, y = data[:, :-1], data[:, -1] # 定义模型 model = Lars() # 拟合模型 model.fit(X, y) # 定义新数据 row = [0.00632,18.00,2.310,0,0.5380,6.5750,65.20,4.0900,1,296.0,15.30,396.90,4.98] # 进行预测 yhat = model.predict([row]) # 总结预测 print('预测值: %.3f' % yhat) |
运行示例,拟合模型并对新数据行进行预测。
鉴于学习算法的随机性,您的具体结果可能会有所不同。尝试运行几次示例。
1 |
预测值: 29.904 |
接下来,我们可以看看如何配置模型超参数。
调整LARS超参数
作为LARS训练算法的一部分,它会自动发现Lasso算法使用的lambda超参数的最佳值。
在scikit-learn的Lasso和LARS实现中,这个超参数被称为“alpha”参数。
然而,自动发现最佳模型和alpha超参数的过程仍然基于单个训练数据集。
另一种方法是在训练数据集的多个子集上拟合模型,并在各个折叠中选择最佳的内部模型配置,在这种情况下是alpha的值。通常,这被称为交叉验证估计器。
scikit-learn库通过 LarsCV 类提供LARS的交叉验证版本,用于找到更鲁棒的alpha值。
下面的示例演示了如何拟合LarsCV模型并报告通过交叉验证找到的alpha值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# 使用自动配置的LARS回归算法 from numpy import arange from pandas import read_csv from sklearn.linear_model import LarsCV from sklearn.model_selection import RepeatedKFold # 加载数据集 url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.csv' dataframe = read_csv(url, header=None) data = dataframe.values X, y = data[:, :-1], data[:, -1] # 定义模型评估方法 cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1) # 定义模型 model = LarsCV(cv=cv, n_jobs=-1) # 拟合模型 model.fit(X, y) # 总结选择的配置 print('alpha: %f' % model.alpha_) |
运行此示例将使用重复交叉验证来拟合LarsCV模型,并报告在运行中找到的最佳alpha值。
1 |
alpha: 0.001623 |
此版本的LARS模型在实践中可能更鲁棒。
我们可以使用与上一节相同的程序来评估它,尽管在这种情况下,每个模型拟合都基于通过内部重复k折交叉验证(例如,交叉验证估计器的交叉验证)找到的超参数。
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# 在数据集上评估LARS交叉验证回归模型 from numpy import mean from numpy import std from numpy import absolute from pandas import read_csv from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedKFold from sklearn.linear_model import LarsCV # 加载数据集 url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.csv' dataframe = read_csv(url, header=None) data = dataframe.values X, y = data[:, :-1], data[:, -1] # 定义模型评估方法 cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1) # 定义模型 model = LarsCV(cv=cv, n_jobs=-1) # 评估模型 scores = cross_val_score(model, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1) # 将分数强制为正数 scores = absolute(scores) print('平均MAE: %.3f (%.3f)' % (mean(scores), std(scores))) |
运行此示例将通过重复交叉验证来评估模型超参数的交叉验证估计。
鉴于学习算法的随机性,您的具体结果可能会有所不同。尝试运行几次示例。
在这种情况下,我们可以看到我们取得了比上一节的3.432稍好的结果,为3.374。
1 |
平均MAE: 3.374 (0.558) |
进一步阅读
如果您想深入了解,本节提供了更多关于该主题的资源。
书籍
API
文章
总结
在本教程中,您学习了如何在Python中开发和评估LARS回归模型。
具体来说,你学到了:
- LARS回归提供了一种替代方法来训练Lasso正则化线性回归模型,该模型在训练期间向损失函数添加惩罚项。
- 如何评估LARS回归模型并使用最终模型对新数据进行预测。
- 如何通过该估计器的交叉验证版本自动配置LARS回归模型以适应新数据集。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
尊敬的Jason博士,
非常感谢这些精彩的教程,非常感激。
如果LARS可以在不调整超参数的情况下完成,并且Lasso在惩罚成本函数L1添加到成本函数方面与LARS“相同”,那么Lasso的意义是什么?直接使用LARS?
再次感谢您,
悉尼的Anthony
好问题。
它们使用不同的优化算法来解决相同的优化问题。另外,Lasso是一个系统,而LARS是一种解决方案,例如,你可以用LARS来解决Lasso。
https://scikit-learn.cn/stable/modules/generated/sklearn.linear_model.LassoLars.html
这对于观测值(样本)很少或样本(n)多于输入预测变量(p)或变量(所谓的p >> n问题)的问题尤其如此。
我认为你的意思是预测变量多于样本,因为符号表示恰恰相反(p >> n)。
谢谢,已修复!