机器学习预测纤维材料力学性能:从数据准备到模型部署
问题的本质
纤维生物材料的力学性能(杨氏模量、极限强度、断裂韧性)取决于大量因素:纤维直径、取向分布、交联密度、含水量、温度、应变率……传统的单变量回归只能处理线性关系,而纤维网络的高度非线性行为需要机器学习来捕捉。
但材料科学的 ML 有个特殊挑战:数据少。你不可能像互联网公司那样收集百万条实验数据——一篇论文可能只有几十个样本。
本文的策略是:在数据稀缺的约束下,用合理的特征工程和模型选择得到可靠的预测。
第一步:数据准备
典型的数据长什么样
import pandas as pd
import numpy as np
data = pd.DataFrame({
"fiber_diameter_nm": [45, 52, 48, 55, 50],
"orientation_std_deg": [12, 22, 8, 18, 15],
"crosslink_density_pct": [2.5, 1.8, 3.2, 2.0, 4.1],
"water_content_pct": [15, 22, 10, 18, 8],
"strain_rate_per_s": [0.01, 0.05, 0.01, 0.1, 0.01],
"youngs_modulus_GPa": [2.8, 1.9, 3.5, 2.3, 4.0],
"ultimate_strength_MPa": [120, 85, 150, 105, 170],
})
关键预处理步骤
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, QuantileTransformer
# 分离特征和目标
feature_cols = [c for c in data.columns if c not in
("youngs_modulus_GPa", "ultimate_strength_MPa")]
X = data[feature_cols].values
y_modulus = data["youngs_modulus_GPa"].values
y_strength = data["ultimate_strength_MPa"].values
# 小规模数据:保留 20% 测试,其余做交叉验证
X_train, X_test, y_train, y_test = train_test_split(
X, y_modulus, test_size=0.2, random_state=42
)
# 标准化(对基于距离/梯度的模型很重要)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
第二步:特征工程
利用领域知识构造交互特征
纤维材料的力学性能通常有物理意义明确的交互关系:
def add_domain_features(df):
"""加入材料科学领域知识的交互特征"""
df = df.copy()
# 交联密度 × 纤维直径:粗纤维高交联的协同效应
df["crosslink_x_diameter"] = (df["crosslink_density_pct"] *
df["fiber_diameter_nm"])
# 取向标准差与含水量的比值:无序 + 湿态的弱化效应
df["orient_water_ratio"] = (df["orientation_std_deg"] /
(df["water_content_pct"] + 1e-3))
# 应变率敏感指数近似
df["strain_rate_log"] = np.log10(df["strain_rate_per_s"] + 1e-9)
return df
data_aug = add_domain_features(data)
第三步:模型选择与评估
核心原则:数据少 → 选偏差高的模型,配合强正则化。
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, WhiteKernel
from sklearn.model_selection import cross_val_score, RepeatedKFold
# 小样本交叉验证策略
cv = RepeatedKFold(n_splits=5, n_repeats=10, random_state=42)
models = {
"RandomForest": RandomForestRegressor(
n_estimators=200, max_depth=5,
min_samples_leaf=2, random_state=42
),
"GradientBoosting": GradientBoostingRegressor(
n_estimators=100, max_depth=3,
learning_rate=0.05, random_state=42
),
"GaussianProcess": GaussianProcessRegressor(
kernel=RBF() + WhiteKernel(),
normalize_y=True, random_state=42
),
}
for name, model in models.items():
scores = cross_val_score(model, X_train_scaled, y_train,
cv=cv, scoring="neg_mean_absolute_error")
print(f"{name}: MAE = {-scores.mean():.3f} ± {scores.std():.3f} GPa")
为什么选这些模型
| 模型 | 小数据优势 | 要注意 |
|---|---|---|
| ------ | ----------- | -------- |
| Random Forest | 对超参数不敏感,自带特征重要性 | max_depth 要小 |
| Gradient Boosting | 精度高,可处理非线性 | 容易过拟合,lr 要低 |
| Gaussian Process | 自带不确定性估计,适合小样本 | 计算量 O(n³),n>1000 慎用 |
第四步:不确定性很重要
材料科学中,只说"预测模量 2.8 GPa"不够,你需要给出置信区间:
from sklearn.ensemble import RandomForestRegressor
def predict_with_uncertainty(model, X, n_iterations=100):
"""用 Bootstrap 估计预测不确定性"""
predictions = np.zeros((n_iterations, len(X)))
for i in range(n_iterations):
idx = np.random.choice(len(X_train_scaled), len(X_train_scaled))
model.fit(X_train_scaled[idx], y_train[idx])
predictions[i] = model.predict(X)
return np.mean(predictions, axis=0), np.std(predictions, axis=0)
rf = RandomForestRegressor(n_estimators=100, max_depth=5, random_state=42)
mean_pred, std_pred = predict_with_uncertainty(rf, X_test_scaled)
for i in range(len(mean_pred)):
print(f"Sample {i}: {mean_pred[i]:.2f} ± {std_pred[i]:.2f} GPa "
f"(actual: {y_test[i]:.2f})")
第五步:特征重要性——告诉老板为什么
ML 模型不仅要做预测,还要帮助理解物理机制:
import matplotlib.pyplot as plt
rf.fit(X_train_scaled, y_train)
importances = rf.feature_importances_
indices = np.argsort(importances)[::-1]
fig, ax = plt.subplots(figsize=(8, 5))
ax.barh(range(len(indices)), importances[indices], align="center")
ax.set_yticks(range(len(indices)))
ax.set_yticklabels([feature_cols[i] for i in indices])
ax.set_xlabel("Feature Importance")
ax.set_title("What Drives Fiber Mechanics?")
ax.invert_yaxis()
plt.tight_layout()
plt.savefig("feature_importance.pdf", dpi=150, bbox_inches="tight")
进阶方向
数据多起来之后,可以考虑:
- 图神经网络 (GNN) —— 把纤维网络建模为图,每个纤维是节点,交点连边
- 迁移学习 —— 在大量仿真数据上预训练,在少量实验数据上微调
- 主动学习 —— 模型告诉你下一个该做哪组实验最有效
- 物理信息神经网络 (PINN) —— 把本构方程作为约束注入神经网络
要点总结
- 数据少不是不做的理由 — 贝叶斯方法和高斯过程专为小样本设计
- 特征工程比模型重要 — 领域知识驱动的特征能补上数据量的不足
- 必须报告不确定性 — 不然审稿人会问
- 开源你的代码和数据 — GitHub 上的可复现代码会让论文更有说服力
代码获取
本文完整代码可在 GitHub 获取(持续更新中)。