模型训练导航:
【机器学习】模型训练:scikitLearn线性模型的公式法与三种梯度下降法求解
【机器学习】欠拟合及过拟合与学习曲线、误差来源
【机器学习】逻辑回归logit与softmax
正则化多项式模型,只需要减少多项式的阶数。
正则化线性模型,有以下几种方式:
岭回归
将线性摸中系数的平方项添加至成本函数,如均方误差,这迫使学习算法不仅拟合数据,而且还使模型权重尽可能小。
仅在训练期间将正则化项添加到成本函数中,评估模型性能时,不应将正则项带入。
超参数λ控制要对模型进行正则化的程度。如果λ=0,则岭回归仅是线性回归。如果λ非常大,则所有权重最终都非常接近于零,结果是一条经过数据均值的平线。**λ的增加会导致更平坦(即不极端,更合理)的预测,从而减少了模型的方差,但增加了其偏差。**体现了模型方差与偏差的权衡。
下图中a即为λ
注意i=0时的参数不参与正则化。
在执行岭回归之前缩放数据(例如使用StandardScaler)很重要,因为它对输入特征的缩放敏感。大多数正则化模型都需要如此。
使用闭式解时:
from sklearn.linear_model import Ridge
ridge_reg = Ridge(alpha=1, solver="cholesky", random_state=42)
ridge_reg.fit(X, y)
使用SGD顺便带L2:
sgd_reg = SGDRegressor(penalty="l2", max_iter=1000, tol=1e-3, random_state=42)
sgd_reg.fit(X, y.ravel())
sgd_reg.predict([[1.5]])
其中:
solver:字符串。指定求解最优化问题的算法。
(1).solver=‘auto’,根据数据集自动选择算法。
(2).solver=‘svd’,采用奇异值分解的方法来计算
(3).solver=‘cholesky’,采用scipy.linalg.solve函数求解最优解,它使用AndréLouis Cholesky矩阵分解技术。
(4).solver=‘sparse_cg’,才哟个scipy.sparse.linalg.cg函数来求取最优解。
(5).solver=‘sag’,采用Stochastic Average Gradient descent算法求解最优化问题。
Lasso回归
Lasso回归的一个重要特点是它倾向于完全消除掉最不重要特征的权重(也就是将它们设置为零)。换句话说,Lasso回归会自动执行特征选择并输出一个稀疏模型(即只有很少的特征有非零权重)。
注意,Lasso回归的λ要更小一些,以匹配更小的参数。
sgd_reg = SGDRegressor(penalty="l1", max_iter=1000, tol=1e-3, random_state=42)
sgd_reg.fit(X, y.ravel())
sgd_reg.predict([[1.5]])
弹性网络
正则项是岭和Lasso正则项的简单混合,你可以控制混合比r。当r=0时,弹性网络等效于岭回归,而当r=1时,弹性网络等效于Lasso回归
from sklearn.linear_model import ElasticNet
elastic_net = ElasticNet(alpha=0.1, l1_ratio=0.5, random_state=42)
elastic_net.fit(X, y)
elastic_net.predict([[1.5]])
提前停止
对于梯度下降这一类迭代学习的算法,还有一个与众不同的正则化方法,就是在验证误差达到最小值时停止训练,该方法叫作提前停止法。
使代价函数最小的点可能出现过拟合。以l2为例做证明,如下图所示:
对应代码:
from copy import deepcopy
poly_scaler = Pipeline([
("poly_features", PolynomialFeatures(degree=90, include_bias=False)),
("std_scaler", StandardScaler())
])
X_train_poly_scaled = poly_scaler.fit_transform(X_train)
X_val_poly_scaled = poly_scaler.transform(X_val)
sgd_reg = SGDRegressor(max_iter=1, tol=-np.infty, warm_start=True,
penalty=None, learning_rate="constant", eta0=0.0005, random_state=42)
#warm_start=True,每次调用fit继续训练,而不是从头开始
minimum_val_error = float("inf")
best_epoch = None
best_model = None
for epoch in range(1000):
sgd_reg.fit(X_train_poly_scaled, y_train) # continues where it left off
y_val_predict = sgd_reg.predict(X_val_poly_scaled)
val_error = mean_squared_error(y_val, y_val_predict)
if val_error < minimum_val_error:
minimum_val_error = val_error
best_epoch = epoch
best_model = deepcopy(sgd_reg)