5.线性回归-欠拟合和过拟合以及过拟合时的解决方法-正则化
1 定义
- 过拟合:一个假设在训练数据上能够获得比其他假设更好的拟合, 但是在测试数据集上却不能很好地拟合数据,此时认为这个假设出现了过拟合的现象。(模型过于复杂)
- 欠拟合:一个假设在训练数据上不能获得更好的拟合,并且在测试数据集上也不能很好地拟合数据,此时认为这个假设出现了欠拟合的现象。(模型过于简单)
那么是什么原因导致模型复杂?线性回归进行训练学习的时候变成模型会变得复杂,这里就对应前面再说的线性回归的两种关系,非线性关系的数据,也就是存在很多无用的特征或者现实中的事物特征跟目标值的关系并不是简单的线性关系?
2 原因以及解决办法
- 欠拟合原因以及解决办法
- 原因:学习到数据的特征过少
- 解决办法:
- 1)添加其他特征项,有时候我们模型出现欠拟合的时候是因为特征项不够导致的,可以添加其他特征项来很好地解决。例如,“组合”、“泛化”、“相关性”三类特征是特征添加的重要手段,无论在什么场景,都可以照葫芦画瓢,总会得到意想不到的效果。除上面的特征之外,“上下文特征”、“平台特征”等等,都可以作为特征添加的首选项。
- 2)添加多项式特征,这个在机器学习算法里面用的很普遍,例如将线性模型通过添加二次项或者三次项使模型泛化能力更强。
- 过拟合原因以及解决办法
- 原因:原始特征过多,存在一些嘈杂特征, 模型过于复杂是因为模型尝试去兼顾各个测试数据点
- 解决办法:
- 1)重新清洗数据,导致过拟合的一个原因也有可能是数据不纯导致的,如果出现了过拟合就需要我们重新清洗数据。
- 2)增大数据的训练量,还有一个原因就是我们用于训练的数据量太小导致的,训练数据占总数据的比例过小。
- 3)正则化
- 4)减少特征维度,防止维灾难
3 正则化
3.1 什么是正则化
如何解决?
在学习的时候,数据提供的特征有些影响模型复杂度或者这个特征的数据点异常较多,所以算法在学习的时候尽量减少这个特征的影响(甚至删除某个特征的影响),这就是正则化
3.2 正则化类别
- L2正则化
- 作用:可以使得其中一些W的都很小,都接近于0,削弱某个特征的影响
- 优点:越小的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象
- Ridge回归
- L1正则化
- 作用:可以使得其中一些W的值直接为0,删除这个特征的影响
- LASSO回归
3.3 正则化线性模型
- Ridge Regression 岭回归
- Lasso 回归
- Elastic Net 弹性网络
- Early stopping
1 Ridge Regression (岭回归,又名 Tikhonov regularization)
岭回归是线性回归的正则化版本,即在原来的线性回归的 cost function 中添加正则项(regularization term):
以达到在拟合数据的同时,使模型权重尽可能小的目的,岭回归代价函数:
- α=0:岭回归退化为线性回归
2 Lasso Regression(Lasso 回归)
Lasso 回归是线性回归的另一种正则化版本,正则项为权值向量的ℓ1范数。
Lasso回归的代价函数 :
【注意 】
- Lasso Regression 的代价函数在 θi=0处是不可导的.
- 解决方法:在θi=0处用一个次梯度向量(subgradient vector)代替梯度,如下式
- Lasso Regression 的次梯度向量
Lasso Regression 有一个很重要的性质是:倾向于完全消除不重要的权重。
例如:当α 取值相对较大时,高阶多项式退化为二次甚至是线性:高阶多项式特征的权重被置为0。
也就是说,Lasso Regression 能够自动进行特征选择,并输出一个稀疏模型(只有少数特征的权重是非零的)。
3 Elastic Net (弹性网络)
弹性网络在岭回归和Lasso回归中进行了折中,通过 混合比(mix ratio) r 进行控制:
- r=0:弹性网络变为岭回归
- r=1:弹性网络便为Lasso回归
弹性网络的代价函数 :
小结:
-
常用:岭回归
-
假设只有少部分特征是有用的:
- 弹性网络
- Lasso
- 一般来说,弹性网络的使用更为广泛。因为在特征维度高于训练样本数,或者特征是强相关的情况下,Lasso回归的表现不太稳定。
-
-
api:
-
from sklearn.linear_model import Ridge, ElasticNet, Lasso
-
-
3.4线性回归的改进-岭回归
- sklearn.linear_model.Ridge(alpha=1.0, fit_intercept=True,solver="auto", normalize=False)
- 具有l2正则化的线性回归
- alpha:正则化力度,也叫 λ
- λ取值:0~1 1~10
- solver:会根据数据自动选择优化方法
- sag:如果数据集、特征都比较大,选择该随机梯度下降优化
- normalize:数据是否进行标准化
- normalize=False:可以在fit之前调用preprocessing.StandardScaler标准化数据
- Ridge.coef_:回归权重
- Ridge.intercept_:回归偏置
Ridge方法相当于SGDRegressor(penalty='l2', loss="squared_loss"),只不过SGDRegressor实现了一个普通的随机梯度下降学习,推荐使用Ridge(实现了SAG)
- sklearn.linear_model.RidgeCV(_BaseRidgeCV, RegressorMixin)
- 具有l2正则化的线性回归,可以进行交叉验证
- coef_:回归系数
class _BaseRidgeCV(LinearModel): def __init__(self, alphas=(0.1, 1.0, 10.0), fit_intercept=True, normalize=False,scoring=None, cv=None, gcv_mode=None, store_cv_values=False):
3.4.2 观察正则化程度的变化,对结果的影响?
- 正则化力度越大,权重系数会越小
- 正则化力度越小,权重系数会越大
3.3.3波士顿房价预测
def linear_model3(): """ 线性回归:岭回归 :return: """ # 1.获取数据 data = load_boston() # 2.数据集划分 x_train, x_test, y_train, y_test = train_test_split(data.data, data.target, random_state=22) # 3.特征工程-标准化 transfer = StandardScaler() x_train = transfer.fit_transform(x_train) x_test = transfer.fit_transform(x_test) # 4.机器学习-线性回归(岭回归) estimator = Ridge(alpha=1) # estimator = RidgeCV(alphas=(0.1, 1, 10)) estimator.fit(x_train, y_train) # 5.模型评估 # 5.1 获取系数等值 y_predict = estimator.predict(x_test) print("预测值为:\n", y_predict) print("模型中的系数为:\n", estimator.coef_) print("模型中的偏置为:\n", estimator.intercept_) # 5.2 评价 # 均方误差 error = mean_squared_error(y_test, y_predict) print("误差为:\n", error)
1 sklearn模型的保存和加载API
- from sklearn.externals import joblib
- 保存:joblib.dump(estimator, 'test.pkl')
- 加载:estimator = joblib.load('test.pkl')