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

为何每次运行MLP模型得到的F1分数均存在较大差异?

问题根因

你仅在数据集拆分环节设置了随机种子,没有覆盖MLP训练流程的全部随机影响因素,因此每次运行的F1分数会出现大幅波动,具体遗漏点如下:

  • MLPClassifier实例未传入random_state参数:MLP的初始权重随机初始化、Adam优化器的批次采样、训练过程中的随机更新逻辑都依赖随机数生成器,未固定该参数时,每次运行的模型初始状态完全不同,收敛结果差异极大。
  • 未做特征标准化:MLP对特征尺度非常敏感,不同特征量纲差异过大会让损失曲面异常崎岖,模型极易收敛到差异极大的局部最优点,进一步放大结果波动。
  • 未全局固定Python、Numpy的随机种子:部分底层计算逻辑的随机行为不会被数据集拆分、模型的单独种子覆盖,全局随机状态不固定也会带来结果偏差。
  • 未设置足够的训练迭代次数:你当前代码使用MLPClassifier默认的max_iter=200参数,很多场景下模型迭代200次还没收敛就终止训练,未收敛的模型结果稳定性极差。
修复后的可复现代码
import random
import pandas as pd
import numpy as np
from sklearn.neural_network import MLPClassifier
from sklearn import metrics
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 统一固定所有随机源的种子
seed = 42
random.seed(seed)
np.random.seed(seed)

# 加载数据集
df = pd.read_csv('/content/wesad-chest-combined-classification-eda.csv')

# 移除非必要分类列
df = df.drop(['SSSQ class', 'condition'], axis='columns')

# 删除缺失值行
df = df.dropna()

# 拆分特征和标签
X = df.to_numpy()
y = df['SSSQ Label'].values
X = np.delete(X, 45, axis=1)

# 拆分训练测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=seed)

# 特征标准化:仅在训练集上拟合缩放器,避免数据泄露
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 初始化MLP分类器,固定随机种子,增加最大迭代次数保证收敛
mlp_clf = MLPClassifier(
    hidden_layer_sizes=100, 
    activation='relu',
    learning_rate_init=0.001, 
    learning_rate='adaptive', 
    momentum=0.9, 
    solver='adam', 
    random_state=seed,
    max_iter=1000
)
mlp_clf.fit(X_train, y_train)

# 预测并计算指标
y_pred = mlp_clf.predict(X_test)

print('RESULTS AFTER APPLYING MLP CLASSIFIER ON GIVEN DATA:')
print('  Accuracy: ' + str(metrics.accuracy_score(y_test, y_pred)))
print('    Recall: ' + str(metrics.recall_score(y_test,
      y_pred, average='weighted', labels=np.unique(y_pred))))
print(' Precision: ' + str(metrics.precision_score(y_test,
      y_pred, average='weighted', labels=np.unique(y_pred))))
print('  F1 Score: ' + str(metrics.f1_score(y_test, y_pred,
      average='weighted', labels=np.unique(y_pred))))
print('\nCROSS TAB RESULTS: [0 = Low, 1 = Medium, 2 = High]')
print(pd.crosstab(y_test, y_pred, colnames=['Stress Levels'], rownames=[None]))
补充说明
  • 特征标准化必须放在数据集拆分之后执行,禁止先对全量数据做缩放再拆分,否则会把测试集的统计信息泄露到训练流程中,导致指标结果虚高。
  • 完成以上配置后,每次运行的F1分数差值应该稳定在1%以内,如果仍然出现大幅波动,需要检查数据集是否存在类别极度不平衡、标签错误、特征冗余度过高的问题。
  • 如果出现极小幅度的结果差异,是底层线性代数库并行计算的浮点误差导致,属于正常现象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 12:27:28