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,避免后续建模时再次混淆。
六、清洗后的验收标准
完成上述五步后,不要急于建模,先做一次验收。验收清单可以很短,但必须逐项确认:目标列无缺失、无负值;成分字段总和在 99%~101% 之间(允许舍入误差);关键工艺参数落在物理合理区间;单位列名显式标注;重复样本已合并且保留了测量次数;异常值处置有记录。只有全部通过,这张表才具备进入特征工程与回归建模的资格。
最后强调一点:清洗不是一次性动作。当后续加入新来源数据时,应把本节的处理规则固化为脚本或函数,对新数据重复执行同样的缺失判断、异常标记和单位换算,保证训练集与推理集的数据口径一致。这一步做扎实,模型性能的波动会明显减小,回归结果也更容易解释。