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

SVR训练拟合完美但测试集始终预测平均值问题咨询

这种情况我之前做时间序列SVR预测时也碰到过!核心问题大概率是模型欠拟合,或者特征/参数/数据处理环节没踩对节奏,给你几个具体的排查和解决方向:

1. 必须对输入特征X做缩放(遵循训练集拟合、测试集转换的原则)

RBF核的SVR对特征尺度极度敏感,你目前的代码只处理了目标变量Y,输入X完全没做缩放,这会导致核函数无法有效捕捉特征和目标的关联,最终模型只能输出均值凑数。正确的缩放流程应该是:

from sklearn.preprocessing import StandardScaler
import numpy as np

# 假设已经按时间顺序划分好X_train, X_test, Y_train, Y_test
sc_x = StandardScaler()
X_train_scaled = sc_x.fit_transform(X_train)
X_test_scaled = sc_x.transform(X_test)  # 注意:测试集只能用训练集的缩放器转换,不能重新fit

sc_y = StandardScaler()
Y_train_scaled = sc_y.fit_transform(Y_train.reshape(-1,1)).ravel()  # SVR需要一维的目标数组

2. 调优RBF核SVR的核心参数

默认参数(C=1.0, gamma='scale', epsilon=0.1)对时间序列数据来说太保守,很容易欠拟合。重点调这三个参数:

  • C(正则化强度):C越小,模型越倾向于“偷懒”输出均值;尝试逐步增大C(比如10、100、1000),让模型更关注拟合数据细节。
  • gamma(核带宽):gamma越小,核函数的影响范围越广,模型输出越平滑;可以手动设置gamma=0.1/1/10,或者用网格搜索自动找最优参数:
    from sklearn.svm import SVR
    from sklearn.model_selection import GridSearchCV
    
    param_grid = {
        'C': [0.1, 1, 10, 100, 1000],
        'gamma': [1, 0.1, 0.01, 0.001],
        'epsilon': [0.001, 0.01, 0.1, 0.2]
    }
    grid_search = GridSearchCV(SVR(kernel='rbf'), param_grid, cv=5, verbose=2)
    grid_search.fit(X_train_scaled, Y_train_scaled)
    print("最优参数组合:", grid_search.best_params_)
    # 用最优参数训练模型
    best_model = grid_search.best_estimator_
    
  • epsilon(不敏感损失阈值):如果epsilon太大,模型允许的误差范围太宽,会直接忽略数据的波动;可以适当减小epsilon,让模型对误差更敏感。

3. 优化时间序列的特征工程

只用单一时间步的X作为输入,模型根本无法捕捉时间序列的趋势、周期性这些关键信息,自然只能输出均值。建议构造滞后特征(用过去n步的值作为当前步的输入):

import pandas as pd

def build_lag_features(series, lag_steps=5):
    df = pd.DataFrame(series, columns=['value'])
    # 生成前1到lag_steps步的滞后特征
    for i in range(1, lag_steps+1):
        df[f'lag_{i}'] = df['value'].shift(i)
    df = df.dropna()  # 去掉包含NaN的行
    # 特征是滞后列,目标是当前值
    X = df.drop('value', axis=1).values
    Y = df['value'].values
    return X, Y

# 假设你的原始时间序列是x
X, Y = build_lag_features(x, lag_steps=5)
# 再按时间顺序划分训练测试集(绝对不能随机划分!)
train_size = int(len(X)*0.8)
X_train, X_test = X[:train_size], X[train_size:]
Y_train, Y_test = Y[:train_size], Y[train_size:]

4. 检查数据划分和预测逆变换

  • 时间序列必须按时间顺序划分训练测试集,绝对不能打乱顺序随机划分,否则模型会“偷看”未来数据,导致训练集拟合完美但测试集完全失效。
  • 如果对Y做了标准化,预测后一定要用sc_y.inverse_transform()转换回原始尺度,否则你看到的“平均值”其实是标准化后的均值(0附近):
    y_pred_scaled = best_model.predict(X_test_scaled)
    y_pred = sc_y.inverse_transform(y_pred_scaled.reshape(-1,1))  # 转换回原始数值范围
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:24:42