第三章 材料数据预处理与清洗:缺失值处理、异常值检测、数据标准化与归一化、特征工程基础

各位好,欢迎来到第三章。说实话,这一章可能是整个课程里最“脏”最“累”的活,但也是最能体现功力的地方。我见过太多人,模型选得再好,算法调得再妙,结果数据一塌糊涂,最后全白干。数据预处理,说白了就是给材料数据“洗澡”,洗得干净,后面的分析才能顺溜。

3.1 缺失值处理:别让“空”坑了你

材料实验数据,很少有完美无缺的。设备故障、人为疏忽、样品污染……原因太多了。我当年做高温合金的疲劳寿命预测时,有一批关键数据因为热电偶烧断了,直接缺了30%的应力值。当时急得不行,后来才明白,缺失值处理不是简单的“填上就行”,而是要根据数据特性来。

3.1.1 缺失值类型与识别

首先,你得知道数据是怎么“丢”的。一般分三种:

  • 完全随机缺失(MCAR):比如打翻了一杯溶液,数据丢失跟其他变量无关。这种情况最简单,直接删掉或简单填充都行。
  • 随机缺失(MAR):缺失的概率跟其他观测变量有关。比如,只有高温下的样品才容易损坏传感器,导致温度数据缺失。这需要更小心。
  • 非随机缺失(MNAR):缺失的原因跟缺失值本身有关。比如,强度太低的材料,测试时直接断裂,数据没采到。这是最麻烦的,需要领域知识介入。

识别方法很简单,用 pandasisnull() 看一眼就行。但我建议你,别只看总数,要按列、按条件分组看。我曾经用 df.groupby('实验批次')['抗拉强度'].apply(lambda x: x.isnull().sum()) 发现,某个批次的缺失率异常高,后来一查,是那台万能试验机该保养了。

核心原则:缺失率低于5%,直接删除行;5%-20%,考虑填充;超过20%,必须评估是否还能用这个特征。

3.1.2 常用填充方法

填充不是瞎填。我习惯按这个顺序来:

  1. 均值/中位数填充:最简单,但会降低方差。适合正态分布的数据。比如,填充杨氏模量的缺失值,用中位数更稳健。
  2. 前向/后向填充:适合时间序列数据。比如,同一炉次的连续测温数据,用前一个值填充。
  3. KNN填充:找最相似的k个样本,用它们的平均值。我在做高熵合金成分优化时,用这个方法效果很好,因为它保留了成分之间的关联性。
  4. 模型预测填充:把缺失值当标签,用其他特征训练模型来预测。这是最精确的,但计算量大。
# 一个简单的KNN填充示例
from sklearn.impute import KNNImputer
import numpy as np

# 假设X是特征矩阵,有缺失值
imputer = KNNImputer(n_neighbors=5, weights='distance')
X_filled = imputer.fit_transform(X)

# 注意:一定要先标准化再填充,否则距离计算会被量纲大的特征主导

我的经验:填充后,一定要对比填充前后的分布直方图。如果形状变了,说明填充方法有问题。我曾经用均值填充偏态分布的数据,结果把双峰变成了单峰,差点误导了后续的聚类分析。

3.2 异常值检测:揪出“捣乱分子”

异常值,就是那些明显偏离正常范围的数据点。在材料科学里,异常值可能是宝贵的发现(比如一种新相),也可能是纯粹的噪声(比如测量错误)。怎么区分?嗯,这里要注意,不能只看统计指标,还得懂材料。

3.2.1 统计方法

最常用的是 3σ原则箱线图

  • 3σ原则:假设数据服从正态分布,超出均值±3倍标准差的值视为异常。适合对称分布。
  • 箱线图(IQR):用四分位距(Q3 - Q1)来定义异常。超出Q1-1.5*IQR或Q3+1.5*IQR的点。这个方法对偏态分布更鲁棒。

我个人更偏爱箱线图,因为材料数据很少是完美的正态分布。比如,金属材料的硬度数据,往往有右偏,用3σ会漏掉很多低端异常。

3.2.2 基于模型的方法

当数据维度高时,统计方法就不够用了。这时候可以用 孤立森林(Isolation Forest)LOF(局部异常因子)

孤立森林的原理很巧妙:异常点因为“与众不同”,更容易被随机划分出来。我曾在处理陶瓷烧结工艺参数时,用孤立森林发现了一组异常的温度-压力组合,后来验证是传感器漂移导致的。

from sklearn.ensemble import IsolationForest

# 假设data是预处理后的特征矩阵
iso_forest = IsolationForest(contamination=0.05, random_state=42)
outliers = iso_forest.fit_predict(data)  # -1表示异常,1表示正常

# 可视化异常点
import matplotlib.pyplot as plt
plt.scatter(data[:, 0], data[:, 1], c=outliers, cmap='coolwarm')
plt.title('异常值检测结果')
plt.show()

避坑指南:我曾经在检测复合材料层间剪切强度时,用默认参数跑孤立森林,结果把几个真实的界面脱粘样本标成了异常。后来调整了 contamination 参数,并结合SEM图像验证,才把真正的异常找出来。记住:算法只是辅助,最终判断要靠领域知识。

3.3 数据标准化与归一化:让所有特征“平起平坐”

为什么需要这一步?你想想看,如果特征A的量级是0.1,特征B的量级是1000,那很多算法(比如KNN、SVM、PCA)会天然地更看重特征B,因为它的数值大。这显然不合理。标准化和归一化,就是让所有特征在同一个尺度上对话。

3.3.1 标准化(Z-score)

公式很简单:z = (x - μ) / σ。处理后,数据均值为0,标准差为1。适合数据近似正态分布的情况。我在做XRD图谱的峰位分析时,常用标准化,因为它保留了原始数据的分布形状。

3.3.2 归一化(Min-Max)

公式:x' = (x - min) / (max - min)。将数据缩放到[0, 1]区间。适合数据有明确边界的情况,比如成分含量(0%-100%)。但注意,它对异常值非常敏感——如果有一个极端值,其他数据会被压缩到很小的范围。

from sklearn.preprocessing import StandardScaler, MinMaxScaler

# 标准化
scaler_std = StandardScaler()
X_std = scaler_std.fit_transform(X)

# 归一化
scaler_mm = MinMaxScaler()
X_mm = scaler_mm.fit_transform(X)

# 我的习惯:先画分布图,再决定用哪个
# 如果数据有长尾,我会先用RobustScaler(基于中位数和IQR),它对异常值更鲁棒

关键区别:标准化不改变数据的分布形状,归一化会改变。如果你后续要用PCA或线性模型,标准化更合适;如果是神经网络,归一化通常收敛更快。

3.4 特征工程基础:从“数据”到“知识”的桥梁

特征工程,说白了就是“造特征”。原始数据往往不够用,你需要根据材料科学的理解,创造出更有预测力的特征。这是最能体现“专家”和“新手”差距的地方。

3.4.1 特征构造

我常用的方法有:

  • 多项式特征:比如,把成分A和成分B的乘积作为新特征,捕捉交互作用。在合金设计中,Cr * Mo 往往比单独看Cr或Mo更能预测耐腐蚀性。
  • 领域特定特征:比如,从应力-应变曲线中提取“屈服点”、“弹性模量”、“断裂伸长率”。这些比直接用原始曲线点更有效。
  • 统计特征:对于时间序列数据(如热处理温度曲线),提取均值、方差、斜率、峰值等。

3.4.2 特征选择

特征不是越多越好。我见过有人把100多个特征全扔进模型,结果过拟合得一塌糊涂。常用的选择方法:

  1. 过滤法:计算每个特征与目标变量的相关性(皮尔逊、互信息)。保留相关性高的。
  2. 包裹法:用递归特征消除(RFE),每次去掉最不重要的特征。计算量大,但效果好。
  3. 嵌入法:用Lasso回归或树模型的特征重要性。我偏爱用随机森林的特征重要性,因为它能处理非线性关系。
from sklearn.feature_selection import SelectKBest, f_regression
from sklearn.ensemble import RandomForestRegressor

# 过滤法:选择与目标最相关的5个特征
selector = SelectKBest(score_func=f_regression, k=5)
X_selected = selector.fit_transform(X, y)

# 嵌入法:用随机森林看特征重要性
rf = RandomForestRegressor()
rf.fit(X, y)
importances = rf.feature_importances_
# 排序后,保留累积重要性达到95%的特征

我的建议:特征工程要“少而精”。我做过一个项目,一开始有50个特征,经过领域分析和特征选择,最后只用了8个,模型性能反而提升了15%。记住:好的特征,一个顶十个。

知识体系总览

下面这张图,是我自己梳理的本章知识结构。你可以把它当作一个检查清单,做预处理时对照着来。

材料数据预处理与清洗知识体系 数据预处理 缺失值处理 • 识别类型(MCAR/MAR/MNAR) • 删除法(行/列) • 填充法(均值/KNN/模型) 异常值检测 • 统计方法(3σ/箱线图) • 模型方法(孤立森林/LOF) • 领域知识验证 标准化与归一化 • Z-score标准化 • Min-Max归一化 • RobustScaler(抗异常值) 特征工程 • 特征构造(多项式/领域) • 特征选择(过滤/包裹/嵌入) • 降维(PCA/t-SNE) 目标:干净、一致、有预测力的特征矩阵

好了,这一章的内容就到这里。数据预处理没有银弹,每个数据集都有自己的脾气。我的建议是:多画图、多思考、多验证。把基础打牢,后面的建模才能事半功倍。

专注资料整理