信息速览
Matbench — 13 个材料任务,给算法排座次
§1 一句话是什么
Matbench 是一套材料性质预测的基准考卷。它把散落在 10 个原始来源里的无机材料数据,清洗成 13 个「输入—输出」明确的监督任务,再配上一套写死的划分方式,让不同算法能在同一把尺子上量。
它不是一个能拿去训练大模型的语料库——13 个任务加起来 408,062 条样本,去掉重复材料后实际独立材料数远小于这个数。它的定位更接近 ImageNet 之于计算机视觉:定义一个可复核的比较场景,而不是提供规模。
官方原话:「Matbench is an ImageNet for materials science; a set of 13 curated machine learning tasks for benchmarking and performance testing.」[^1]
[^1]: GitHub materialsproject/matbench README 首段。
三件东西构成完整的一个任务:
- 一组输入:晶体结构(9 个任务)或化学式(4 个任务)。
- 一组输出:目标性质,例如形成能、带隙、剪切模量。
- 一个测试程序:怎么打分、怎么划分、怎么算最终分数。
前两件是「数据」,第三件才是 Matbench 真正的贡献。很多材料数据集也能下载,但没有一个共同的划分,「我的 RMSE 比你低」就永远说不清是模型好还是划分巧。
§2 十三个任务的全表
这是全篇最该背下来的一张表。样本数来自 matbench_v0.1_dataset_metadata.json,逐条核过,与官网 Benchmark Info 页一致。
| 任务 | 类型 / 输入 | 目标列(单位) | 样本数 | MAD 或正类比例 |
|---|---|---|---|---|
matbench_steels |
回归 / 化学式 | yield strength(MPa) |
312 | 229.3743 |
matbench_jdft2d |
回归 / 结构 | exfoliation_en(meV/atom) |
636 | 67.2020 |
matbench_phonons |
回归 / 结构 | last phdos peak(cm⁻¹) |
1,265 | 323.7870 |
matbench_expt_gap |
回归 / 化学式 | gap expt(eV) |
4,604 | 1.1432 |
matbench_dielectric |
回归 / 结构 | n(无量纲) |
4,764 | 0.8085 |
matbench_expt_is_metal |
分类 / 化学式 | is_metal |
4,921 | 正类 0.4981 |
matbench_glass |
分类 / 化学式 | gfa |
5,680 | 正类 0.7104 |
matbench_log_gvrh |
回归 / 结构 | log10(G_VRH)(log10 GPa) |
10,987 | 0.2931 |
matbench_log_kvrh |
回归 / 结构 | log10(K_VRH)(log10 GPa) |
10,987 | 0.2897 |
matbench_perovskites |
回归 / 结构 | e_form(eV/unit cell) |
18,928 | 0.5660 |
matbench_mp_gap |
回归 / 结构 | gap pbe(eV) |
106,113 | 1.3271 |
matbench_mp_is_metal |
分类 / 结构 | is_metal |
106,113 | 正类 0.4349 |
matbench_mp_e_form |
回归 / 结构 | e_form(eV/atom) |
132,752 | 1.0059 |
| 合计 | 10 回归 + 3 分类 | — | 408,062 | — |
几个必须自己算出来的事实:
- 量级跨度 425 倍:最小的
steels312 条,最大的mp_e_form132,752 条。这不是巧合,是设计意图——考卷要同时测「小数据下的表征能力」和「大数据下的扩展性」。 - 单任务占 32.5%:
mp_e_form一个任务就占全部样本的三分之一。若按样本加权算「平均分」,结果几乎完全由这一个任务决定。 - 结构 vs 化学式 9:4。但这 4 个化学式任务里,
expt_gap与expt_is_metal同源(都来自 Zhuo 等 2018 的补充材料),glass来自 Landolt-Börnstein,steels来自 Citrination。 - 三个任务事实上共用同一批结构:
mp_gap与mp_is_metal都是 106,113 条,来自 Materials Project 的同一批查询(2019-04-02 抓取);log_gvrh与log_kvrh都是 10,987 条,来自 de Jong 等的弹性数据集同一批结构。所以 13 个任务不等于 13 份独立数据——官方自己说的是「13 个任务来自 10 个数据集」[^2]。
[^2]: 论文正文原句:「The Matbench test suite v0.1 contains 13 supervised ML tasks from 10 datasets.」
§3 数据是怎么清洗的(逐任务)
Matbench 最容易被忽略、也最容易踩坑的一层:每个任务都有自己的清洗规则,规则写在 matminer 的数据集描述里,不在论文表格里。
从 Materials Project 派生的 6 个任务,共性规则是:
- 剔除形成能(或凸包以上能量)超过 150 meV 的条目;
- 剔除含惰性气体元素的条目(固态氖、固态氩这类在物理上极端罕见,会把分布拖偏);
- 抓取时间统一为 2019 年 4 月 2 日。
各任务的专属规则:
| 任务 | 额外清洗 |
|---|---|
mp_e_form |
剔除形成能 > 3.0 eV 的条目(阈值比其他任务宽,因为目标本身就是它) |
log_gvrh / log_kvrh |
剔除 G_Voigt / G_Reuss / G_VRH / K_Voigt / K_Reuss / K_VRH 任一为负的条目;剔除不满足 G_Reuss ≤ G_VRH ≤ G_Voigt 或 K_Reuss ≤ K_VRH ≤ K_Voigt 的条目(这是弹性常数的物理约束,Hill 平均必须落在 Reuss 与 Voigt 之间) |
dielectric |
剔除折射率 < 1 的条目(真空折射率为 1,低于 1 在静态近似下不物理) |
phonons |
只保留 150 meV 阈值,无额外规则;原始计算由 ABINIT 在谐近似下用密度泛函微扰理论(DFPT)完成 |
非 MP 派生的 7 个任务:
| 任务 | 来源与清洗 |
|---|---|
steels |
来自 Citrination(数据集 153092)。按成分去重。312 条实验测得的屈服强度 |
jdft2d |
来自 JARVIS-DFT(Choudhary 等 2017 的 2D 数据集,figshare 的 jdft_2d-7-7-2018.json)。泛函为 OptB88vdW 与 TBmBJ |
perovskites |
来自 Castelli 等 2012,5 原子立方钙钛矿胞。泛函 RPBE GGA-DFT。氧的参考态取水蒸气中氧的化学势,不是 O₂ 分子——这是为「光解水」这个应用场景定的 |
glass |
来自 Landolt-Börnstein 第 III/37A 卷《三元非晶合金的非平衡相图》。按成分去重,且要求所有报道对分类一致(同一成分不能被同时报成 GFA 与非 GFA) |
expt_gap |
来自 Zhuo 等 2018(J. Phys. Chem. Lett.)补充材料。按成分去重,剔除同一成分的报道带隙跨度超过 0.1 eV 的条目;剩下的成分取值规则是「在所有报道中,挑最接近该成分均值的那个实验值」 |
expt_is_metal |
同源。按成分去重,剔除金属性与非金属性报道冲突的成分 |
mp_*(6 个) |
见上表 |
3.1 「剔除 150 meV」到底意味着什么
这是最容易写错的一条。它剔的不是「形成能为正的」,而是凸包以上能量(energy above hull)超过 150 meV/atom 的条目——即远离热力学稳定、大概率在实验上做不出来的结构。
后果是:你在 Matbench 上训练的模型,面对的是一个被预筛过的、偏向稳定相的分布。拿它去预测任意生成结构(比如 Matbench Discovery 里的 25 万条 WBM 结构)时,分布偏移是真实存在的。
3.2 「按成分去重」的具体含义
expt_gap、expt_is_metal、glass、steels 四个任务都是按成分(composition)去重,而不是按条目去重。原因是它们的输入只有化学式——同一成分有两条记录,模型就无法区分。所以去重的逻辑不是「删重复」而是「让每个输入唯一对应一个输出」。
expt_gap 的处理尤其值得注意:不是取均值,而是「取最接近均值的那个实测值」。这是为了保留一个真实测量过的数,而不是人造的平均数。
§4 划分:五折嵌套交叉验证
这是 Matbench 能被当作基准的核心。技术细节:
- 五折嵌套交叉验证(nested cross-validation, NCV),不是简单的 train/test 一次切分。
- 每一折内:80% 训练+验证 / 20% 测试。
- 外层测试折用 scikit-learn
KFold,随机种子18012019,shuffle=True。 - 分类任务改用
StratifiedKFold,同一种子,以保证不平衡类别下的评估更准确。 - 每一折的划分对所有算法完全相同——划分文件随包分发,不再是各人自己 random_split。
- 「嵌套」意味着测试集在超参搜索期间完全不可见:模型在 80% 内部再分训练/验证调参,然后只在 20% 上评一次。
- 五折的好处:每条样本都会在四折里当训练、在一折里当测试,全部样本都被评估过一遍,不是因为运气不好抽到怪测试集而失分。
对 CGCNN / MEGNet 这类需要验证集的图网络,论文额外说明:把每折的训练部分再按 75% 训练 / 25% 验证切,于是整体是 60% 训练 / 20% 验证 / 20% 测试。
4.1 划分文件长什么样
包里的 matbench/matbench_v0.1_validation.json 是全部划分的唯一真源。结构:
{
"metadata": {"n_splits": 5, "random_state": 18012019, "shuffle": true},
"splits": {
"matbench_steels": {
"fold_0": {"train": ["mb-steels-...", ...], "test": [...]},
... "fold_4"
},
...
}
}
这个文件只有约 130 KB,但它决定了所有分数的可比性。 拿 Matbench 报数,就必须用这个文件里的划分;自己重划之后报的 MAE,不能和 leaderboard 上的数字并排。
§5 样本 ID 的构造规则
mbid 不是随机生成的,规则在 matbench/data_ops.py 的 load() 里:
id_n_zeros = math.floor(math.log(df.shape[0], 10)) + 1
mpcontribs_prefix = dataset_name.replace("matbench", "mb").replace("_", "-")
df[MBID_KEY] = [f"{mpcontribs_prefix}-{i + 1:0{id_n_zeros}d}" for i in df.index]
翻译成人话:
- 前缀 = 任务名把
matbench换成mb、下划线换成连字符。matbench_mp_e_form→mb-mp-e-form。 - 补零位数 =
floor(log10(n)) + 1,即样本量的十进制位数。 - 序号从 1 开始,不是 0。
实算出来的结果:
| 任务 | 样本数 | 补零位数 | 首条 ID |
|---|---|---|---|
steels |
312 | 3 | mb-steels-001 |
jdft2d |
636 | 3 | mb-jdft2d-001 |
phonons |
1,265 | 4 | mb-phonons-0001 |
expt_gap |
4,604 | 4 | mb-expt-gap-0001 |
mp_e_form |
132,752 | 6 | mb-mp-e-form-000001 |
坑:同一批材料在 Matbench 与 MPContribs 网页上看到的 ID 可能不同(MPContribs 用 mp-id)。Matbench 的 mbid 是按导入顺序临时编号的,不是材料本身的标识——换个任务,同一材料就是另一个号。
§6 打分方式
回归任务算四个指标:MAE、RMSE、MAPE、max_error。分类任务算四个:accuracy、balanced_accuracy、f1、rocauc,概率转标签的阈值固定 0.5。
折间汇总用四项统计:mean、max、min、std。官方 leaderboard 排序用的是 mean MAE(分类用 mean ROCAUC)。
6.1 「Scaled Error」才是不受单位影响的尺子
leaderboard 上除了原始 MAE,还给一个归一化误差:
- 回归:
Scaled Error = MAE / MAD,MAD 就是 §2 表里那一列。 - 分类:
Scaled Error = (1 − ROCAUC) / 0.5。
为什么需要它:13 个任务的单位互不相同(MPa、eV、cm⁻¹、log10 GPa、无量纲),原始 MAE 之间没有可比性。mae/mad = 1.0 大致等于「和无脑预测中位数的效果一样」,< 0.1 才是真学到了东西。
§7 目前的最好成绩
官方 leaderboard(matbench_v0.1 榜单)当前各任务的最优,按 MAE 或 ROCAUC 排序:
| 任务 | 最优模型 | 分数 |
|---|---|---|
matbench_steels |
MODNet v0.1.12 | 87.7627 MPa |
matbench_jdft2d |
MODNet v0.1.12 | 33.1918 meV/atom |
matbench_phonons |
MegNet(kgcnn v2.1.0) | 28.7606 cm⁻¹ |
matbench_expt_gap |
MODNet v0.1.12 | 0.3327 eV |
matbench_dielectric |
MODNet v0.1.12 | 0.2711 |
matbench_expt_is_metal |
AMMExpress v2020 | 0.9209 ROCAUC |
matbench_glass |
MODNet v0.1.12 | 0.9603 ROCAUC |
matbench_log_gvrh |
coNGN | 0.0670 log10(GPa) |
matbench_log_kvrh |
coNGN | 0.0491 log10(GPa) |
matbench_perovskites |
coGN | 0.0269 eV/unit cell |
matbench_mp_gap |
coGN | 0.1559 eV |
matbench_mp_is_metal |
CGCNN v2019 | 0.9520 ROCAUC |
matbench_mp_e_form |
coGN | 0.0170 eV/atom |
几个观察:
- 没有一个模型通吃。MODNet 拿下 4 个,coGN / coNGN 系拿下 4 个,MEGNet 1 个、CGCNN 1 个、AMMExpress 1 个。这正是基准该有的样子。
mp_e_form的 0.0170 eV/atom 是所有回归任务里 scaled error 最低的(0.0170 / 1.0059 ≈ 1.7%),因为它的数据量最大(13 万条)。对比steels的 87.76 / 229.37 ≈ 38%——小样本任务的误差就是降不下来。- 分类任务的 ROCAUC 都挤在 0.92–0.96 之间,区分度很低,排行榜前列的名次差别在噪声范围内。
7.1 论文当时的基线(2020)
论文本身比较了三种模型,结论是 Automatminer 在 13 个任务中的 8 个上取得最好成绩。
Automatminer(AMMExpress v2020)在四个大任务上的成绩:
| 任务 | MAE(mean) | RMSE(mean) |
|---|---|---|
mp_e_form |
0.1726 | 0.2602 |
mp_gap |
0.2824 | 0.5611 |
steels |
97.4929 | 154.0161 |
expt_gap |
0.4161 | 0.9918 |
另一个关键结论是规模效应:图神经网络(CGCNN、MEGNet)在小数据任务上误差偏高,但随着数据量增长改善很快;描述符类方法(Automatminer、随机森林)在小数据上占优,但斜率平缓,样本数超过 10⁴ 后优势就基本消失,到 10⁵ 附近「AutoML 的优势基本不存在」。
Dummy 基线(无脑预测)的误差比最好模型高 68% 到 299%——这是「任务到底有多难」的下界。
§8 和数据版 Matbench Discovery 的关系(别混)
leaderboard 页面上有两个榜单,很容易看错:
| Matbench(本条) | Matbench Discovery | |
|---|---|---|
| 标识 | matbench_v0.1 |
matbench_discovery 0.1.0 |
| 性质 | 性质预测(prediction) | 发现流水线(discovery) |
| 任务 | 13 个独立任务 | 单一任务:给约 25 万条生成结构排序 |
| 数据 | 10 个来源、40.8 万条 | WBM 数据集,约 25 万条中 42k 稳定 |
| 指标 | MAE / ROCAUC | F1、DAF、Precision、TPR、TNR… |
| 维护者 | Dunn 等(LBNL / Materials Project) | Janosh Riebesell |
Matbench Discovery 榜上前几名:CHGNet F1 0.59、M3GNet 0.58、MEGNet 0.52、CGCNN 0.52、CGCNN+P 0.51、Wrenformer 0.48、BOWSR+MEGNet 0.44、Voronoi RF 0.34、dummy 0.19。
两者共享「Matbench」这个名字,但数据集、任务、指标、维护者都不同。 引用时必须写清是哪一个。
§9 许可与版本
- 包许可:modified BSD(
setup.py里license="modified BSD",PyPI 元数据同为modified BSD)。 - PyPI 版本 0.6,发布于 2022-07-27。历史版本只有 5 个:0.2(2021-05-06)、0.3(2021-07-28)、0.4(2021-10-10)、0.5(2021-10-10,同日连发)、0.6。
- 注意版本号有两层,别混:
matbench的包版本是0.6(constants.py里VERSION = "0.6");- 基准版本是
matbench_v0.1,自 2020 年以来没变过。 - 基准版本不动是刻意的——一动,所有历史分数就作废。
- 单个数据集的许可并未在元数据里逐条声明。它们来自 10 个上游(Materials Project、JARVIS、figshare、Citrination、SpringerMaterials 等),各有各的条款。Matbench 的 BSD 是代码与划分文件的许可,不是全部数据的许可。要商用,必须回上游逐个确认。
§10 用之前必须知道的坑
坑 1:perovskites 的 e_form 单位是 eV/unit cell,不是 eV/atom
这是全库最容易出错的一处。同样是 e_form,mp_e_form 是 eV/atom,perovskites 是 eV/unit cell(5 原子胞)。两者数值差 5 倍,直接合并会把模型带偏。要换算得除以原子数。
坑 2:mp_gap 与 mp_is_metal 是同一批 106,113 条
两个任务的名字不同、目标不同,但结构完全一样。若把 13 个任务当成 13 份独立数据来做多任务学习,这两份会被重复计算;若做「跨任务迁移」,这里存在严重的信息泄漏——mp_gap 的训练结构可能正是 mp_is_metal 的测试结构。
同理 log_gvrh 与 log_kvrh 都是 10,987 条同批结构。
坑 3:is_metal 不是实验测的,是 pymatgen 判的
mp_is_metal 的 is_metal 定义是「pymatgen 判定是否金属」,而 pymatgen 的判定依据是 PBE 计算出的能带是否跨费米面。所以它本质上是 DFT 标签,不是实验标签。名字里的 mp_ 就是提示。
对比 expt_is_metal:那个才是实验的,来自 Zhuo 等 2018 的文献汇总,且输入只有化学式。
坑 4:划分不能自己重划
random_state=18012019 是硬编码在官方划分文件里的。自己用 train_test_split(random_state=42) 跑出来的数,和 leaderboard 上的数没有任何可比性。要报数就 MatbenchBenchmark() 拿官方折。
坑 5:steels 只有 312 条,五折每折测试集只有约 62 条
小任务上的分数抖动极大。论文自己给的每折 MAE 是 109.31 / 80.42 / 83.54 / 98.72 / 115.49——最差折和最好折差 43%。只看 mean 会掩盖这个方差。
坑 6:glass 的正类比例是 0.71
matbench_glass 里 71% 的样本是「能形成玻璃」。全部预测为 1 就有 0.71 的 accuracy。所以这个任务必须看 balanced_accuracy 或 ROCAUC,不能看 accuracy。
同理 expt_is_metal 正类 0.498、mp_is_metal 正类 0.435,都还算均衡;glass 是唯一明显偏斜的。
坑 7:phonons 的目标是「最高光学声子峰」,不是完整声子谱
last phdos peak 的定义是声子态密度里频率最高的那个光学支峰,单位 cm⁻¹,可以作为「主导纵向光学声子频率」的估计。它只是一个标量,不是声子谱本身。 想要完整色散关系要去 Petretto 等的原始数据。
坑 8:jdft2d 只有 636 条,且泛函不是 PBE
exfoliation_en 由 OptB88vdW 与 TBmBJ 两个泛函算的,不是 PBE。拿它和 PBE 派生的数据混用,等于把两种泛函的误差叠在一起。
坑 9:expt_gap 的取值规则会「人造」一致性
「取最接近均值的实测值」意味着:如果某成分有 5 篇文献报了 1.0、1.1、1.2、1.3、3.5 eV,均值 1.62,最接近的是 1.3——那条异常高的 3.5 就被丢掉了。这是刻意的清洗,但也意味着数据里没有离群点。 若你的研究目的就是「模型能否识别异常实验」,这个数据集不能用。
坑 10:数据下载端点在 Cloudflare 后面,脚本直连会 403
https://ml.materialsproject.org/projects/matbench_<task>.json.gz 用 curl 直接请求会返回 HTTP 403(Cloudflare bot 拦截)。正常路径是 pip install matbench matminer,走 matminer 的 load_dataset(),它会带上正确的请求头。硬要裸下载就得自己处理 CF 挑战。
坑 11:matbench_v0.1_validation.json 写在包里,不在数据里
划分文件随 PyPI 包分发(matbench/matbench_v0.1_validation.json,约 130 KB)。如果你只下了数据文件、没装包,就没有划分——这时候谈「Matbench 分数」是无意义的。
坑 12:13 个任务不等于 13 份数据,是 10 份
官方原话「13 supervised ML tasks from 10 datasets」。去重关系:mp_gap / mp_is_metal 共用一份 MP 结构集;log_gvrh / log_kvrh 共用一份弹性数据集;expt_gap / expt_is_metal 共用 Zhuo 等 2018 的补充材料。所以 13 − 3 = 10。
§11 逐任务详解:每道题在考什么
前面 §2 给了全表,§10 给了坑。这一节把 13 个任务逐个拆开——它想测的能力、目标是怎么来的、以及为什么这个任务的分数天花板在哪里。如果你只想用其中几个任务,这一节是选型依据。
§11.1 matbench_steels — 312 条钢材屈服强度
考什么:在极小样本 + 纯化学式输入下,能不能学到「成分 → 力学性能」这条链条。
这是全库最小的任务,也是唯一一个目标是实验测得、且属于工程材料(钢)的任务。312 条来自 Citrination 的数据集 153092,按成分去重。
为什么它难:
- 312 条里要分五折,每折测试集约 62 条。62 条样本的 MAE 标准差极大,论文给的五折分别是 109.31 / 80.42 / 83.54 / 98.72 / 115.49 MPa——极差 43%。
- 输入只有化学式,没有晶格、没有热处理工艺、没有轧制方向。而钢的屈服强度高度依赖显微组织与工艺历史,这些在化学式里根本不存在。
- 所以这个任务的 MAE 天然有下界:同样成分的不同钢种,屈服强度可以差一倍以上。
这意味着:steels 上的 MAE 大致反映「成分能解释多少性能方差」,而不是「模型有多聪明」。目前最优 87.76 MPa,MAD 是 229.37,scaled error ≈ 0.383——也就是说,最好的模型也只把误差压到了「无脑预测」的四成。这个数字看着不好看,但它是这个任务的物理上限,不是模型的失败。
§11.2 matbench_jdft2d — 636 条二维材料剥落能
考什么:从三维晶体结构判断「能不能剥离成单层」。
exfoliation_en(剥落能)是把这个材料从体相剥离成单层所需的能量,单位 meV/atom。数值越低越容易剥离。636 条来自 JARVIS-DFT 的 2D 数据集(Choudhary 等 2017),泛函是 OptB88vdW 与 TBmBJ——这两个名字在材料计算里意味着「专门为二维体系调过的 van der Waals 泛函」。
为什么泛函要特别说明:标准 PBE 无法正确处理层间范德华相互作用,会把层间结合算得偏弱或偏强。OptB88vdW 是加了 vdW 修正的版本。所以 jdft2d 的剥落能不能和 PBE 派生的数据混用——这是 §10 坑 8 的展开。
目前最优 33.19 meV/atom,MAD 67.20,scaled error ≈ 0.494。刻度最差的一个回归任务(和 steels 差不多),原因同样是小样本 + 目标本身噪声大。
§11.3 matbench_phonons — 1,265 条最高光学声子峰
考什么:从结构预测晶格振动的高频端。
目标是 last phdos peak——声子态密度里频率最高的光学支峰,单位 cm⁻¹。数据来自 Petretto 等 2018,用 ABINIT 在谐近似下做 DFPT。
这个任务有个特殊性:声子计算是全库最贵的一类 DFT。一次完整声子谱要算几十个位移构型,成本是单点能计算的几十倍。所以原始库只有 1,265 条——不是没人想做,是算不起。
这也解释了为什么这个任务的最优模型是 MEGNet(kgcnn v2.1.0) 而不是榜上其他的 MODNet / coGN 系:图网络在结构信息上的归纳偏置,对「振动频率」这种强依赖局部配位环境的量更合适。当前 28.76 cm⁻¹,MAD 323.79,scaled error ≈ 0.089——相当好。
§11.4 matbench_expt_gap — 4,604 条实验带隙
考什么:只用化学式预测实验测得的带隙。
这是最有现实意义的任务之一:实验带隙是做材料筛选时的第一道门槛,但实验测量贵、慢、覆盖窄。如果能从化学式直接给出估计,筛选成本能降一个数量级。
数据来自 Zhuo 等 2018 的补充材料。清洗规则见 §3.2——**「取最接近均值的实测值」**这条规则是双刃剑:
- 好处:每个成分只有一个干净的数,模型不用处理冲突标签;
- 代价:离群值被系统性地删掉了。如果你的研究目的包含「模型能否识别异常实验」,这个数据集不适用。
目前最优 0.3327 eV(MODNet v0.1.12),MAD 1.1432,scaled error ≈ 0.291。
值得注意:实验带隙与 PBE 计算带隙之间有系统性偏差(PBE 普遍低估 30–50%)。所以 expt_gap 和 mp_gap 虽然都叫「带隙」,不是同一个量,不能互相验证。
§11.5 matbench_dielectric — 4,764 条折射率
考什么:从结构预测光学响应。
目标 n 是折射率,无量纲。来自 Petousis 等 2017 的高通量介电/光学筛选。清洗时剔除 n < 1 的条目(真空折射率为 1,低于 1 在静态近似下不物理)。
这个任务的单位是「无量纲」,所以 MAD 0.8085 直接可读:「无脑预测中位数」的平均误差是 0.81,最好的模型是 0.2711,scaled error ≈ 0.335。
一个实用细节:折射率与带隙之间有经验关系(Penn 模型),所以 dielectric 与 mp_gap 在物理上是相关的。如果你做多任务学习,这两个任务之间可能有正迁移——但要注意 §10 坑 2 的结构重叠问题:dielectric 的 4,764 条是 MP 的子集,可能与 mp_gap 的 106,113 条有交集。
§11.6 matbench_expt_is_metal — 4,921 条实验金属性分类
考什么:只用化学式判断「是金属还是非金属」。
同源 Zhuo 等 2018。清洗时剔除「金属性与非金属性报道冲突」的成分——这是分类任务必须做的,否则标签本身有噪声。
为什么这个任务的正类比例 0.4981 几乎是完美的 50/50:不是刻意平衡的,恰好如此。这对分类是有利的——accuracy 和 balanced_accuracy 几乎一致,不像 glass 那样必须看后者。
目前最优 AMMExpress v2020,ROCAUC 0.9209。这是 13 个任务里唯一一个 Automatminer 系还守着榜首的——因为输入只有化学式,图网络的结构优势用不上,描述符 + AutoML 反而最合适。
§11.7 matbench_glass — 5,680 条金属玻璃形成能力
考什么:从化学式判断三元合金能不能形成块体金属玻璃。
来自 Landolt-Börnstein 第 III/37A 卷《三元非晶合金的非平衡相图》。这本手册是实验相图的老牌汇编,数据质量高但年代久(1997 年版)。
这是全库唯一一个明显类别不平衡的任务:正类比例 0.7104。全部预测为 1 就有 0.71 的 accuracy。所以:
- 看 accuracy → 会得到一个虚高的数;
- 必须看 balanced_accuracy 或 ROCAUC。
目前最优 0.9603 ROCAUC(MODNet v0.1.12)。这个数看着很高,但注意——ROCAUC 在类别偏斜时会偏乐观,因为负类样本少,假阳性率的估计方差大。
§11.8 matbench_log_gvrh — 10,987 条剪切模量
考什么:从结构预测弹性。
目标 log10(G_VRH),是 Voigt-Reuss-Hill 平均剪切模量取以 10 为底的对数,单位 log10(GPa)。取对数是刻意的——弹性模量跨好几个数量级(软材料几 GPa,硬材料几百 GPa),取对数后才近似正态。
数据来自 de Jong 等 2015 的弹性数据集。清洗时施加了物理约束:
- 剔除 G/K 的 Voigt / Reuss / VRH 任一为负的;
- 剔除不满足 G_Reuss ≤ G_VRH ≤ G_Voigt 的。
后一条是 Hill 平均的定义要求:Hill 平均是 Reuss(等应力)下界与 Voigt(等应变)上界的算术平均,必须落在两者之间。不满足的条目说明原始计算有问题。
目前最优 coNGN 0.0670,MAD 0.2931,scaled error ≈ 0.229。
§11.9 matbench_log_kvrh — 10,987 条体积模量
和 log_gvrh 同批 10,987 条结构,只是目标换成体积模量 log10(K_VRH)。
这是 §10 坑 2 的第二处:两个任务共享同一批结构,做多任务学习时不能当成两份独立数据。但反过来说,这两个任务的目标高度相关(剪切模量与体积模量都来自同一套弹性张量),做多任务学习有明确的正迁移理由。
目前最优 coNGN 0.0491,MAD 0.2897,scaled error ≈ 0.169——比 log_gvrh 好一截。原因可能是体积模量对结构变化的敏感性更平滑(剪切模量对晶体对称性和缺陷更敏感)。
§11.10 matbench_perovskites — 18,928 条钙钛矿形成能
考什么:从 5 原子立方钙钛矿结构预测形成能。
数据来自 Castelli 等 2012,为「光解水」这个应用场景构建。泛函 RPBE GGA-DFT。
这个任务有两个必须记住的特殊性:
- 单位是 eV/unit cell,不是 eV/atom。5 原子胞,所以数值大约是 eV/atom 值的 5 倍。要和其他形成能任务合并,必须先除以原子数。
- 氧的参考态是水蒸气中氧的化学势,不是 O₂ 分子。这是为光解水场景定的——在这个场景下氧来自水,不是来自氧气。所以这个
e_form的零点和mp_e_form的零点不一样,两者不可比。
目前最优 coGN 0.0269 eV/unit cell,MAD 0.5660,scaled error ≈ 0.048——13 个任务里第二好。原因:5 原子胞的结构空间极规整(立方钙钛矿只有一种骨架),模型要学的是「A 位、B 位换什么元素」,问题被结构化地简化了。
§11.11 matbench_mp_gap — 106,113 条 PBE 带隙
考什么:从结构预测 DFT PBE 带隙。
来自 Materials Project,2019-04-02 抓取。清洗见 §3。
这是 13 个任务里数据量第二大的,也是「图网络开始发力」的临界点。论文的 Fig. 4 显示:到 10⁵ 样本量级,描述符方法与图网络的优势关系开始反转。
目前最优 coGN 0.1559 eV,MAD 1.3271,scaled error ≈ 0.117。
一个必须提的物理事实:PBE 带隙系统性低估实验带隙 30–50%(这是 PBE 的已知缺陷,源于自相互作用误差)。所以 mp_gap 上的低 MAE 不代表能预测实验带隙——它只代表能复现 PBE 的输出。要预测实验值,得用 expt_gap 或在 PBE 值上做经验修正(如 scissor 操作)。
§11.12 matbench_mp_is_metal — 106,113 条 PBE 金属性
和 mp_gap 同批 106,113 条结构,目标换成「是否金属」。
is_metal 的定义:pymatgen 判定。而 pymatgen 的依据是PBE 计算出的能带是否跨越费米面。所以这是 DFT 标签,不是实验标签。
一个逻辑关系值得注意:is_metal 与 gap pbe 在定义上是耦合的——带隙为 0(或小于阈值)就是金属。所以这两个任务实际上是同一个物理量的两种编码。这意味着它们的分数不能当作两个独立的证据。
目前最优 CGCNN v2019,ROCAUC 0.9520。
§11.13 matbench_mp_e_form — 132,752 条形成能
考什么:从结构预测 DFT 形成能(eV/atom)。
这是全库最大的任务,也是最重要的一道题。 形成能是判断「这个材料能不能稳定存在」的第一判据,几乎所有材料发现流水线的第一步都是它。
来自 Materials Project,清洗阈值放宽到 e_form > 3.0 eV(其他 MP 任务用 150 meV 凸包阈值)。
目前最优 coGN 0.0170 eV/atom,MAD 1.0059,scaled error ≈ 0.017——13 个任务里最好的一个,误差只有「无脑基线」的 1.7%。
为什么能做到这么好:
- 数据量 13 万条,是第二名的 1.25 倍、最小任务的 425 倍;
- 目标本身平滑(形成能是成分与结构的连续函数,不像分类那样有硬边界);
- 物理上有强先验(元素电负性、原子半径直接决定形成能的主要部分),模型容易学。
但注意:0.017 eV/atom 已经接近 DFT 计算本身的数值噪声水平。再往下压意义不大——继续优化这个数,更可能是在拟合 MP 计算设置的特有偏倚,而不是学到更真的物理。
§12 怎么在十个任务之间做取舍
如果你不想跑全部 13 个任务(时间成本不低:论文里 AutoML 单任务训练上限 24 小时),这一节给选型建议。
§12.1 按研究目的选
| 你的目的 | 该用哪些任务 | 理由 |
|---|---|---|
| 验证「图神经网络是否优于描述符」 | 全部 13 个,但必须按样本量分组看 | 这正是论文 Fig. 4 做的事:小数据描述符赢,大数据图网络赢。只看总数会得出错误结论 |
| 测「小样本学习能力」 | steels(312)、jdft2d(636)、phonons(1,265) |
三个都在 1,300 条以下,是真正的低资源场景 |
| 测「纯化学式输入能做到什么」 | expt_gap、expt_is_metal、glass、steels |
四个 composition 任务,不给结构。如果你的生产环境拿不到晶体结构,这四个才有现实意义 |
| 测「大规模扩展性」 | mp_e_form(132,752)、mp_gap(106,113)、mp_is_metal(106,113) |
三个都在 10 万条以上。要测训练时间、显存、分布式,只能靠它们 |
| 测「实验数据 vs 计算数据」的差距 | expt_gap vs mp_gap;expt_is_metal vs mp_is_metal |
两对任务分别对应同一个物理量的实验版与计算版。分数差距就是「DFT 偏倚」的量化 |
| 测「多任务 / 迁移学习」 | log_gvrh + log_kvrh;mp_gap + mp_is_metal |
两对共享结构,是天然的迁移学习场景(但要注意信息泄漏,见 §10 坑 2) |
| 只要一个能代表整体水平的数 | 不要这么做 | 13 个任务的样本量差 425 倍,任何「平均分」都会被 mp_e_form 主导 |
§12.2 按成本选
按「加载耗时 + 训练耗时」大致排序(从轻到重):
steels、jdft2d、phonons— 千条以内,几秒加载完毕expt_gap、dielectric、expt_is_metal、glass— 数千条,加载快log_gvrh、log_kvrh、perovskites— 万条级,结构对象反序列化开始变慢mp_gap、mp_is_metal、mp_e_form— 十万条级,仅加载就要几分钟到十几分钟,内存占用以 GB 计
注意:mp_gap 和 mp_is_metal 是同一批结构,加载两次等于把 106,113 个 pymatgen Structure 对象反序列化两次。如果两个任务都要跑,先加载一次然后复用,能省一半时间和内存。
§12.3 按「报告可读性」选
如果你要写论文或报告,13 个任务全报会让读者失焦。更实用的做法:
- 选 3 个代表性任务:一个大数据回归(
mp_e_form)、一个小数据回归(steels)、一个分类(expt_is_metal); - 每个都报 mean MAE + 五折标准差,不只报均值;
- 附上 scaled error,让不同单位的任务可横向比较;
- 说明你的模型属于哪一类(描述符 / 图网络 / AutoML),因为这直接决定它在哪个任务上该赢。
§13 DAIMS 24 项逐项评分
按本站统一口径,对 Matbench 的数据就绪度逐项打分。
| # | 维度 | 分 | 说明 |
|---|---|---|---|
| 1 | 数据集标识 | 1.0 | 名称、5 位作者、DOI(10.1038/s41524-020-00406-3)、官网、GitHub 全部明确 |
| 2 | 版本标识 | 1.0 | 双版本号:包版本 0.6(2022-07-27)+ 基准版本 matbench_v0.1(冻结)。基准冻结这件事本身就是版本治理的正面案例 |
| 3 | 许可明确性 | 0.5 | 包许可 modified BSD 明确;但数据本身的许可未逐条声明,需回 10 个上游分别确认 |
| 4 | 出处可溯 | 1.0 | 10 个原始来源逐一点名,附文献 DOI;matminer 元数据里每个任务都有 reference 字段 |
| 5 | 采集方法描述 | 1.0 | 每个任务的清洗规则写在 matminer description 里,逐条可读:阈值、剔除条件、抓取日期都有 |
| 6 | 处理链可复现 | 1.0 | 全部代码开源(GitHub),清洗由 matminer.datasets 的构建脚本完成;数据文件有 SHA-256 |
| 7 | 数据模型 | 1.0 | 极简:(mbid) → (input, target)。输入是 Structure 或 Composition,目标是标量或 0/1 |
| 8 | 字段字典 | 0.5 | 无集中字段字典;列说明散在 columns 字段里(每个任务两条),但 13 个任务的单位、量纲要自己汇总 |
| 9 | 单位与量纲 | 0.5 | 大部分任务单位明确;但 perovskites 的 eV/unit cell 极易被误读成 eV/atom,官方未在显眼处警告 |
| 10 | 缺失值语义 | 0.5 | 官方声明「pre-cleaned」,即不含缺失值。这是优点也是缺点——用户看不到「哪些被剔了」,只能从 description 反推 |
| 11 | 数据量级 | 0.5 | 逐任务样本数精确可查(312–132,752);但无总体积、无磁盘占用官方数字 |
| 12 | 覆盖范围声明 | 0.5 | 任务性质覆盖广(电子、热力学、力学、光学、声学);但材料空间覆盖窄——大量含稀土、含放射性的条目被上游剔除 |
| 13 | 抽样方法 | 0.5 | 不是抽样,是从上游库按规则筛选;筛选规则公开(150 meV 阈值等),但不是随机抽样 |
| 14 | 偏倚讨论 | 0.5 | 论文讨论了模型规模效应的偏倚;但未系统讨论数据本身的偏倚(稳定相偏差、元素分布偏差) |
| 15 | 质量控制 | 1.0 | SHA-256 逐文件;物理约束过滤(弹性张量、折射率下界);去重规则明确;这是很强的质控 |
| 16 | 已知问题清单 | 0.5 | 论文正文讨论了局限;但没有一份集中的「已知问题」文档(对比 QMOF 有 updates.md) |
| 17 | 更新政策 | 1.0 | 基准版本冻结是明确的政策:matbench_v0.1 不动,新任务进 v0.2。旧分数永远有效 |
| 18 | 访问方式 | 1.0 | pip install matbench 一行;matminer.load_dataset() 一行;划分文件随包 |
| 19 | 访问门槛 | 1.0 | 完全开放,无需注册、无需申请、无 DUA |
| 20 | 格式规范 | 1.0 | JSON(pymatgen MSON 序列化),json.gz 压缩;标准且通用 |
| 21 | 可机读性 | 1.0 | 一个 DataFrame,两列。没有比这更好读的格式了 |
| 22 | 文档完整性 | 1.0 | 官网有 Install / How To Use / Benchmark Info / Full Benchmark Data / Reference 五套页面;GitHub README 简洁 |
| 23 | 引用规范 | 1.0 | 明确给出 BibTeX;且区分了「用 v0.1 基准」与「用 Automatminer」两种引用场景 |
| 24 | 社区与支持 | 1.0 | GitHub Issues;Matsci 论坛专版(discuss.matsci.org);leaderboard 接受 PR 提交 |
总分:18.5 / 24 = 77.1%
评分结构很有特点:
- 满分集中在「可复现」与「文档」(1、2、4、5、6、7、15、17、18、19、20、21、22、23、24)——这正是基准类数据集该强的地方。它不提供大规模数据,但提供可复核的协议,这一点做到了极致。
- 扣分集中在「数据本身的描述」(3、8、9、10、11、12、13、14、16)——它没有集中字段字典、没讨论数据偏倚、没有已知问题文档、没给总体积。因为它的定位是「考卷」,考卷不需要向考生解释自己是怎么出题的。
对比站内其他条目:QMOF 20.5/24(85.4%),HMD 18.0/24(75.0%),SHARE 19.5/24(81.3%)。Matbench 的 18.5 落在中间偏上——它的强项(复现性)和弱项(数据描述)都非常典型。
§14 口径交叉核对
本站对每条入库数据都做「多源对账」。Matbench 的核对结果:
| 核对项 | 来源 A | 来源 B | 结果 |
|---|---|---|---|
| 任务数 | 官网「13 tasks」 | matbench_v0.1_dataset_metadata.json 键数 = 13 |
一致 ✓ |
| 样本总数 | 逐任务相加 = 408,062 | 论文仅给范围「312 to 132,752」 | 本条目自算,论文未给总数 |
mp_e_form 样本数 |
元数据 132,752 | 官网 Benchmark Info 页 132,752 | 一致 ✓ |
mp_gap / mp_is_metal |
元数据均 106,113 | 官网均 106,113 | 一致 ✓ |
steels 样本数 |
元数据 312 | 官网 312 | 一致 ✓ |
| MAD 值 | 元数据 JSON | 官网 Benchmark Info 页 | 13 个全部一致 ✓ |
| 正类比例 | 元数据 frac_true |
官网「Fraction True」 | 一致 ✓ |
| 原始数据集数 | 论文「10 datasets」 | 13 任务 − 3 组共享(mp_gap/mp_is_metal、log_gvrh/log_kvrh、expt_gap/expt_is_metal)= 10 | 一致 ✓ |
| 划分方式 | 论文「five-fold NCV, random seed 18012019」 | validation.json 的 metadata 字段 |
一致 ✓ |
| 包版本 | PyPI 最新 0.6(2022-07-27) | constants.py 的 VERSION = "0.6" |
一致 ✓ |
| 许可 | setup.py license="modified BSD" |
PyPI 元数据 modified BSD |
一致 ✓ |
| Automatminer 最优任务数 | 论文「8 of 13」 | leaderboard 当前仅 expt_is_metal 一项由 AMMExpress 守榜 |
不冲突——论文说的是 2020 年当时,榜单是滚动更新的 |
一处需要注意的差异:论文说 Autopatminer「13 个任务中 8 个最优」,而当前 leaderboard 上 AMMExpress 只剩 1 项在首位。这是正常的——2020 到 2026 年,图网络方法(MODNet、coGN、coNGN)大量涌现,榜单被刷新了。引用「8/13」时必须说明是 2020 年的结论。
另一处:论文提到「10 个回归任务」,但 §2 的元数据里 13 个任务拆出来是 10 回归 + 3 分类——一致 ✓。
§15 与 QMOF 的对照:两种完全不同的「材料数据」
站内刚收录的 QMOF(rid 1357)与本条同为材料领域,但定位是互补而非重叠。这张表能帮你判断该用哪个:
| 维度 | Matbench | QMOF |
|---|---|---|
| 本质 | 考卷(基准 + 划分 + 排行榜) | 库(结构与属性) |
| 材料范围 | 无机晶体、2D、合金、玻璃 | 金属有机框架(MOF)+ 配位聚合物 |
| 结构数 | 408,062 条样本(去重后独立材料更少) | 20,372 个结构 |
| 单结构规模 | 常规晶胞(几到几十原子) | 17–500 原子,均值 114 |
| 目标数 | 每任务 1 列 | 数十列(带隙、电荷、键级、自旋、孔径…) |
| 泛函 | PBE / RPBE / OptB88vdW / TBmBJ(按任务) | PBE-D3(BJ) + HLE17 + HSE06* + HSE06(四档对照) |
| 划分 | 官方五折,冻结 | 无官方划分 |
| 许可 | modified BSD(代码);数据需回上游 | CC BY 4.0(数据);代码 MIT |
| 主要用途 | 比较模型 | 训练/评估模型 |
怎么配合用:
- 用 Matbench 选模型——五个任务跑一遍,看哪类架构适合你的问题;
- 用 QMOF 做实际训练——它的字段更丰富、泛函层级更完整;
- 注意
matbench_mp_gap与 QMOF 的 PBE 带隙不能直接合并:前者是纯 PBE,后者是 PBE-D3(BJ)(加了 D3 色散修正),虽然都是「PBE 级」,但 D3 修正会轻微影响几何,进而影响带隙; - 注意元素覆盖差异:QMOF 覆盖 H 至 Pu(79 种),Matbench 的 MP 派生任务受上游清洗影响,稀土与锕系覆盖不全。
一句话区分:如果你在问「我的模型好不好」,用 Matbench;如果你在问「MOF 的带隙是多少」,用 QMOF。
§16 十分钟上手:从零到第一个分数
这一节是实操,全部命令都验证过语法。
§16.1 安装
pip install matbench matminer
两个包都要。matbench 只提供基准框架与划分,数据加载在 matminer 里——这是最容易困惑的一点:MatbenchTask.load() 内部调的是 matminer.datasets.load_dataset()。
Python 版本要求 3.8+。依赖链:matminer>=0.7.4、scipy>=1.9.0、monty>=2022.4.26、scikit-learn>=1.0.1。
§16.2 看清单个任务的元信息(不加载数据)
from matbench.metadata import mbv01_metadata
for name in mbv01_metadata:
md = mbv01_metadata[name]
print(f"{name:28s} n={md['n_samples']:>7d} type={md['task_type']:14s} "
f"input={md['input_type']:12s} unit={md['unit']}")
这段不会下载任何数据,只读包里自带的 matbench_v0.1_dataset_metadata.json。想快速确认某个任务的样本数与单位,用这个就够。
§16.3 跑一个完整任务
import numpy as np
from matbench.bench import MatbenchBenchmark
from sklearn.ensemble import RandomForestRegressor
mb = MatbenchBenchmark(autoload=False, subset=["matbench_steels"])
for task in mb.tasks:
task.load() # 从 matminer 拉数据
for fold in task.folds: # 0..4
train_inputs, train_outputs = task.get_train_and_val_data(fold)
test_inputs, test_outputs = task.get_test_data(fold, include_target=True)
# 这里必须自己做特征化:train_inputs 是化学式字符串或 Structure 对象
model = RandomForestRegressor(n_estimators=100, random_state=0)
# model.fit(X_train, train_outputs)
# preds = model.predict(X_test)
task.record(fold, preds) # 交给 matbench 打分
print(task.scores) # 5 折 × 4 指标的完整结果
三个关键点:
task.record(fold, preds)的顺序必须与测试集行序一致。task.get_test_data()返回的顺序就是官方划分文件里的顺序,不要自己 shuffle。task.scores是嵌套结构:外层按指标(mae / rmse / mape / max_error),内层按 fold 与统计量(mean / max / min / std)。mb.tasks遍历的是你subset里指定的任务,不是全部 13 个。不传subset就是全跑。
§16.4 把结果存成可复核的文件
mb.to_file("my_results.json.gz")
这个文件里包含:benchmark 名称、包版本、13(或子集)个任务的全部预测、每折参数、所有分数。别人拿这个文件就能复算你的分数——这是 Matbench 设计里最实用的一环。
§16.5 提交到 leaderboard
流程是 fork → 把结果文件放进 benchmarks/ 目录 → 开 PR。官方仓库的结构约定是 benchmarks/matbench_v0.1_<算法名>/。合并后官网会自动列出。
注意:提交时必须给出算法类别的说明(描述符类 / 图网络类 / AutoML 类 / 混合),因为榜单的解读依赖这个分类。
§17 常见误用与正确做法
这一节是 §10 的「反向清单」——不是「有哪些坑」,而是「别人都错在哪里」。
§17.1 误用一:把 13 个任务的 MAE 直接平均
错法:mean([0.17, 0.28, 97.49, 0.42, ...])。
为什么错:单位不同(eV、MPa、cm⁻¹、log10 GPa、无量纲),数值区间差 3 个数量级。平均出来的数没有任何物理意义,而且会被 steels(97.49)这一个数完全主导。
正确做法:平均 scaled error(MAE/MAD)。这样每个任务的贡献被归一化到「相对无脑基线的比例」:
scaled_i = MAE_i / MAD_i
综合分 = mean(scaled_0, ..., scaled_12)
但即使这样,也要说明「是按任务等权还是按样本加权」——两者结论可能完全不同。
§17.2 误用二:只报 best fold
错法:只报五折里最好的那一折,或者只报 mean 而不报 std。
为什么错:steels 的五折 MAE 是 109.31 / 80.42 / 83.54 / 98.72 / 115.49,最好的折比最差的折低 30%。只报 best fold 等于隐去了模型的稳定性问题。
正确做法:报 mean ± std,并列出五折原始值。样本数越小的任务,这个标准差越重要。
§17.3 误用三:用自己的划分然后声称「在 Matbench 上」
错法:train_test_split(X, y, test_size=0.2, random_state=42),然后写「在 Matbench 上 MAE = 0.15」。
为什么错:Matbench 的核心资产就是那个冻结的划分。自己切之后,你的数与其他人的数不可比——这时候你用的只是 Matbench 的「数据」,不是 Matbench 的「基准」。
正确做法:要么用官方划分(推荐),要么明确写「使用 Matbench 数据,自建划分,不可与 leaderboard 对比」。
§17.4 误用四:把 mp_gap 与 mp_is_metal 当独立任务
错法:跑完 13 个任务后统计「我的模型在 13 个任务里赢了 9 个」。
为什么错:mp_gap 与 mp_is_metal 是同一批 106,113 条结构;log_gvrh 与 log_kvrh 是同一批 10,987 条。13 个任务里只有 10 份独立数据。赢了 9 个「任务」不等于赢了 9 份「数据」。
正确做法:按 §7 的做法——按数据份数统计胜场,或者说清「按任务计数」。
§17.5 误用五:用 test 集调超参
错法:跑五折,看哪一折分数低就调参,直到五折都好。
为什么错:嵌套交叉验证的意义就是测试集在调参期间不可见。反复看测试分数调参,等于把测试集变成了验证集,最终分数会系统性偏乐观。
正确做法:只用 get_train_and_val_data() 返回的那 80% 做内部调参(再切出验证集),get_test_data() 只在最后一次调用。
§17.6 误用六:忽略 composition 任务的表征差异
错法:把 matbench_steels(化学式输入)和 matbench_mp_e_form(结构输入)用同一个模型跑。
为什么错:化学式任务没有晶格信息。图网络吃的是 Structure 对象,喂化学式进去根本跑不起来;反过来,描述符方法喂结构时通常只用成分部分,等于浪费了全部结构信息。
正确做法:先看 mbv01_metadata[name]['input_type'],structure 走结构模型,composition 走成分模型。这两类的分数不可横向比较——它们的信息量本来就不同。
§17.7 误用七:把 expt_* 与 mp_* 当成「同一个量」
错法:用 matbench_mp_gap 训练的模型去预测 matbench_expt_gap,然后说「迁移失败」。
为什么错:PBE 带隙系统性低估实验带隙 30–50%。两个任务的标签之间存在系统性偏移,不是噪声。迁移失败是物理上预期的,不是模型问题。
正确做法:要迁移,先在 PBE 值上做经验修正(scissor 操作,或拟合一个缩放关系),再迁移。或者干脆做多任务学习,让模型自己学这个偏移。
§17.8 误用八:把 leaderboard 的排名当「模型优劣」的定论
错法:「coGN 赢了 3 个任务,所以 coGN 最好」。
为什么错:
- 榜单是滚动更新的,今天的第一明天可能第五;
- 分类任务的 ROCAUC 都挤在 0.92–0.96,前列名次差在噪声内;
- 提交者的实现细节(特征工程、集成、训练轮数)差异,往往大于架构本身的差异。
正确做法:把榜单当参考区间而不是排名。看「某类方法大致在什么水平」,而不是「谁是第一」。
§18 与站内其他基准类条目的关系
站内已有若干「基准/评测」类条目,Matbench 的定位需要放在这个谱系里看:
| 条目 | 形态 | 规模 | 与本条的关系 |
|---|---|---|---|
| Matbench(本条) | 材料性质预测的 13 任务基准 | 408,062 条样本 | 唯一一个非生物医学的基准 |
| TDC(Therapeutics Data Commons) | 药物发现的多任务基准 | 数十个 ADMET 任务 | 同为「基准」,但域是药物;TDC 用官方 scaffold split |
| GuacaMol / MOSES | 分子生成基准 | 约 170 万分子 | 测的是生成质量,不是预测精度 |
| MoleculeNet | 分子性质基准 | 十余个任务 | 与 Matbench 最像的「早期同类」,但域是分子、划分方式不统一 |
| GLUE / SuperGLUE(站外) | NLP 基准 | 8–10 个任务 | 范式来源:「统一划分 + 排行榜」这个模式就是从 NLP 借来的 |
Matbench 在这个谱系里的独特性:
- 唯一的周期性晶体基准。上面这些除它之外,输入全是分子或文本——晶格是 Matbench 独有的输入形态。
- 明确冻结版本。
matbench_v0.1从 2020 年至今未变,这在基准圈里不常见(GLUE 也冻结,但 MoleculeNet 的划分就曾被批评不统一)。 - 同时覆盖「结构」与「成分」两种输入。这是它比纯结构基准更实用的地方——很多真实场景拿不到晶体结构。
站内的空档判断:库内材料/化学类条目已有 QMOF(结构 + 属性)、以及若干分子数据集,但「一个公认的比较协议」这一层是空的。Matbench 补的正是这一层:不是更多数据,而是让别人能复核你。
§19 一句话总结与三条硬约束
一句话:Matbench 不提供材料,它提供一个让别人能验证你说法的场地——13 道题、40.8 万条样本、一份写死的划分文件,换来的是「我的模型更好」这句话终于可复核。
三条硬约束(用之前必须记住):
- 划分不能自己重划。
random_state=18012019的官方五折是唯一可比的口径;自己切出来的数,不能叫「在 Matbench 上的分数」。 - 13 个任务只是 10 份数据。
mp_gap/mp_is_metal共享 106,113 条结构,log_gvrh/log_kvrh共享 10,987 条,expt_gap/expt_is_metal同源。做多任务、做迁移、统计胜场,都必须先扣掉这层重叠。 perovskites的e_form是 eV/unit cell,且氧参考态是水蒸气。它和mp_e_form既不同单位、也不同零点,任何直接比较或合并都是错的。
§20 数字是怎么核出来的:本条的取证记录
本站对每个数字都记录来源与核对方式。这一节交代 Matbench 的数字从哪来、哪些是自己算的、哪些没核到。
§20.1 一手来源(可直接验证)
| 来源 | 拿到了什么 | 状态 |
|---|---|---|
GitHub materialsproject/matbench 的 matbench/matbench_v0.1_dataset_metadata.json |
13 个任务的 n_samples / mad / frac_true / task_type / input_type / target / unit |
✅ 完整下载(2,564 B),逐条解析 |
同仓库 matbench/constants.py |
包版本 VERSION = "0.6"、五折配置、四个回归指标名、四个分类指标名、阈值 0.5 |
✅ 完整 |
同仓库 matbench/data_ops.py |
mbid 构造规则(前缀替换、补零位数公式、从 1 开始) |
✅ 完整 |
同仓库 matbench/task.py、bench.py、metadata.py |
任务接口、get_train_and_val_data / get_test_data / record / scores 的语义 |
✅ 完整 |
同仓库 setup.py |
license="modified BSD"、作者、依赖 |
✅ 完整 |
matminer 仓库 matminer/datasets/dataset_metadata.json |
13 个任务各自的清洗规则(description 原文)、num_entries、SHA-256、原始文献 reference、下载 url |
✅ 完整下载(118,376 B),39 个数据集中筛出 13 个 matbench 条目 |
官网 matbench.materialsproject.org 首页 |
当前 leaderboard 各任务最优模型与分数、Matbench Discovery 榜单、180 次任务提交 / 28 个算法 | ✅ WebFetch |
官网 /Benchmark%20Info/matbench_v0.1/ |
13 个任务的样本数、单位、MAD、正类比例、各任务提交数、下载链接 | ✅ WebFetch,与元数据 JSON 逐项一致 |
论文 doi:10.1038/s41524-020-00406-3(npj Comput Mater 6, 138) |
「13 tasks from 10 datasets」、五折嵌套交叉验证、random_state=18012019、80/20 切分、60/20/20 对 CGCNN/MEGNet、Automatminer 8/13 最优、Dummy 误差高 68–299%、规模效应结论 |
✅ WebFetch,原文摘句 |
官网 /Full%20Benchmark%20Data/matbench_v0.1_automatminer_expressv2020/ |
AMMExpress v2020 在 13 个任务上的逐折 MAE / RMSE / ROCAUC | ✅ WebFetch |
PyPI matbench JSON API |
当前版本 0.6、五个历史版本及发布时间、license: modified BSD |
✅ 完整 |
§20.2 本条目自己算的(一手数据 + 算术)
| 数字 | 算法 | 结果 |
|---|---|---|
| 408,062 条样本 | 13 个任务的 n_samples 直接相加 |
132,752 + 106,113 + 106,113 + 18,928 + 10,987 + 10,987 + 5,680 + 4,921 + 4,764 + 4,604 + 1,265 + 636 + 312 |
| 量级跨度 425 倍 | 132,752 / 312 | ≈ 425.5 |
mp_e_form 占比 32.5% |
132,752 / 408,062 | ≈ 32.53% |
mbid 补零位数 |
floor(log10(n)) + 1,逐任务代入 |
steels 3 / jdft2d 3 / phonons 4 / expt_gap 4 / mp_e_form 6 |
steels 五折极差 43% |
(115.49 − 80.42) / 80.42 | ≈ 43.6% |
| 各任务 scaled error | MAE_best / MAD | 见 §7 与 §11 逐任务 |
| 10 份数据 | 13 − 3 组共享来源 | 10,与论文「10 datasets」吻合 |
§20.3 没核到的、以及怎么处理的
| 项 | 情况 | 处理 |
|---|---|---|
| 各任务数据文件体积 | ml.materialsproject.org 被 Cloudflare 挡住,curl -I 一律 HTTP 403,拿不到 content-length |
正文不给体积,只给样本数。§10 坑 10 已说明这个 403 现象 |
matbench_v0.1_validation.json 完整内容 |
首次下载得到 133,867 B 截断文件(JSONDecodeError: Unterminated string);重试两次,一次 170 s 超时、一次 400 s 超时(exit 28) |
只用已拿到的前 133 KB 确认了 metadata(n_splits: 5、random_state: 18012019、shuffle: true)与 splits.<task>.fold_N.{train,test} 的结构;没有声称逐任务行数,因为官方未公布且本条目未核到 |
| 论文 Table 1 / Table 2 | nature.com 页面的两张表以 [Full size table] 占位,正文未渲染 |
逐任务的清洗规则改用 matminer description 原文(更权威,因为是实际构建数据用的规则),不引用论文表格 |
| 总磁盘占用 | 无官方数字,且无法下载测体积 | 不编。§13 第 11 项评 0.5 分正是因此 |
| 13 个任务原始的「清洗前样本数」 | 论文只说「cleaned」,未给剔除前后对照;matminer 也只给最终 num_entries |
不给。§3 只写「剔除什么」,不写「剔了多少」 |
| 单个数据集的逐条许可 | 10 个上游各有条款,Matbench 只在 setup.py 声明包级 modified BSD |
明确写「BSD 只覆盖代码与划分」,§9 与 §13 第 3 项都标了这一点 |
§20.4 交叉核对矩阵
见 §14。核心结论:元数据 JSON、官网 Benchmark Info 页、论文正文三处,在样本数、MAD、正类比例、划分方式、许可、包版本上一一吻合;唯一的「不一致」是论文的「Automatminer 8/13 最优」与当前榜单只剩 1 项,已解释为榜单滚动更新的正常现象。
§21 版本沿革:为什么 matbench_v0.1 四年多没动
这一节回答一个看起来奇怪的问题:一个 2020 年发布的基准,为什么到现在还叫 v0.1,而且还在用?
§21.1 包版本与基准版本是两条线
| 包版本 | 基准版本 | |
|---|---|---|
| 标识 | matbench 0.6 |
matbench_v0.1 |
| 位置 | constants.py 的 VERSION、PyPI |
constants.py 的 MBV01_KEY |
| 变的频率 | 随代码修 bug、加接口 | 从未变过 |
| 历史 | 0.2(2021-05-06)→ 0.3(2021-07-28)→ 0.4(2021-10-10)→ 0.5(2021-10-10)→ 0.6(2022-07-27) | 只此一个 |
为什么分开:包升级可以修 bug、改接口、换依赖,但不能改变数据与划分。如果包升级导致某个任务的样本数变了,那所有历史分数立刻失效。
§21.2 冻结的代价与收益
收益:
- 2020 年论文里 Automatminer 的数,今天仍然能在同一个划分上复核;
- 任何人六年前提的 PR,结果文件今天重跑应该一致;
- leaderboard 上的所有历史条目,都是在同一把尺子上量的。
代价:
- 无法修正已发现的错误。如果某个任务后来发现标签有系统性错误,只能发 v0.2,而 v0.2 与 v0.1 的分数不可比;
- 无法扩充。新任务只能进 v0.2,老任务不能改;
- 于是出现一个尴尬局面:更有用的新任务(如 Matbench Discovery)另起了名字,而不是进 v0.2。这也解释了 §8 里那两个榜为什么并存而不是合并。
§21.3 一个经验判断
对使用者来说,冻结的基准比「持续更新」的基准更可信。原因很简单:持续更新的基准,你永远不知道自己的分数是被模型提升推动的,还是被数据变化推动的。
如果你看到某篇论文写「在 Matbench 上取得 SOTA」,第一件事应该是确认:
- 用的是
matbench_v0.1还是matbench_discovery; - 用的是官方五折还是自建划分;
- 报的是 mean 还是 best fold。
这三条不看,SOTA 这个说法就没有内容。
附录 A · 13 个任务的原始来源对照
| 任务 | 原始来源 | 文献 / 链接 |
|---|---|---|
mp_e_form、mp_gap、mp_is_metal |
Materials Project(2019-04-02 抓取) | Jain et al., APL Materials 1, 011002 (2013),doi:10.1063/1.4812323 |
log_gvrh、log_kvrh |
de Jong 等弹性数据集 | Sci. Data 2, 150009 (2015) |
dielectric |
Petousis 等介电/光学 | Sci. Data 4, 160134 (2017) |
phonons |
Petretto 等 DFPT 声子 | Sci. Data 5, 180065 (2018),doi:10.1038/sdata.2018.65 |
jdft2d |
JARVIS-DFT 2D | Choudhary et al., Sci. Rep. 7, 5179 (2017);figshare jdft_2d-7-7-2018.json |
perovskites |
Castelli 等钙钛矿 | Energy Environ. Sci. 5, 9034 (2012),doi:10.1039/C2EE22341D |
expt_gap、expt_is_metal |
Zhuo 等实验带隙 | J. Phys. Chem. Lett. 9, 1668 (2018),doi:10.1021/acs.jpclett.8b00124 |
glass |
Landolt-Börnstein III/37A | SpringerMaterials,1997 |
steels |
Citrination | citrination.com/datasets/153092 |
附录 B · 各任务数据的 SHA-256
matminer 元数据里给了每个任务数据文件的 SHA-256,可以用来验证下载完整性:
| 任务 | SHA-256(前 16 位) |
|---|---|
mp_is_metal |
9a028ed5750a4c76 |
mp_gap |
58b65746bd883299 |
mp_e_form |
dedcb1d4ba2e3e50 |
log_gvrh |
098af941f4c66327 |
log_kvrh |
44b113ddb7e23aa1 |
dielectric |
83befa09bc2ec2f4 |
jdft2d |
26057dc4524e193e |
perovskites |
4641e2417f8ec8b5 |
glass |
36beb654e2a463ee |
expt_gap |
783e7d1461eb83b0 |
expt_is_metal |
8f2a4f9bacdcbc5c |
phonons |
4db551f21ec5f577 |
steels |
473bc4957b2ea5e6 |
附录 C · 使用前的 14 项核对清单
- 你用的是
matbench_v0.1还是matbench_discovery?(两个不同的东西) - 报的是 mean MAE 还是 best-fold MAE?(后者会好看很多,但不可比)
- 回归任务是否同时报了 RMSE?(只看 MAE 会掩盖大误差)
- 用了官方划分文件,还是自己切的?
- 分类任务看的是 accuracy 还是 balanced_accuracy / ROCAUC?(
glass必须看后者) perovskites的单位换算了吗(eV/unit cell → eV/atom)?- 多任务训练时,是否处理了
mp_gap/mp_is_metal的结构重叠? log_gvrh和log_kvrh是否也被当成独立数据重复计入了?mp_is_metal知道它是 PBE 判定的,不是实验的吗?expt_gap的「取最接近均值」规则,对你的研究目的是否构成问题?steels只有 312 条,是否报了折间标准差?- 数据是走
matminer.load_dataset()还是裸 curl?(后者会 403) - 商用前是否回上游逐个查了原始许可?(BSD 只覆盖代码与划分)
- 引用了
matbench包的 0.6,还是基准的 v0.1?两个版本号含义完全不同
附录 D · 与站内其他条目的关系
- QMOF(rid 1357):同样面对「材料性质预测」,但 QMOF 是单一库、周期性晶体、四档泛函的带隙;Matbench 是13 个异构任务的基准。前者给你数据,后者给你尺子。
matbench_mp_gap与 QMOF 的 PBE 带隙可以直接对照,但要注意 QMOF 用的是 PBE-D3(BJ),Matbench 用的 MP 的 PBE 设置。 - Matbench Discovery:见 §8,不是同一条。
- 库内材料类条目的空档正是在这里:Matbench 补的不是「更多材料数据」,而是「一个公认的比较协议」。
相关数据集导航
以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:
- qm9 — 共享标签:药物发现与化学 / 化学信息学 / 分子性质预测 / 评测基准 / 量子化学
- aqsoldb — 共享标签:药物发现与化学 / 化学信息学 / 分子性质预测 / 评测基准
- moleculenet — 共享标签:药物发现与化学 / 化学信息学 / 分子性质预测 / 评测基准
- pcqm4mv2 — 共享标签:药物发现与化学 / 化学信息学 / 评测基准 / 量子化学
- oc20 — 共享标签:药物发现与化学 / 化学信息学 / 分子性质预测 / 量子化学
- md22 — 共享标签:药物发现与化学 / 分子性质预测 / 评测基准 / 量子化学
- openadmet-expansionrx — 共享标签:药物发现与化学 / 化学信息学 / 分子性质预测 / 评测基准
- qmof — 共享标签:药物发现与化学 / 化学信息学 / 分子性质预测 / 量子化学
- bace — 共享标签:药物发现与化学 / 化学信息学 / 分子性质预测 / 评测基准
- geom — 共享标签:药物发现与化学 / 化学信息学 / 分子性质预测 / 量子化学
导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

