岭回归使用L2正则化对系数w进行约束,以限制模型复杂度(防止过拟合),
import numpy as np
import pandas as pd
import mglearn
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
X,y = mglearn.datasets.load_extended_boston()
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=0)
from sklearn.linear_model import Ridge
from sklearn.linear_model import LinearRegression
ridge = Ridge().fit(X_train,y_train)
print('训练集准确度:{:.2f}'.format(ridge.score(X_train,y_train)))
print('测试集准确度:{:.2f}'.format(ridge.score(X_test,y_test)))
输出
训练集准确度:0.89
测试集准确度:0.75
可以看出,由于Ridge是一种约束更强的线性模型,可以通过设置alpha参数来对泛化能力做出调整,增大alpha会使系数更加趋向于0,可能有助于提高泛化能力。
ridge10 = Ridge(alpha=10).fit(X_train,y_train)
print('训练集准确度:{:.2f}'.format(ridge10.score(X_train,y_train)))
print('测试集准确度:{:.2f}'.format(ridge10.score(X_test,y_test)))
输出
训练集准确度:0.79
测试集准确度:0.64
当alpha变得非常小时,得到的模型和线性回归相类似。
ridge01 = Ridge(alpha=0.1).fit(X_train,y_train)
print('训练集准确度:{:.2f}'.format(ridge01.score(X_train,y_train)))
print('测试集准确度:{:.2f}'.format(ridge01.score(X_test,y_test)))
输出
训练集准确度:0.93
测试集准确度:0.77
下面画出三种不同alpha下,对应的coef_大小
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)
plt.plot(ridge.coef_,'s',label='Ridge alpha=1')
plt.plot(ridge10.coef_,'>',label='Ridge alpha=10')
plt.plot(ridge01.coef_,'<',label='Ridge alpha=0.1')
plt.plot(lr.coef_,'o',label='LinearRegression')
plt.ylabel('Coefficient magnitude')
plt.xlabel('Coefficient index')
# 辅助线
# plt.hlines(y, xmin, xmax, colors='k', label='')
plt.hlines(0,0,len(lr.coef_),colors='k')
plt.ylim(-25,25)
plt.legend()
可见alpha越大,系数越靠近0,线性回归的系数最大,离0最远。
还有一种方法可以用来理解正则化的影响,就是固定alpha值,改变训练数据量。
mglearn.plots.plot_ridge_n_samples()
除了Ridge,还有一种正则化线性回归Lasso,它使用L1正则化,使得某些系数的值为0,即忽略某些特征。
将Lasso应用于扩展的波士顿房价数据集上,
from sklearn.linear_model import Lasso
lasso = Lasso().fit(X_train,y_train)
print('训练集准确度:{:.2f}'.format(lasso.score(X_train,y_train)))
print('测试集准确度:{:.2f}'.format(lasso.score(X_test,y_test)))
print('使用的特征个数:{}'.format(np.sum(lasso.coef_!=0)))
输出
训练集准确度:0.29
测试集准确度:0.21
使用的特征个数:4
可以看出Lasso在训练集和测试集上表现都很差,表示存在欠拟合,为了降低欠拟合,我们对Lasso的alpha进行减小,同时增大max_iter的值
lasso001 = Lasso(alpha=0.01,max_iter=100000).fit(X_train,y_train)
print('训练集准确度:{:.2f}'.format(lasso001.score(X_train,y_train)))
print('测试集准确度:{:.2f}'.format(lasso001.score(X_test,y_test)))
print('使用的特征个数:{}'.format(np.sum(lasso001.coef_!=0)))
输出
训练集准确度:0.90
测试集准确度:0.77
使用的特征个数:33
由此可见,减小alpha值,使得欠拟合的程度得到改善。同理,alpha值过小,模型的性能也会变得和线性回归类似。
lasso00001 = Lasso(alpha=0.0001,max_iter=100000).fit(X_train,y_train)
print('训练集准确度:{:.2f}'.format(lasso00001.score(X_train,y_train)))
print('测试集准确度:{:.2f}'.format(lasso00001.score(X_test,y_test)))
print('使用的特征个数:{}'.format(np.sum(lasso00001.coef_!=0)))
输出
训练集准确度:0.95
测试集准确度:0.64
使用的特征个数:96
对不同模型的系数进行绘图,
plt.plot(lasso.coef_,'s',label='Lasso alpha=1')
plt.plot(lasso001.coef_,'>',label='Lasso alpha=0.01')
plt.plot(lasso00001.coef_,'<',label='Lasso alpha=0.0001')
plt.plot(ridge01.coef_,'o',label='Ridge alpha=0.1')
plt.ylabel('Coefficient magnitude')
plt.xlabel('Coefficient index')
plt.ylim(-25,25)
plt.legend(ncol=2,loc=(0.09,1.05))