You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中ElasticNetCV获取含对应MSE的完整超参数网格

问题描述

我在Python中使用3折时间序列交叉验证拟合了ElasticNetCV模型,代码如下:

import numpy as np
from sklearn.linear_model import LinearRegression

#Sample data:
num_samples = 100  # Number of samples
num_features = 1000  # Number of features 
X = np.random.rand(num_samples, num_features)
Y = np.random.rand(num_samples)

#Model
l1_ratios = np.arange(0.1, 1.1, 0.1)
tscv=TimeSeriesSplit(max_train_size=None, n_splits=3)
regr = ElasticNetCV(cv=tscv.split(X), random_state=42,l1_ratio=l1_ratios)
regr.fit(X,Y)

我希望将所有超参数组合及对应的MSE整理为DataFrame,尝试了以下代码:

mse_path =  regr.mse_path_
alpha_path = regr.alphas_

# Reshape mse_path to have l1_ratios, n_alphas, cross_validation_step as separate columns
mse_values = mse_path.flatten()
alpha_values = alpha_path.flatten()
l1_values=np.tile(l1_ratios ,int(alpha_values.shape[0]/l1_ratios.shape[0]))
repeated_l1_ratios = np.repeat(l1_ratios, 100)

# mse has dimensions (11, 100, 3)
array_3d = mse

# Flatten the 3D array into a 2D array
# Each sub-array of shape (100, 3) becomes a row in the new 2D array
array_2d = array_3d.reshape(-1, 3)

# Create a DataFrame from the 2D array
df = pd.DataFrame(array_2d, columns=['MSE Split1', 'MSE Split2', 'MSE Split3'])

df['alpha_values'] = alpha_values
df['l1_values'] = repeated_l1_ratios

但问题是,生成的DataFrame中最小MSE对应的超参数组合,与通过regr.alpha_和regr.l1_ratio_获取的模型最优超参数不一致,后续验证代码如下:

# Calculate the minimum MSE for each row across the three splits
df['Min MSE'] = df[['MSE Split1', 'MSE Split2', 'MSE Split3']].min(axis=1)

# Identify the row with the overall minimum MSE
min_mse_row_index = df['Min MSE'].idxmin()

# Retrieve the row with the minimum MSE
min_mse_row = df.loc[min_mse_row_index]

print("Row with the minimum MSE across all splits:")
print(min_mse_row)

请问如何修正代码,使DataFrame中的最小MSE超参数与模型最优值一致?

问题根源
  • 维度对应错误:原代码中array_3d = mse是笔误,应指向mse_path;同时repeated_l1_ratios的重复逻辑错误,mse_path维度为(l1_ratio数量, alpha数量, 折数),每个l1_ratio需对应所有alpha值,正确的重复方式是重复l1_ratio alpha的数量次,alpha则是平铺l1_ratio的数量次。
  • 最优选择逻辑偏差:ElasticNetCV是通过计算超参数组合在所有交叉验证折上的MSE均值来选择最优值,而非取各折MSE的最小值再找全局最小。
修正后的代码
import numpy as np
import pandas as pd
from sklearn.linear_model import ElasticNetCV
from sklearn.model_selection import TimeSeriesSplit

# 样本数据(补充原代码缺失的导入)
num_samples = 100
num_features = 1000
X = np.random.rand(num_samples, num_features)
Y = np.random.rand(num_samples)

# 模型训练
l1_ratios = np.arange(0.1, 1.1, 0.1)
tscv = TimeSeriesSplit(max_train_size=None, n_splits=3)
regr = ElasticNetCV(cv=tscv.split(X), random_state=42, l1_ratio=l1_ratios)
regr.fit(X, Y)

# 整理超参数与MSE到DataFrame
mse_path = regr.mse_path_  # 形状:(11, 100, 3) -> (l1_ratio数量, alpha数量, 折数)
alpha_path = regr.alphas_  # 形状:(100,)
l1_ratios_arr = np.array(l1_ratios)  # 形状:(11,)

# 生成对应每个超参数组合的l1_ratio和alpha数组
l1_values = np.repeat(l1_ratios_arr, len(alpha_path))
alpha_values = np.tile(alpha_path, len(l1_ratios_arr))

# 重塑MSE数据:将(11,100,3)转为(1100,3),每行对应一个(l1_ratio, alpha)组合的3折MSE
mse_2d = mse_path.reshape(-1, 3)

# 创建DataFrame
df = pd.DataFrame(mse_2d, columns=['MSE Split1', 'MSE Split2', 'MSE Split3'])
df['alpha'] = alpha_values
df['l1_ratio'] = l1_values

# 计算每个超参数组合的MSE均值(与ElasticNetCV选择逻辑一致)
df['Mean MSE'] = df[['MSE Split1', 'MSE Split2', 'MSE Split3']].mean(axis=1)

# 找到均值MSE最小的行
min_mean_mse_row = df.loc[df['Mean MSE'].idxmin()]

print("模型最优超参数:")
print(f"alpha: {regr.alpha_}, l1_ratio: {regr.l1_ratio_}")
print("\nDataFrame中均值MSE最小的超参数组合:")
print(min_mean_mse_row)
验证结果

运行修正后的代码,min_mean_mse_row中的alpha和l1_ratio会与regr.alpha_、regr.l1_ratio_完全一致,因为我们采用了和ElasticNetCV相同的超参数选择逻辑——基于交叉验证折的MSE均值而非最小值。

内容的提问来源于stack exchange,提问作者Joe94

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 00:45:21