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

如何为Ridge回归训练合适的alpha值?附现有实现代码

如何用数据集前半部分确定Ridge回归的alpha值?

这方法其实就是时间序列场景下的「训练-验证」拆分调参思路,因为你做的是市场收益预测(典型的时间序列任务),不能像普通机器学习那样随机拆分数据,必须严格按时间顺序来——用「过去的前半段数据」调参,再用「后半段未来数据」验证效果。具体实现步骤和代码我帮你梳理好了:


核心思路拆解

  1. 按时间拆分数据集:把整个数据集切成前半段(调参+训练用)和后半段(仅用于最终验证,调参过程完全碰不到),模拟「用历史数据找最优参数,再用未来数据检验效果」的真实场景。
  2. 避免数据泄露:标准化的均值/方差只能用前半段数据计算,测试集必须复用这个统计量,绝对不能用整个数据集的均值!
  3. 用交叉验证选最优alpha:在前半段数据内部做交叉验证(比如5折),遍历候选alpha值,选在交叉验证上表现最好的那个,比你之前的试错法靠谱多了。

修改后的完整代码(结合你的原代码)

import pandas as pd
from sklearn import linear_model
from sklearn.model_selection import GridSearchCV

# 假设你的df已加载,cols是特征列,horizon是你的时间跨度参数
# 1. 按时间拆分:前半段调参+训练,后半段留作测试
split_point = len(df) // 2  # 取中间位置拆分,你也可以按比例(比如前60%)
df_train_tune = df.iloc[:split_point].copy()
df_test = df.iloc[split_point:].copy()

# 2. 仅用前半段数据做标准化(关键:防止数据泄露)
feature_cols = cols  # 你的原特征列列表
target_col = f'SPXR_{horizon}D'

for col in feature_cols:
    # 只从训练调参集计算均值和标准差
    train_mean = df_train_tune[col].mean()
    train_std = df_train_tune[col].std(ddof=0)
    # 标准化训练调参集
    df_train_tune[col] = (df_train_tune[col] - train_mean) / train_std
    # 测试集必须用训练集的统计量做标准化!
    df_test[col] = (df_test[col] - train_mean) / train_std

# 3. 准备调参用的X和y
X_tune = df_train_tune[feature_cols]
y_tune = df_train_tune[target_col]

# 4. 定义候选alpha范围(可以根据需求调整,比如加更小或更大的值)
alpha_options = [0.001, 0.01, 0.1, 0.5, 1, 2, 5, 10, 20]
# 用GridSearchCV做交叉验证选最优alpha
ridge_model = linear_model.Ridge()
grid_search = GridSearchCV(
    estimator=ridge_model,
    param_grid={'alpha': alpha_options},
    cv=5,  # 5折交叉验证,你也可以改成10折
    scoring='neg_mean_squared_error'  # 用均方误差作为评估指标,适合回归任务
)
grid_search.fit(X_tune, y_tune)

# 查看最优结果
best_alpha = grid_search.best_params_['alpha']
print(f"通过前半段数据找到的最优alpha:{best_alpha}")
print(f"交叉验证上的最优均方误差:{-grid_search.best_score_}")  # 因为scoring是负的,所以取反

# 5. 用最优alpha训练最终模型(用整个前半段数据)
final_ridge_model = linear_model.Ridge(alpha=best_alpha)
final_ridge_model.fit(X_tune, y_tune)

# 6. (可选)用后半段测试集评估模型泛化能力
X_test = df_test[feature_cols]
y_test = df_test[target_col]
test_r2 = final_ridge_model.score(X_test, y_test)
test_mse = ((final_ridge_model.predict(X_test) - y_test)**2).mean()
print(f"测试集R²分数:{test_r2:.4f}")
print(f"测试集均方误差:{test_mse:.4f}")

几个关键注意点

  • 为什么不能随机拆分?:你的任务是预测未来市场收益,随机拆分会把未来的数据混入训练调参过程,导致模型看起来效果很好,但实际用历史数据预测未来时完全失效。按时间顺序拆分才符合真实逻辑。
  • 交叉验证的作用:在前半段数据内部做交叉验证,能避免「用单一训练集调参导致过拟合调参集」的问题,找到的alpha更具泛化性。
  • 如果你的数据集很大:也可以把前半段再拆成「训练集」和「验证集」,直接在验证集上选alpha,但交叉验证的效果通常更好。

内容的提问来源于stack exchange,提问作者Évariste Galois

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:52:05