醴,为你介绍7种盛行的线性回归缩短与挑选办法(附代码),相思

频道:国际新闻 日期: 浏览:292

作者:Micha Oleszak

翻译:张恬钰

校正:吴金笛

本文5000字,主张阅览12分钟。

本文评论了几种子集和缩短方法:最佳子集回归, 岭回归, LASSO, 弹性网, 最小视点回归, 主成分回归和偏最小二乘。

本文评论了七种盛行的缩短和选择方法的数学特点和实践的Python运用。

在本文中,咱们将介绍七种盛行的子集选择和线性回归缩短方法。在介绍了证明需求这些方法的主题之后,咱们将逐个研讨每种方法,包含数学特点和Pytrookiehon运用程序。

为什么缩短或子集,这是什么意思?

在线性回归上下文中,子集意味着从可用变量中选择要包含在模型中的子集,然后削减其维数。另一方面,缩短意味着减小系数估量的巨细(将它们缩小到零)。请注意,假如系数缩小到刚好为零,则相应的变量将退出模型。因而,这种状况也能够看作是一种子集。

缩短和选择旨在改善简略的线性回归。关于为什么需求改善,这里有两个原因:

  • 猜测准确性:线性回归估量倾向于具有低差错和高方差。下降模型复杂性(需求估量的参数数量)导致削减差异,但价值是引进更多差错。假如咱们能够找到总差错的最佳方位,那么差错导致的差错加上方差的差错被最小化,这样咱们就能够改善模型的猜测。
  • 模型的可解说性:因为猜测变量太多,人类很难把握变量之间的一切联系。在某些状况下,咱们乐意确认影响最大的一小部分变量,为大局考虑而献身一些细节。

设置和数据加载

在直接跳到方法本身之前,让咱们先看看咱们即将剖析的数据集。它来自Stamey等人的马龙一项研讨(1989)。Stamey研讨了不同临床丈量对前列腺特异性抗原(PSA)水平的影响。使命是依据一组临床和人口核算学变量确认前列腺癌的危险要素。数据以及变量的一些描绘能够在Hastie等人的网站以及 “核算学习的要素”教科书的数据部分找到。

Hastie等人的网站

http://web.stanford.edu/~hastie/ElemStatLearn/

咱们将首要导入本文中运用的模块,加载数据并将其拆分为练习和测验集,别离保存方针和特征。然后,咱们将评论每种缩短和选择方法,使其合适练习数据,并运用测验集查看它猜测新数据的PSA水平的作用怎么。

# Import necessary modules and set options

import pandas as pd

import numpy as np

import itertools

from sklearn.linear_model import LinearRegression, RidgeCV, LassoCV, ElasticNetCV, LarsCV

from sklearn.cross_decomposition import PLSRegression

from sklearn.decomposition import PCA

from sklearn.pipeline import Pipeline

from sklearn.model_selection import GridSearchCV

import warnings

warnings.filterwarnings("ignore")

# Load data

data = pd.read_csv("prostate_data", sep = "\t")

print(data.head())

# Train-test split

y_train = np.array(data[data.train == "T"]['lpsa'])

y_test = np.array(data[data.train == "F"]['lpsa'])

X_train = np.array(data[data.train == "T"].drop(['lpsa', 'train'], axis=1))

X_test = np.array(data[data.trai钟书阁n == "F"].drop(['lpsa', 'train'], axis=1))

线性回归

让咱们从简略的线性回归开端,这将构成咱们的基准。它将方针变量y建模为p个猜测变量或特征X的线性组合:



该模型具有有必要从练习数据估量的p + 2个参数:

  • p个特征系数,每个变量一个,表明它们对方针的影响;
  • 一个截距参数,表明为上面的0,它是在一切X都为零的状况下的猜测。纷歧定要将它包含在模型中,实践上在某些状况下应该将其删去(例如,假如想要包含表明分类变量等级的全套虚拟方针),但一般它会给模型更大的灵活性,正如你将在下一段中看到的;
  • 高斯差错项的一个方差参数。

一般运用一般最小二乘法(OLS)估量这些参数。 OLS最小化残差平方和,由下式给出



以图形方法考虑这种最小化规范是有协助的。只要一个猜测变量X时,咱们处于由猜测变量和方针构成的抚顺市望花区邮编2D空间中。在此设置中,模型在最挨近一切数据点的X-Y空间中拟合这样的线:挨近度丈量为一切数据点的垂直距离的平方和 - 请拜见下面的左图。假如有两个预醴,为你介绍7种盛行的线性回归缩短与选择方法(附代码),想念测变量X1和X2,则空间增长到3D,现在模型拟合最挨近3D空间中一切点的平面 - 请拜见下面的右图。有了两个以上的特征,平面变成了有点笼统的超平面,但这个思维仍然是相同的。这些可视化也有助于了解截距怎么为模型供给更大的灵活性:假如包含它,它答应线或平面不跨过空间的原点。



上述最小化问题证明具有解析解,而且参数能够被核算为



在X矩阵中包含一列1能够表达上述公式中的帽矢量的截距部分。 “”上方的“帽子”表明它是根据练习数据的估量值。

差错-方差权衡

在核算学中,要考虑估量量的两个要害特征:差错和方差。差错是实在整体参数和预期估量量之间的差异。它衡量估量数的不准确性。另一方面,方差衡量它们之间的差异。



明显,假如模型太大,差错和方差都会危害模型的猜测功用。但是,线性回归更遭到方差的影响,一同具有低差错。假如模型中存在许多猜测特征或许它们互相高度相关,则特别如此。这便是用到子集化和正则化来批改的当地。它们答应以引进一些差错为价值来削减方差,终究削减模型的总差错。

在具体评论这些方法之前,让咱们将线性回归拟合到前列腺数据中并查看其样本外的均匀猜测差错(MAE)。

linreg_model = LinearRegression(normalize=True).fit(X_train, y_train)

linreg_prediction = linreg_model.predict(X_test)

linreg_mae = np.mean(np.abs(y_test - linreg_prediction))

linreg_coefs = dict(

zip(['Intercept'] + data.columns.tolist()[:-1],

np.round(np.concatenate((linreg_model.intercept_, linreg_model.coef_),

axis=None), 3))

)

print('Linear Regression MAE: {}'.format(np.round(linreg_mae, 3)))

print('Linear Regression coefficients:')

linreg_coefs

最佳子集回归

选择线性回归变量子集的直接方法是测验一切或许的组合,并选择一个最小化某些规范的组合。这便是最佳子集回归的方针。关于每个k∈{1,2,...,p},其间p是可用特征的总数,它选择巨细为k的子集,其给出最小的残差平方和。但是,平方和不能用作确认k本身的规范,因为它必定随k减小:模型中包含的变量越多,其残差越小。但这并不能确保更好的猜测功用。这便是为什么应该运用另一个规范来选择终究模型的原因。关于专心于猜测的模型,测验数据上的(或许是穿插验证的)过错是常见的选择。

因为最佳子集回归没有在任何Python包中完成,i5咱们有必要手动循环k和k巨细的一切子集。以下代码块完成了这项作业。

results = pd.DataFrame(columns=['num_features', 'features', 'MAE'])

# Loop over all possible numbers of features to be included

for k in range(1, X_train.shape[1] + 1):

# Loop over all possible subsets of size k

for subset in itertools.combinations(range(X_train.shape[1]), k):

subset = li青蜂侠周杰伦st(subset)

linreg_model = LinearRegression(normalize=True).fit(X_train[:, subset], y_train)

linreg_prediction = linreg_model.predict(X_test[:, subset])

linreg_mae = np.mean(np.abs(y_test - linreg_prediction))

results = results.append(pd.DataFrame([{'num_features': k,

'features': subset,

'MAE': linreg_mae}]))

# Inspect best combinations

results = results.sort_values('MAE').reset_index()

print(results.head())

# Fit best model

best_subset_model = LinearRegression(normalize=True).fit(X_train[:, results['features'][0]], y_train)

best_subset_coefs = dict(

zip(['Intercept'] + data.columns.tolist()[:-1],

np.round(np.concatenate((best_subset_model.intercept_, best_subset_model.coef_), axis=None), 3))

)

print('Best Subset Regression MAE: {}'.format(np.round(results['MAE'][0], 3)))

print('Best Subset Regression coefficients:')

best_subset_coefs

岭回归

最佳子集回归的一个缺陷是它没有通知咱们关于从模型中扫除的变量对呼应变量的影响。岭回归供给了这种难以选择的变量的代替计划,这些变量将它们分解为模型中包含的和不包含的。相反,它赏罚系数以将它们缩小到零。不彻底为零,因为这意味着从模型中移除,但是在零方向上,这能够被视为以接连方法下降模型的复杂性,一同将一切变量坚持在模型中。

在岭回归中,线性回归丢失函数以这样的方法增强,不只能够最小化残差平方和,还能够赏罚参数估量的巨细:



处理这个最小化问题可得到s的剖析公式:



其间I表明单位矩阵。赏罚项是要选择的超参数:其值越大,系数越向零缩短。从上面的公式能够看出,当变为零时,加性罚分消失,-ridge与线性回归中的-OLS相同。另一方面,跟着增长到无穷大,-ridge挨近零:在足够高的赏罚下,系数能够恣意地缩短醴,为你介绍7种盛行的线性回归缩短与选择方法(附代码),想念到挨近零。

但这种缩短是否真的会导致削减模型的方差并以许诺的方法引进一些差错呢?是的,的确如此,从岭回归估量的差错和方差的公式中能够清楚地看出:跟着的增加,差错也随之增加,而方差则下降!



现在,怎么选择的最佳值?进行穿插验证测验一组不同的值,并选择一个最小化测验数据上穿插验证过错的值。走运的是,Python的scikit-learn能够为咱们做到这一点。

ridge_cv = RidgeCV(normalize=True, alphas=np.logspace(-10, 1, 400))

ridge_model = ridge_cv.fit(X_train, y_train)

ridge_prediction = ridge_mode王书桂l.predict(X_test)

ridge_mae = np.mean(np.abs(y_test - ridge_prediction))

r醴,为你介绍7种盛行的线性回归缩短与选择方法(附代码),想念idge_coefs = dict(

zip(['Intercept'] + data.columns.tolist()[:-1],

np.round(np.concatenate((ridge_model.intercept_, ridge_model.coef_),

axis=None), 3))

)

print('Ridge Regression MAE: {}'.format(np.round(ridge_mae, 3)))

print('Ridge Regression coefficients:')

ridge_coefs

LASSO

Lasso,或最小肯定缩短和选择算子,在本质上与岭回归十分类似。它也为丢失函数的非零系数增加了一个赏罚,但与赏罚平方系数之和(所谓的L2赏罚)的岭回归不同,LASSO赏罚它们的肯定值之和(L1赏罚)。因而,关于的高值,许多系数在LASSO下彻底归零,在岭回归中从未如此。

它们之间的另一个重要区别是它们地热取暖怎么处理这些特征之间的多重共线性问题。在岭回归中,相关变量的系数趋于类似,而在LASSO中,其间一个一般为零,另一个则赋值为整个影响。因而,假如存在相同值的许多大参数,即当大多数猜测器实在影响呼应时,预期岭回归将有更好的作用。另一方面,当存在少量重要参数且其他参数挨近零时,即当只要少量猜测因子实践影响呼应时,LASSO将占有首位。

但是,在实践中,人们不知道参数的实在值。因而,岭回归和LASSO之间的选择能够根据样本外猜测差错。另一种选择是将这两种方法合二为一 - 见下一节!

LASSO的丢失函数如下:



与岭回归不同,这种最小化问题无法经过剖析处理。走运的是,有数值算法能够处理它。

lasso_cv = LassoCV(normalize=True, alphas=np.logspace(-10, 1, 400))

lasso_model = lasso_cv.fit(X_train, y_train)

lasso_prediction = lasso_model.predict(X_test)

lasso_mae = np.mean(np.abs(y_test - lasso_prediction))

lasso_coefs = dict(

zip(['Intercept'] + data.columns.tolist()[醴,为你介绍7种盛行的线性回归缩短与选择方法(附代码),想念:-1],

np.round(np.concatenate((lasso_model.intercept_, lasso_model.coef_), axis=None), 3))

)

p醴,为你介绍7种盛行的线性回归缩短与选择方法(附代码),想念rint('LASSO MAE: {}'.format(np.round(lasso_mae, 3)))

print('LASSO coefficients:')

lasso_coefs

弹性网

弹性网首要是对LASSO的批判而发生的,LASSO的变量选择过于依靠数据,因而不稳定。它的处理计划是将岭回归和LASSO的赏罚结合起来,以取得一举两得的作用。弹性网旨在最大极限地削减包含L1和L2赏罚的丢失函数:



其间是岭回归(当它为零时)和LA醴,为你介绍7种盛行的线性回归缩短与选择方法(附代码),想念SSO(当它为1时)之间的混合参数。能够运用根据scikit-learn的根据穿插验证的超左边调整来选择最佳。

elastic_net_cv = ElasticNetCV(normal青海花儿打擂台对唱ize=True, alphas=np.logspace(-10, 1, 400),

l1_ratio=np.linspace(0, 1, 100))

elastic_net_model = elastic_net_cv.fit(X_train, y_train)

elastic_net_prediction = elastic_net_model.predict(X_test)

elastic_net_mae = np.mean(np.abs(y_test - elastic_net_prediction))

elastic_net_coefs = dict(

zip(['Intercept'] + data.columns.tolist()[:-1],

np.round(np.concatenate((elastic_net_model.intercept_,

elastic_net_model.coef_), axis=None), 3))

)

print('Elastic Net MAE: {}'.format(np.round(elastic_net_mae, 3)))

print('Elastic Net coefficients:')

elastic_net_coefs

最小视点回归

到目前为止,咱们现已评论了一种子集化方法,最佳子集回归和三种缩短方法:岭回归,LASSO及其组合,弹性网络。本节专门介绍坐落子集和缩短之间的方法:最小视点回归(LAR)。该算法以空模型开端,一切系数等于零,然后迭代地作业,在每个进程将一个变量的系数移向其最小二乘值。

更具体地说,LAR从辨认与呼应最相关的变量开端。然后,它将该变量的系数接连地移向其最小平方值,然后下降其与演化残差的相关性。一旦另一个变量在与残差的相关性方面“赶上”,该进程就会暂停。然后,第二个变量参加有用集,即具有非零系数的变量集,而且它们的系数以坚持它们的相关性衔接和削减的方法一同移动。持续该进程直到一切变量都在模型中,并以彻底最小二乘拟合完毕。称号“最小视点回归”来自算法的几许解说,其间给定进程处的新拟合方向与现已具有非零系数的每个特征构成最小视点。

下面的代码块将LAR运用于前列腺数据。

LAR_cv = LarsCV(normalize=True)

LAR_model = LAR_cv.fit(X_train, y_train)

LAR_prediction = LAR_model.predict(X_test)

LAR_mae = np.mean(np.abs(y_test - LAR_prediction))

LAR_coefs = dict(

zip(['Intercept'] + data.columns.tolist()[:-1],

np.round(np.concatenate((LAR_model.intercept_, LAR_model.coef_), axis=None), 3))

)

print('Least Angle Regression MAE: {}'.format(np.round(LAR_mae, 3)))

pri余念邵衍nt('Least Angle Regression coefficients:')

LAR_coefs

主成分回归

咱们现已评论了选择变量(子集)和下降系数(缩短率)的方法。本文中介绍的终究两种方法采用了略微不同的方法:它们将原始要素的输入空间挤压到较低维度的空间中。主要是,他们运用X创立一小组新特征Z,它们是X的线性组合,然后在回归模型中运用它们。

这两种方法中的第一种是主成分回归。它运用主成分剖析,这种方法答应取得一组新特征,互相不相关且具有高方差(以便它们能够解说方针的方差),然后将它们用作简略线性回归中的特征。这使得它墨尔本气候类似于岭回归,因为它们都在原始特征的主成分空间上运转(关于根据PCA的岭回归推导,拜见本文底部的Sources中的[1])。不同之处在于PCR丢掉具有最少信息功用的组件,而岭回归仅仅将它们缩短得更强。

要从头取得的组件数量能够视为超参数,并经过穿插验证进行调整,如下面的代码块中的状况。

regression_model = LinearRegression(normalize=True)

pca_model = PCA()

pipe = Pipeline(steps=[('pca', pca_model), ('least_squares', regression_model)])

param_grid = {'pca__n_components':刈 range(1, 9)}

search = GridSearchCV(pipe, param_grid)

pcareg_model =捷豹suv search.fit(X_train, y_train)

pcareg_prediction = pcareg_model.predict(X_test)

pcareg_mae = np.mean(np.abs(y_test - pcareg_prediction))

n_comp = list(pcareg_model.best_params_.values())[0]

pcareg_coefs = dict(

zip(['Intercept'] + ['PCA狗智商排名_comp_' + str(x) for x in range(1, n_comp + 1)],

np.round(np.concatenate((pcareg_model.best_estimator_.steps[1][1].intercept_,

pcareg_model.best_estimator_.steps[1][1].coef_), axis=None), 3))

)

print('Principal Components Regression MAE: {}'.format(np.round(pcareg_mae, 3)))

print('Principal Components Regression coefficients:')

pcareg_coefs

偏最小二乘法

本文评论的终究方法是偏最小二乘法(PLS)。与主成分回归类似,它也运用原始要素的一小组线性组合。不同之处在于怎么构建这些组合。虽然主成分回归仅运用X本身来创立派生特征Z,但偏最小二乘别的运用方针y。因而,在构建Z时,PLS寻觅具有高方差的方向(因为这些能够解说方针中的方差)以及与方针的高相关性。与主成分剖析构成比照,主成分剖析仅重视高差异。

在算法的驱动下,第一个新特征z1被创立为一切特征X的线性组合,其间每个X由其内积与方针y加权。然后,y在z1上回归,给出PLS系数。终究,一切X都相关于z1正交化。然后,该进程从头开端z2并持续,直到取得Z中所需的组件数量。像平常相同,这个数字能够经过穿插验证来选择。

能够证明,虽然PLS依据需求缩小了Z中的低方差重量,但它有时会使高方差重量胀大,这或许导致在某些状况下更高的猜测差错。这似乎是咱们的前generate列腺数据的状况:PLS在一切评论的方法中体现最差。

pls_model_setup = PLSRegression(scale=True)

param_grid = {'n_components': range(1, 9)}

search = GridSearchCV(pls_model_setup, param_grid)

pls_model = search.fit(X_train, y_train)

pls_prediction = pls_model.predict(X_test)

pls_mae = np.mean(np.abs(y_test - pls_prediction))

pls_coefs = dict(

zip(data.columns.tolist()[:-1],

np.round(np.concatenate((pls_model.best_estimator_.coef_), axis=None), 3))

)

print('Partial Least Squares Regression MAE: {}'.format(np.round(pls_mae, 3)))

print('Partial Least Squares R跪趴egression coefficients:')

pls_coefs

回忆与定论

因为模型参数存在很大的方差,线性模型具有许多或许相关的特征,导致猜测精度和模型的可解说性方面较差。这能够经过削减方差来缓解,这种方差只会以引进一些差错为价值。但是,找到最佳的差错 - 方差权衡能够优化模型的功用。

答应完成此意图的两大类方法是子集和缩短。前者选择变量的子集,而后者将模型的系数缩小为零。这两种方法都会下降模型的复杂性,然后导致参数方差的削减。

本文评论了几种子集和缩短方法:

  • 最佳子集回归迭代一切或许的特征组合以选择最佳特征组合;
  • 岭回归赏罚平方系数值(L2赏罚),强制它们很小;
  • LASSO赏罚系数的肯定值(L1赏罚),这能够迫使它们中的一些准确为零;
  • 弹性网结合了L1和L2的赏罚,享受了Ridge和Lasso的精华;
  • 最小视点回归适用于子集和缩短之间:它迭代地作业,在每个进程中增加其间一个特征的“某个部分”;
  • 主成分回归履行PCA将原始特征紧缩为一小部分新特征,然后将其用作猜测变量;
  • 偏最小二乘也将原始特征归纳为较小的新特征子集,但与PCR不同,它也使用方针构建它们。


正如您在上面运转代码块时从运用程序看到的前列腺数据,大多数这些方法在猜测准确性方面体现类似。前5种方法的差错范围在0.467和0.5rope17之间,打败最小二乘差错为0.523。终究两个,PCR和PLS,体现更差,或许是因为数据中没有那么多特征,因而降维的收益是有限的。

谢谢阅览!我期望你学到了新东西!

来历

  • Hastie, T., Tibsh喝irani, R., & Friedman, J. H. (2009). The elements of statistical learning: data mining, inference, and prediction. 2nd ed. New York: Springer.
  • https://www.datacamp.com/community/tutorials醴,为你介绍7种盛行的线性回归缩短与选择方法(附代码),想念/tutorial-ridge-lasso-elastic-net


原文标题:

A Comparison of Shrinkage and Selection Methods for Linear Regression

原文链接:

https://towardsdatascience.com/a-comparison-of-shrinkage-and-selection-methods-for-linear-regression-ee4dd3a71f16

修改:王菁

校正:洪舒越

译者简介


张恬钰,上海交通大学本科物理专业,Emory University生物核算硕士在迅游手游加速器读。今后想持续在生物核算方向进修。期望能留在美国学习和作业。期望能和广阔的数据爱好者做朋友!

— 完 —

重视清华-青岛数据科学研讨院官方微信大众渠道“THU数据派”及姊妹号“数据派THU”获取更多讲座福利及优质内容。

热门
最新
推荐
标签