如何用Sklearn高效实现LASSO模型的固定验证集调参?
自定义训练/验证集下的LASSO最优alpha选择
我需要用sklearn训练LASSO模型,已有专门划分好的训练集和验证集。目标是自动生成一系列alpha值(L1惩罚强度),针对每个alpha用训练集拟合模型后在验证集评估性能,最终选择验证集表现最优的模型。
已尝试的方法
1. LassoCV + 自定义1折CV迭代器
将训练集和验证集绑定为1折交叉验证迭代器传入cv参数,但fit()方法最终会用最优alpha和合并后的全量数据训练模型,必须手动取出最优alpha再重新调用Lasso训练,步骤繁琐:
import numpy as np from sklearn.linear_model import LassoCV from sklearn.datasets import make_regression X, y = make_regression(noise = 4, random_state = 0) Nrow, Ncol = len(X), len(X[0]) Ntrain = int(np.round(Nrow * 0.7)) Nvalid = Nrow - Ntrain trainInd = np.asarray([i for i in range(Ntrain)]) validInd = np.asarray([i for i in range(Ntrain, Nrow)]) trainValidInd = [(trainInd, validInd)] cvIter = iter(trainValidInd) reg = LassoCV(cv = cvIter, verbose = True).fit(X, y) # 问题:fit()会用最优alpha和合并后的全部数据训练模型
2. lasso_path
尝试过sklearn.linear_model.lasso_path,但不清楚如何结合验证集做预测,且该方法不返回截距项,无法获取模型截距。
3. 临时 workaround
给验证集样本设置极小权重(接近0),让模型拟合时忽略验证集,测试有效但方法不够合理:
sampleW = np.asarray([1.0 for i in range(Ntrain)] + \ [1e-200 for i in range(Nvalid)]) reg = LassoCV(cv = cvIter, verbose = True).fit(X, y, sampleW)
合理高效的实现方案
方案1:手动遍历候选alpha
直接拆分训练/验证集,用LassoCV生成候选alpha(或手动指定),逐个训练并评估,最终选择最优模型:
import numpy as np from sklearn.linear_model import Lasso, LassoCV from sklearn.datasets import make_regression from sklearn.metrics import mean_squared_error # 拆分训练集和验证集 X, y = make_regression(noise=4, random_state=0) Ntrain = int(np.round(len(X) * 0.7)) X_train, X_valid = X[:Ntrain], X[Ntrain:] y_train, y_valid = y[:Ntrain], y[Ntrain:] # 生成候选alpha(基于训练集的LassoCV自动生成) lasso_cv = LassoCV(cv=5, random_state=0) lasso_cv.fit(X_train, y_train) candidate_alphas = lasso_cv.alphas_ # 或者手动指定alpha范围 # candidate_alphas = np.logspace(-4, 4, 50) # 遍历每个alpha,训练并评估 best_score = float('inf') best_alpha = None best_model = None for alpha in candidate_alphas: model = Lasso(alpha=alpha, random_state=0) model.fit(X_train, y_train) y_pred = model.predict(X_valid) # 用MSE作为评估指标,可替换为其他指标如R² score = mean_squared_error(y_valid, y_pred) if score < best_score: best_score = score best_alpha = alpha best_model = model print(f"最优alpha: {best_alpha:.4f}") print(f"验证集最优MSE: {best_score:.4f}")
方案2:GridSearchCV + 自定义CV迭代器
利用GridSearchCV,指定自定义1折CV迭代器,同时设置refit=False避免用全量数据重训,最后用最优alpha训练模型:
import numpy as np from sklearn.linear_model import Lasso from sklearn.datasets import make_regression from sklearn.model_selection import GridSearchCV # 拆分数据并生成CV迭代器 X, y = make_regression(noise=4, random_state=0) Ntrain = int(np.round(len(X) * 0.7)) trainInd = np.asarray([i for i in range(Ntrain)]) validInd = np.asarray([i for i in range(Ntrain, len(X))]) trainValidInd = [(trainInd, validInd)] # 定义参数网格 candidate_alphas = np.logspace(-4, 4, 50) param_grid = {'alpha': candidate_alphas} # 初始化GridSearchCV,refit=False避免全量重训 grid_search = GridSearchCV( estimator=Lasso(random_state=0), param_grid=param_grid, cv=trainValidInd, refit=False, scoring='neg_mean_squared_error' # 负MSE,GridSearch默认最大化得分 ) grid_search.fit(X, y) # 获取最优参数和得分 best_alpha = grid_search.best_params_['alpha'] best_score = -grid_search.best_score_ # 转为正MSE # 用最优alpha训练最终模型 best_model = Lasso(alpha=best_alpha, random_state=0) best_model.fit(X[:Ntrain], y[:Ntrain]) print(f"最优alpha: {best_alpha:.4f}") print(f"验证集最优MSE: {best_score:.4f}")
这两种方案都清晰高效,避免了临时 workaround 的不合理性,同时严格遵循训练/验证集的划分逻辑。
内容的提问来源于stack exchange,提问作者user2961927
相关产品推荐
相关产品推荐

