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

数据集规模引发训练集与测试集得分差异的模型问题求助

问题描述

我尝试使用SOAP描述符将机器学习应用于原子结构研究,目前遇到的问题是:使用不同规模的数据集时,模型的训练集与测试集得分差异极大。当前运行结果显示训练集得分远低于测试集,怀疑模型存在问题,恳请提供解决方案。使用的数据集来自论文《Dataset MoS2(single)》。

代码实现

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import  ase
from dscribe.descriptors import SOAP
from dscribe.descriptors import CoulombMatrix

from sklearn.model_selection import train_test_split
import sklearn
from sklearn.linear_model import LinearRegression
from sklearn.kernel_ridge import KernelRidge
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVR


from ase.io import read
materials = read('structures.xyz', index=':')
materials = materials[:5000]
energies = pd.read_csv('Energy.csv')
energies = np.array(energies['b'])
energies = energies[:5000]

species = ["H", 'Mo', 'S']
rcut = 8.0
nmax = 1
lmax = 1

# 设置SOAP描述符
soap = SOAP(
    species=species,
    periodic=False,
    rcut=rcut,
    nmax=nmax,
    lmax=lmax,
)

coulomb_matrices = soap.create(materials, positions=[[51]]*len(materials)) 

nsamples, nx, ny = coulomb_matrices.shape
d2_train_dataset = coulomb_matrices.reshape((nsamples,nx*ny))

df = pd.DataFrame(d2_train_dataset)
df['target'] = energies

from sklearn.preprocessing import StandardScaler

X = df.iloc[:, 0:12].values
y = df.iloc[:, 12:].values

st_x = StandardScaler()
st_y = StandardScaler()

X = st_x.fit_transform(X)
y = st_y.fit_transform(y)

X_train, X_test, y_train, y_test = train_test_split(X, y)

#krr = GridSearchCV(
#    KernelRidge(kernel="rbf", gamma=0.1),
#    param_grid={"alpha": [1e0, 0.1, 1e-2, 1e-3], "gamma": np.logspace(-2, 2, 5)},
#)

svr = GridSearchCV(
    SVR(kernel="rbf", gamma=0.1),
    param_grid={"C": [1e0, 1e1, 1e2, 1e3], "gamma": np.logspace(-2, 2, 5)},
)

svr = svr.fit(X_train, y_train.ravel())

print("训练集得分: {:.4f}".format(svr.score(X_train, y_train)))
print("测试集得分: {:.4f}".format(svr.score(X_test, y_test)))

运行得分

训练集得分: 0.0414
测试集得分: 0.9126
解决方案

针对训练集得分远低于测试集的反常情况,从数据、描述子、模型三个维度给出排查和解决方向:

  • 修正SOAP描述子的设计
    当前代码仅提取每个结构中第51个原子的局部SOAP描述子,但目标是整个体系的能量,局部特征无法有效关联体系级属性,这是核心问题。建议改为计算全局SOAP描述子:对每个结构的所有原子SOAP取平均值/求和,或使用dscribe的average="inner"参数直接生成体系级平均描述子,确保特征与目标的物理意义匹配。
    同时,当前nmax=1、lmax=1的参数过于简单,无法捕捉原子间复杂相互作用,建议逐步提升nmax(如3-5)和lmax(如3-4),增强描述子的表达能力。

  • 验证数据划分与一致性
    单次train_test_split的结果可能存在随机性,改用K折交叉验证(如KFold配合cross_val_score)多次验证模型性能,排除偶然因素。同时确认structures.xyz与Energy.csv的样本顺序完全对应,避免数据错位;检查训练集和测试集的结构分布是否一致,必要时手动打乱数据集后再划分。

  • 调整模型参数与拟合状态
    打印svr.best_params_查看网格搜索的最优参数:如果最优C值偏小(如1e0),说明模型正则化过强导致欠拟合,可扩大C的搜索范围(如1e-1到1e4),同时调整gamma的区间,让模型具备足够复杂度拟合训练数据。另外,回归任务中对y做标准化并非必须,尝试仅标准化X,观察得分变化。

  • 检查数据质量
    绘制能量数据的分布直方图,排查是否存在异常值或分布极度不均的情况;统计每个结构中第51个原子的物种,确认是否存在物种不一致的情况,这会导致SOAP描述子的特征分布混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 22:39:25