2. 材料数据集构建与清洗实战

材料性能机器学习回归的第一个瓶颈往往不在模型,而在数据。合金、陶瓷、高分子三类材料的数据来源、字段形态和噪声模式差异很大:合金数据常来自炉次记录与力学测试报告,陶瓷数据常来自烧结工艺与致密度测量,高分子数据则常来自配方、分子量与拉伸测试。本节以“构建一张可直接用于回归建模的表格”为目标,把采集、缺失值处理、异常值识别、重复样本合并与单位统一串成一条可复现的清洗链。

一、先定义目标表结构,再谈采集

回归任务的目标列决定整张表的组织方式。假设我们要预测合金的抗拉强度(MPa),那么每一行应代表一个“成分—工艺—性能”的完整观测单元。建议先写出字段字典,再开始采集,避免后期反复返工。一个可用的最小字段集如下:

字段含义单位/类型是否目标
sample_id样本唯一编号字符串否
source数据来源(文献/实验/数据库)类别否
Fe, Cr, Ni, Mo…合金元素质量分数wt.%否
T_solution固溶温度℃否
t_age时效时间h否
UTS抗拉强度MPa是

陶瓷体系可把成分字段换成 Al₂O₃、ZrO₂、Y₂O₃ 的摩尔分数,工艺字段换成烧结温度、保温时间、致密度;高分子体系则换成单体配比、数均分子量 Mn、拉伸速率。字段名一旦确定,后续所有清洗操作都围绕它进行。

二、缺失值:先判断机制,再决定删或补

缺失值不能一律删除或一律填充。先看缺失比例和缺失机制:若某字段缺失超过 40%,且不是关键工艺参数,通常直接整列剔除;若缺失集中在少数行且目标列完整,可考虑删除该行;若缺失比例低(如小于 5%)且字段间存在物理关联,则用规则或模型填补更合理。

以合金为例,若某批样本缺少 Mo 含量,但已知其牌号属于 316L 系列,可按该牌号典型范围取中位值填补,并在 source 字段旁增加一列 Mo_imputed 标记为 1,保留可追溯性。对连续工艺参数,如时效时间缺失,可用同成分族样本的中位数填补;对类别字段,如热处理状态缺失,则新增“unknown”类别,而不是强行归入某一类。下面是一段可直接运行的 pandas 示例:

import pandas as pd
import numpy as np

df = pd.read_csv("alloy_raw.csv")

# 1) 删除缺失率过高的列
thr = 0.4
df = df.loc[:, df.isna().mean() < thr]

# 2) 目标列缺失的行直接删除
df = df.dropna(subset=["UTS"])

# 3) 数值列按成分族中位数填补,并打标记
num_cols = ["Mo", "t_age", "T_solution"]
for c in num_cols:
    if df[c].isna().any():
        df[c + "_imputed"] = df[c].isna().astype(int)
        df[c] = df.groupby("family")[c].transform(
            lambda s: s.fillna(s.median())
        )

# 4) 类别列缺失填 unknown
df["heat_treatment"] = df["heat_treatment"].fillna("unknown")

填补后要检查分布是否被扭曲:对比填补前后 Mo 的均值与标准差,若偏移超过 10%,说明填补规则不合理,应改用分组回归或直接删除。

三、异常值:物理边界 + 统计规则双通道

材料数据的异常值有两类:一类是物理上不可能的值,如抗拉强度为负、元素质量分数之和超过 100%、致密度大于 100%;另一类是统计上偏离群体但物理上可能的值,如某炉次强度异常高。前者直接判为错误,后者需要结合工艺记录判断是真实极端样本还是录入错误。

推荐先用物理边界做硬过滤,再用 IQR 或稳健 Z 分数做软标记。例如对 UTS 按成分族分组,计算 Q1、Q3,标记超出 [Q1−1.5IQR, Q3+1.5IQR] 的样本,但不立即删除,而是输出到待核查清单。若该样本同时伴随 T_solution 或 t_age 明显偏离常规窗口,则更可能是录入错误;若工艺参数正常且来源可靠,则应保留,因为极端值对回归边界的约束很有价值。

异常值处理的核心不是“删干净”,而是“可解释”。每一个被删除或修正的样本,都应在清洗日志中记录原因、依据和操作人。

四、重复样本合并:识别“同一实验的不同记录”

重复样本不一定 sample_id 相同。合金数据中,同一炉次可能因多次测试产生多条记录;高分子数据中,同一配方可能因不同拉伸速率被重复录入。识别重复应基于“成分 + 关键工艺”的组合键,而不是仅看编号。

合并策略取决于重复的性质:若为同一条件下的多次测量,取均值并记录标准差,可同时得到不确定性信息;若为不同来源的同一材料,优先保留实验来源,文献来源作为补充;若两条记录目标值差异超过 15%,则不应简单平均,而应视为两个不同状态或存在错误,转入人工核查。示例代码如下:

key = ["Fe", "Cr", "Ni", "Mo", "T_solution", "t_age"]

# 同一条件下多次测量:取均值与标准差
agg = df.groupby(key).agg(
    UTS_mean=("UTS", "mean"),
    UTS_std=("UTS", "std"),
    n=("UTS", "size")
).reset_index()

# 目标值差异过大的组单独输出核查
bad = agg[(agg["UTS_std"] / agg["UTS_mean"]) > 0.15]

五、单位统一:清洗链中最容易被忽视的一步

单位不统一是回归模型性能骤降的常见原因。合金强度可能同时出现 MPa、ksi、GPa;温度可能混用 ℃ 与 K;高分子分子量可能用 g/mol 与 kg/mol。必须在清洗阶段统一到一套单位,并在字段名或元数据中固定下来。常用换算:1 ksi ≈ 6.895 MPa,1 GPa = 1000 MPa,K = ℃ + 273.15。

单位统一后,还要检查量纲一致性:成分字段统一为 wt.% 或 at.%,不要混用;时间统一为 h 或 s;温度统一为 ℃ 或 K。建议在数据字典中写明每个字段的单位,并在代码中用列名后缀显式标注,如 UTS_MPa、T_solution_C,避免后续建模时再次混淆。

材料数据清洗链:从原始记录到可建模表格 以合金 UTS 回归为例,陶瓷/高分子仅替换字段对象 ① 数据采集 炉次记录 / 文献 成分 · 工艺 · 性能 字段字典先行 sample_id / source ② 缺失值处理 >40% 列剔除 目标缺失行删除 分组中位数填补 + imputed 标记列 ③ 异常值识别 物理边界硬过滤 IQR / 稳健 Z 软标记 待核查清单 不立即删除 ④ 重复样本合并 成分+工艺组合键 均值 + 标准差 差异 >15% 转核查 保留 n 计数 ⑤ 单位 统一 MPa ℃ wt.% 核查后回填或修正 输出:可建模表格(每行一个完整观测) sample_id Fe/Cr/Ni/Mo (wt.%) T_solution (℃) t_age (h) UTS (MPa) A-001 Bal / 17.2 / 12.1 / 2.3 1050 4.0 620 清洗日志(必须保留) · 删除行数 / 原因 · 填补字段 / 规则 / 影响 · 异常样本处置结论 质量检查点 · 成分总和 ≈ 100% · 目标列无缺失、无负值 · 单位列名显式标注 常见陷阱 · 用全局均值填补分组数据 · 重复样本简单平均掩盖差异 · ksi 与 MPa 混用未察觉

六、清洗后的验收标准

完成上述五步后,不要急于建模,先做一次验收。验收清单可以很短,但必须逐项确认:目标列无缺失、无负值;成分字段总和在 99%~101% 之间(允许舍入误差);关键工艺参数落在物理合理区间;单位列名显式标注;重复样本已合并且保留了测量次数;异常值处置有记录。只有全部通过,这张表才具备进入特征工程与回归建模的资格。

最后强调一点:清洗不是一次性动作。当后续加入新来源数据时,应把本节的处理规则固化为脚本或函数,对新数据重复执行同样的缺失判断、异常标记和单位换算,保证训练集与推理集的数据口径一致。这一步做扎实,模型性能的波动会明显减小,回归结果也更容易解释。