不忘初心,方得始终——线性回归的python实现

hello,大家好,我是此木,很高兴能在2020年的第一天和大家分享点东西,新的一年,新的开始,希望大家能在接下来的一年里有所成长,有所收获。

导读:在当前机器学习、深度学习、强化学习、元学习等盛行的时代,我想在新年第一天做一次回归始点的总结,不忘初心,方得始终。在数据分析中,回归问题,可以说是模型解决的最基础同时也是最广泛的问题,在统计学中,你建立的第一个预测模型解决的问题我相信就是回归。本文分享的主要内容是有关回归的线性模型:线性回归(ordinary least squares,OLS)、岭回归(ridge regression),Lasso回归

线性模型是在时间中广泛使用的一类模型,几十年来被广泛研究,它可以追溯到一百多年前。线性模型利用输入特征的线性函数进行预测,线性回归模型预测的一般公式如下:

y = w[0]*x[0] + w[1]*x[1] + ... + w[p]*x[p] + b

1 线性回归(又名普通最小二乘法)

线性回归,是回归问题最简单也是最经典的线性方法,线性回归寻找参数w 和 b,使得对训练集的预测值与真实的回归目标值y之间的均方误差最小。均方误差(MSE)是预测值与真实值之差的平方和除以样本数。线性回归没有参数,这是一个优点,但也因此无法控制模型的复杂度。

from sklearn.linear_model import LinearRegressionX, y = mglearn.datasets.make_wave(n_samples=60)X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)lr = LinearRegression().fit(X_train, y_train)print("lr.coef_:", lr.coef_)print("lr.intercept_:", lr.intercept_)

lr.coef_: [0.394]

lr.intercept_: -0.031804343026759746

intercept_属性是一个浮点数,而coef_属性是一个NumPy数组,每个元素对应一个输入特征。由于wave数据集中只有一个输入特征,所以lr.coef_中只有一个元素。

我们来看一下训练集和测试集的性能:

print("Training set score: {:.2f}".format(lr.score(X_train, y_train)))print("Test set score: {:.2f}".format(lr.score(X_test, y_test)))

Training set score: 0.67

Test set score: 0.66

R2约为0.66,这个结果不是很好,但是我们可以看到,训练集和测试集上的分数非常接近,这说明可能存在欠拟合,而不是过拟合。对于这个一维数据集来说,过拟合的风险很小,因为模型非常简单(或受限)。然而,对于更高维的数据集,线性模型将变得更加强大,过拟合的可能性也会变大。我们来看一下LinearRegression在更复杂数据集上的表现,比如波士顿房价数据集,这个数据集有506个样本和105个特征。

​​​​​​​

X, y = mglearn.datasets.load_extended_boston()X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)lr = LinearRegression().fit(X_train, y_train)print("Training set score: {:.2f}".format(lr.score(X_train, y_train)))print("Test set score: {:.2f}".format(lr.score(X_test, y_test)))

比较一下训练集和测试集的分数可以发现,我们在训练集上的预测非常准确,但在测试集上的R2低很多。

Training set score: 0.95

Test set score: 0.61

训练集和测试集之间的性能差异是过拟合的明显标志,因此我们应该试图找一个可以控制复杂度的模型。标准线性回归最常用的代替方法之一就是岭回归(ridge regression)。

岭回归

岭回归也是一种用于回归的线性模型,因此它的预测公式与普通最小二乘法相同。但在岭回归中,对系数(w)的选择不仅要在训练数据上得到很好的预测结果,而且还要拟合附加约束。我们还希望系数尽量小,即w的所有元素都应该接近于0,这意味着每个特征对输出的影响尽可能的小,同时仍给出很好的预测结果。这种约束是所谓正则化,对模型做显示约束,避免过拟合。岭回归用到L2正则化。

​​​​​​​

from sklearn.linear_model import Ridgeridge = Ridge(alpha=1.0).fit(X_train, y_train)print("Training set score: {:.2f}".format(ridge.score(X_train, y_train)))print("Test set score: {:.2f}".format(ridge.score(X_test, y_test))

Training set score: 0.89

Test set score: 0.75

可以看出,Ridge在训练集上的分数要低于LinearRegression,但在测试集上的分数更高。这和我们预期的一致。线性回归对数据存在过拟合。Ridge是一种约束更强的模型,所以更不容易过拟合,复杂度更小的模型意味着在训练集上的性能更差,但泛化性能更好。

这里需要注意的是,岭回归存在alpha参数,姑且叫它惩罚项系数,增大alpha会使系数更加趋向于0。

同时,我做了一个测试,固定alpha值,改变训练数据量。结果显示,随着模型可用数据越来越多,两个模型的性能都在提升,最终线性回归的性能追上了岭回归,这表明,如果有足够多的训练数据,正则化变得不那么重要,并且岭回归和线性回归将具有相同的性能。

 

​​​​​​​

 

3 Lasso

除了Ridge,还有一种正则化的线性回归是Lasso,与岭回归相同,使用Lasso也是约束系数,使其接近于0,但用到的方法不同,叫做L1正则化。L1正则化的结果是,使用Lasso时,某些系数刚好为0。这说明某些特征被模型完全忽略。这可以看做是一种自动化的特征选择。某些系数刚好为0,这样的模型更容易解释,也可以看做是模型最重要的特征。

我们将Lasso用在波士顿房价的数据集上:

​​​​​​​

from sklearn.linear_model import Lassolasso = Lasso().fit(X_train, y_train)print("Training set score: {:.2f}".format(lasso.score(X_train, y_train)))print("Test set score: {:.2f}".format(lasso.score(X_test, y_test)))print("Number of features used:", np.sum(lasso.coef_ != 0))

Training set score: 0.29

Test set score: 0.21

Number of features used: 4

如你所见,Lasso在训练集和测试集上的表现都很差,这表示欠拟合,我们发现模型只用到了105个特征中的4个。与Ridge类似,Lasso也有一个正则化的参数alpha,可以控制系数趋向于0的强度。我们尝试减小alpha,,同时,增加max_iter的值(运行迭代的最大次数):

​​​​​​​

lasso001 = Lasso(alpha=0.01, max_iter=100000).fit(X_train, y_train)print("Training set score: {:.2f}".format(lasso001.score(X_train, y_train)))print("Test set score: {:.2f}".format(lasso001.score(X_test, y_test)))print("Number of features used:", np.sum(lasso001.coef_ != 0))

Training set score: 0.90

Test set score: 0.77

Number of features used: 33

alpha值变小,我们可以拟合一个更复杂的模型,在训练集和测试集上的表现也更好,模型的性能比使用Ridge时略好一点,而且我们只用到了105个特征中的33个。这样模型可能更容易理解。

但如果把alpha设的太小,那么就会消除正则化的效果,并出现过拟合,得到与LinearRegression类似的结果:​​​​​​​

lasso00001 = Lasso(alpha=0.0001, max_iter=100000).fit(X_train, y_train)print("Training set score: {:.2f}".format(lasso00001.score(X_train, y_train)))print("Test set score: {:.2f}".format(lasso00001.score(X_test, y_test)))print("Number of features used:", np.sum(lasso00001.coef_ != 0))

Training set score: 0.95

Test set score: 0.64

小结

在实践中,在两个模型中一般首选岭回归。但如果特征特别多,你认为只有其中几个是重要的,那么选择Lasso可能更好。同样,如果你想要一个更容易解释的模型,Lasso可以给出更容易理解的模型,因为它只选择了一部分输入特征。scikit-learn还提供了ElasticNet类,结合了Lasso和Ridge的惩罚项。在实践中,这种结合的效果最好,不过代价是要调节两个参数:一个用于L1正则化,一个用于L2正则化。

今天就和大家分享到这里,接下来的内容可能会分享涉及logistics或者xgboost/lgboost的相关内容,欢迎大家相互交流学习。


文章的结尾,送给大家一首词,再大的城市也应有它的温度,再忙碌的工作也应只为更好的生活,幸福和安宁才是我们生活的主旋律。

苏轼的好友王巩(字定国)因为受到使苏轼遭杀身之祸的“乌台诗案”牵连,被贬谪到地处岭南荒僻之地的宾州。王定国受贬时,其歌妓柔奴毅然随行到岭南。公元1083年(元丰六年)王巩北归,出柔奴(别名寓娘)为苏轼劝酒。苏轼问及广南风土,柔奴答以“此心安处,便是吾乡”。苏轼听后,大受感动,作此词以赞。

《定风波·南海归赠王定国侍人寓娘》

作者:苏轼

 

常羡人间琢玉郎。天应乞与点酥娘。尽道清歌传皓齿。风起。雪飞炎海变清凉。
万里归来颜愈少。微笑。笑时犹带岭梅香。试问岭南应不好。却道。此心安处是吾乡

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值