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

使用sklearn设置随机种子后神经网络结果仍不一致的技术求助

问题分析与解决方案

咱们一步步拆解你遇到的问题:设置随机种子后结果仍不一致,以及模型性能波动极大(R²在-0.1到0.6之间),这两个问题其实紧密相关,下面来逐一解决:

一、为什么np.random.seed没起作用?

你踩了Sklearn随机控制的一个常见坑:
Sklearn从0.21版本开始,默认使用自身独立的随机数生成器,不受全局np.random.seed的影响。也就是说,即使你设置了numpy的种子,MLPRegressor初始化权重、内部随机操作的随机性依然不受控制——必须显式给MLPRegressor设置random_state参数,才能固定它的随机行为。

另外,虽然你的train_test_split写在循环外,暂时不会影响当前结果,但如果后续调整代码把它放进循环,没设置random_state的话,每次划分的训练测试集都会不一样,结果自然也会波动。固定这个参数能让你的实验完全可复现。

二、模型性能波动大的核心原因:小数据集+过拟合

你的数据集只有241行、22列,属于典型的小样本场景:

  • 测试集仅约48行数据,样本量太小,单次测试的结果本身就容易受随机因素干扰;
  • 你用的hidden_layer_sizes=(22,22,22)太复杂了——三层隐藏层,每层神经元数和特征数持平,参数总量远大于样本量,模型很容易过拟合训练数据,不同的权重初始化会导致模型在测试集上的表现天差地别。

三、具体解决步骤与修改后的代码

1. 固定所有随机源

把train_test_split和MLPRegressor的random_state都显式设置,确保每一次实验的随机性完全可控。

2. 简化模型+加入正则化

减少隐藏层/神经元数量,同时开启L2正则化(alpha参数)或早停(early_stopping=True),抑制过拟合。

3. 用交叉验证替代单次测试

小样本下,K折交叉验证能更稳定地评估模型性能,避免单次测试集的偶然性。

修改后的代码示例:

import matplotlib.pyplot as plt
import pandas as pd
import sklearn
import numpy as np
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.neural_network import MLPRegressor
from sklearn import metrics
from math import sqrt

# 加载数据
data = pd.read_csv(r"D:\PhD\1styear\machinelearning\NNforF2050\DATAnnF2050.csv")
print(data.shape)
print(data.dtypes)

x = data.drop('EnergyConsumpManuf', axis=1)
y = data['EnergyConsumpManuf']

# 固定训练测试集划分的随机种子
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)

# 数据标准化
scaler = StandardScaler()
scaler.fit(x_train)
x_train = scaler.transform(x_train)
x_test = scaler.transform(x_test)

# 测试固定随机种子后的模型稳定性
fixed_seed = 42
np.random.seed(fixed_seed)
# 简化模型结构+加入正则化+固定random_state
mlp = MLPRegressor(
    hidden_layer_sizes=(10, 5),  # 简化结构:两层隐藏层,减少神经元数量
    max_iter=2000,
    learning_rate_init=0.001,
    random_state=fixed_seed,  # 固定模型的随机状态
    alpha=0.01,  # L2正则化,抑制过拟合
    early_stopping=True  # 早停:当验证集性能不再提升时停止训练
)

mlp.fit(x_train, y_train)
predictions = mlp.predict(x_test)

print('固定种子后的结果:')
print('MSE test: ', metrics.mean_squared_error(y_test, predictions))
print('RMS: ', sqrt(metrics.mean_squared_error(y_test, predictions)))
print('R²: ', sklearn.metrics.r2_score(y_test, predictions))
print('MAE: ', metrics.mean_absolute_error(y_test, predictions))

# 用5折交叉验证评估模型稳定性
cv_scores = cross_val_score(mlp, scaler.transform(x), y, cv=5, scoring='r2')
print('\n5折交叉验证的R²分数:', cv_scores)
print('平均R²:', cv_scores.mean())
print('R²标准差:', cv_scores.std())

四、额外建议

  • 如果条件允许,收集更多数据是解决小样本问题最根本的办法;
  • 可以尝试调整alpha的值(比如0.001、0.1),或者测试不同的隐藏层结构,找到最适配你数据集的模型;
  • 若需要对比不同种子下的模型表现,把random_state设为循环变量i即可,但要确保其他随机源都固定不变。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:52:17