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

Python神经网络预测质量量化求助:R²值异常排查与评估方法

解决MLP回归模型R²为负的问题及优化评估方案

首先得纠正一个常见误区:R²值并非只能限制在-1到1之间。它的计算公式是 $R^2 = 1 - \frac{SS_{res}}{SS_{tot}}$,其中$SS_{res}$是预测值与真实值的残差平方和,$SS_{tot}$是真实值与均值的平方和。如果你的模型预测效果比直接用训练集y的均值还差(也就是$SS_{res} > SS_{tot}$),R²就会变成负数,甚至远小于-1——这正是你当前遇到的情况。

接下来我们一步步排查问题,并给出更全面的模型评估方案:

一、排查代码中的潜在问题

1. 缺失值处理不彻底

你用df.dropna(how='all')只删除了全为空值的行,但单个特征或目标列的空值依然存在。MLPRegressor无法处理缺失值,这会直接导致模型训练异常、预测效果极差。建议修改为:

# 删除任何包含空值的行
df2 = df.dropna()

之后可以再验证数据是否还有空值:

print(df2.isnull().sum())

2. 未对目标变量y做标准化

神经网络对输入输出的数值范围非常敏感。你仅标准化了特征X,但如果Fuel Rate的数值范围较大,模型输出层很难拟合这么大的数值,直接导致残差平方和暴增。建议对y也做标准化处理:

from sklearn.preprocessing import StandardScaler

# 初始化y的标准化器
scaler_y = StandardScaler()
y_train_scaled = scaler_y.fit_transform(y_train.values.reshape(-1, 1))
y_test_scaled = scaler_y.transform(y_test.values.reshape(-1, 1))

# 用标准化后的y训练模型
rna.fit(X_train, y_train_scaled.ravel())

# 预测后反标准化回原始尺度
y_predicted_scaled = rna.predict(X_test)
y_predicted = scaler_y.inverse_transform(y_predicted_scaled.reshape(-1, 1))

3. MLP模型参数可能不合理

  • 迭代次数不足:max_iter=2000不一定能让模型收敛,你可以查看损失曲线判断:
    plt.plot(rna.loss_curve_)
    plt.title('MLP Training Loss Curve')
    plt.xlabel('Iterations')
    plt.ylabel('Loss')
    plt.show()
    
    如果曲线还在持续下降,说明需要增加max_iter(比如调到5000)或调大学习率learning_rate_init(默认0.001,可尝试0.01)。
  • 网络结构不合适:hidden_layer_sizes=(13,13,13)可能过于复杂或简单。如果特征数量少,三层13神经元可能过拟合;如果特征维度高,又可能欠拟合。可以先尝试简化结构(比如(6,6))再调整。
  • 随机初始化影响:MLP权重是随机初始化的,单次训练可能得到极差结果。建议设置固定随机种子保证可复现,或多次训练取平均:
    rna = MLPRegressor(hidden_layer_sizes=(13,13,13), max_iter=2000, random_state=42)
    

4. 数据相关性与划分问题

  • 检查特征与Fuel Rate的相关性:如果特征和目标完全无关,模型自然学不到有效规律。可以用热力图查看:
    import seaborn as sns
    corr = df2.corr()
    sns.heatmap(corr, annot=True, cmap='coolwarm')
    plt.show()
    
  • 验证训练集和测试集的分布一致性:对比两者的特征均值、方差,避免划分后数据分布差异过大。

二、更全面的模型评估方案

除了R²,建议结合以下方法全面评估模型性能:

1. 基础回归指标

同时计算MSE、RMSE、MAE,这些指标更直观反映预测误差的大小:

from sklearn.metrics import mean_squared_error, mean_absolute_error

mse = mean_squared_error(y_test, y_predicted)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_predicted)
r2 = r2_score(y_test, y_predicted)

print(f"MSE: {mse:.4f}")
print(f"RMSE: {rmse:.4f}")
print(f"MAE: {mae:.4f}")
print(f"R²: {r2:.4f}")

2. 可视化评估

  • 真实值vs预测值散点图:直观查看拟合程度,理想情况下点应集中在y=x直线附近:
    plt.scatter(y_test, y_predicted)
    plt.plot([y.min(), y.max()], [y.min(), y.max()], 'r--')  # y=x参考线
    plt.xlabel('True Fuel Rate')
    plt.ylabel('Predicted Fuel Rate')
    plt.title('True vs Predicted Values')
    plt.show()
    
  • 残差分布图:残差(真实值-预测值)应随机分布在0附近,无明显趋势,否则说明模型存在偏差:
    residuals = y_test - y_predicted.ravel()
    plt.scatter(y_predicted, residuals)
    plt.axhline(y=0, color='r', linestyle='--')
    plt.xlabel('Predicted Fuel Rate')
    plt.ylabel('Residuals')
    plt.title('Residual Plot')
    plt.show()
    

3. 交叉验证

用k折交叉验证替代单次训练测试划分,避免数据划分的偶然性,结果更可靠:

from sklearn.model_selection import cross_val_score
from sklearn.pipeline import Pipeline

# 用Pipeline整合预处理和模型
pipeline = Pipeline([
    ('scaler_x', StandardScaler()),
    ('scaler_y', StandardScaler()),
    ('mlp', MLPRegressor(hidden_layer_sizes=(13,13,13), max_iter=2000, random_state=42))
])

# 交叉验证,用负MSE作为评分指标(cross_val_score默认越高越好)
scores = cross_val_score(pipeline, X, y, cv=5, scoring='neg_mean_squared_error')
rmse_scores = np.sqrt(-scores)

print(f"Cross-validated RMSE scores: {rmse_scores}")
print(f"Mean RMSE: {rmse_scores.mean():.4f}")

4. 超参数调优

用网格搜索优化MLP的参数,找到最优的网络结构和训练配置:

from sklearn.model_selection import GridSearchCV

param_grid = {
    'mlp__hidden_layer_sizes': [(6,), (6,6), (13,13)],
    'mlp__activation': ['relu', 'tanh'],
    'mlp__learning_rate_init': [0.001, 0.01],
    'mlp__max_iter': [2000, 5000]
}

grid_search = GridSearchCV(pipeline, param_grid, cv=5, scoring='neg_mean_squared_error')
grid_search.fit(X, y)

print(f"Best parameters: {grid_search.best_params_}")
print(f"Best cross-validated RMSE: {np.sqrt(-grid_search.best_score_):.4f}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:36:11