本节摘要
上一节中,我们利用线性回归从应力—应变数据中识别了材料弹性模量。当模型只有一个输入特征时,问题相对简单。但真实的有限元代理模型往往同时包含载荷、几何尺寸、材料参数和边界条件等多个输入,其中一些变量还可能高度相关。
本节将通过一个多参数结构位移预测案例,学习岭回归、Lasso回归和弹性网络,理解如何利用正则化缓解特征共线性与过拟合,并从大量候选参数中筛选关键力学特征。
一、本节学习目标
完成本节后,你将能够:
理解过拟合与特征共线性的基本含义;
解释正则化为什么能够提高模型稳定性;
掌握岭回归的L2正则化原理;
掌握Lasso回归的L1正则化原理;
理解弹性网络如何结合L1与L2正则化;
正确使用StandardScaler标准化力学特征;
比较不同模型的系数、MAE、RMSE和
;
利用Lasso初步筛选关键力学参数。
二、为什么普通线性回归还不够?
考虑一个结构位移预测任务。
模型输入包括:
其中:
为载荷;
为结构长度;
为截面宽度;
为截面厚度;
为截面积;
为弹性模量。
模型输出为最大位移:
由于:
截面积与宽度、厚度之间存在直接关系。因此,模型输入中的、
和
并不是相互独立的。
这类现象称为特征共线性。
当多个特征表达了相似的信息时,普通线性回归可能出现:
回归系数随数据扰动明显变化;
某些系数符号不符合直觉;
不同数据划分得到完全不同的系数;
训练集表现很好,测试集表现下降;
很难判断哪个参数真正重要。
三、什么是过拟合?
一个模型如果过度追随训练数据中的偶然波动,就可能出现:
训练误差很小,但测试误差较大。
这种现象称为过拟合。
可以把它想象成一个结构设计:
约束过少,结构虽然灵活,却可能不稳定;
约束过强,结构非常稳定,却可能失去必要的变形能力;
约束合理,才能兼顾适应性与稳定性。
正则化就是给模型系数增加适当的“约束力”。
图5-1 不同正则化方法的作用
四、普通线性回归的目标函数
多元线性回归模型可以写成:
普通线性回归通过最小化残差平方和寻找模型参数:
它只关心预测误差,不限制系数大小。
当特征数量较多或存在共线性时,模型可能使用较大的正负系数相互抵消。虽然训练误差很小,但模型容易受到数据扰动影响。
五、正则化的基本思想
正则化在原有损失函数后增加一个系数惩罚项:
预测误差+系数惩罚
它要求模型在两个目标之间进行权衡:
尽量准确地拟合数据;
不要使用过大、过于复杂的系数组合。
控制惩罚强度的参数通常记为:
一般来说:
时,模型接近普通线性回归;
较小时,约束作用较弱;
较大时,系数被明显压缩;
过大时,模型可能发生欠拟合。
六、岭回归:使用L2约束稳定模型
岭回归的目标函数为:
其中:
称为L2惩罚项。
岭回归的主要特点是:
将较大的系数向0压缩;
通常不会让系数严格等于0;
能够降低共线特征造成的系数波动;
适合大部分特征都有一定贡献的情况。
岭回归更像是让所有参数“共同承担责任”,但不允许某一个参数获得过大的权重。
七、Lasso回归:使用L1约束筛选特征
Lasso回归的目标函数为:
其中:
称为L1惩罚项。
Lasso的重要特点是:
它可以把部分不重要或冗余特征的系数直接压缩为0。
因此,Lasso不仅能够抑制过拟合,还可以用于特征选择。
在力学预测中,它可以帮助回答:
哪些几何参数对位移影响较大?
哪些材料参数可以暂时忽略?
哪些特征表达了重复信息?
后续参数化仿真应重点扫描哪些变量?
八、弹性网络:同时结合L1和L2
弹性网络的目标函数可以写成:
其中在scikit-learn中对应:
l1_ratio当:
模型接近Lasso回归。
当:
模型接近岭回归。
弹性网络适合以下情况:
特征数量较多;
多个特征高度相关;
希望进行特征筛选;
又不希望Lasso只保留相关特征中的一个。
九、构造多参数力学仿真数据集
本案例模拟80组结构参数化仿真数据。输入变量包括载荷、长度、宽度、厚度、截面积和弹性模量,输出为最大位移。
import numpy as np import pandas as pd n_samples = 80 index = np.arange(n_samples) load_kN = 5 + (index % 16) * 0.8 length_mm = 600 + (index % 8) * 25 width_mm = ( 20 + (index % 10) * 0.9 + 0.5 * np.sin(index) ) thickness_mm = ( 2.5 + (index % 7) * 0.12 + 0.05 * np.cos(index) ) area_mm2 = width_mm * thickness_mm elastic_modulus_values = np.array([ 70.0, 110.0, 210.0, 110.0 ]) elastic_modulus_GPa = ( elastic_modulus_values[index % 4] ) noise = ( 0.18 * np.sin(0.7 * index) + 0.08 * np.cos(1.3 * index) ) max_displacement_mm = ( 0.55 * load_kN + 0.004 * length_mm - 0.035 * area_mm2 - 0.018 * elastic_modulus_GPa + noise ) data = pd.DataFrame({ "载荷_kN": load_kN, "长度_mm": length_mm, "宽度_mm": width_mm, "厚度_mm": thickness_mm, "截面积_mm2": area_mm2, "弹性模量_GPa": elastic_modulus_GPa, "最大位移_mm": max_displacement_mm }) print("数据形状:", data.shape) print("列名:", data.columns.tolist())预期输出
数据形状: (80, 7) 列名: ['载荷_kN', '长度_mm', '宽度_mm', '厚度_mm', '截面积_mm2', '弹性模量_GPa', '最大位移_mm']这里加入少量周期性扰动,用来模拟有限元离散误差、测量误差和未建模因素。
十、检查特征共线性
geometry_correlation = data[ ["宽度_mm", "厚度_mm", "截面积_mm2"] ].corr() print(geometry_correlation.round(3))预期输出
宽度_mm 厚度_mm 截面积_mm2 宽度_mm 1.000 -0.002 0.777 厚度_mm -0.002 1.000 0.624 截面积_mm2 0.777 0.624 1.000可以看到:
这说明截面积与宽度、厚度包含较多重复信息。
相关系数接近1或-1时,代表两个特征具有较强线性关系。但相关系数只能帮助发现问题,不能单独决定是否删除某个力学参数。
十一、划分特征、标签和数据集
feature_names = [ "载荷_kN", "长度_mm", "宽度_mm", "厚度_mm", "截面积_mm2", "弹性模量_GPa" ] X = data[feature_names] y = data["最大位移_mm"] test_mask = index % 5 == 0 train_mask = ~test_mask X_train = X.loc[train_mask] X_test = X.loc[test_mask] y_train = y.loc[train_mask] y_test = y.loc[test_mask] print("训练集:", X_train.shape) print("测试集:", X_test.shape)预期输出
训练集: (64, 6) 测试集: (16, 6)测试集不参与模型参数训练,只用于评价模型对未见工况的预测能力。
十二、为什么必须进行特征标准化?
不同力学特征的数值尺度差异很大:
载荷可能为
;
长度可能为
;
厚度可能只有
;
弹性模量可能为
。
如果直接进行正则化,数值尺度较大的特征可能受到不公平的惩罚。
标准化公式为:
其中:
为第
个特征的训练集均值;
为第
个特征的训练集标准差。
注意:标准化器只能使用训练集拟合,不能提前读取测试集信息,否则会造成数据泄漏。
十三、建立四种回归模型
使用Pipeline可以将标准化和模型训练封装成一个完整流程。
from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.linear_model import ( LinearRegression, Ridge, Lasso, ElasticNet ) models = { "线性回归": Pipeline([ ("scaler", StandardScaler()), ("model", LinearRegression()) ]), "岭回归": Pipeline([ ("scaler", StandardScaler()), ("model", Ridge(alpha=1.0)) ]), "Lasso": Pipeline([ ("scaler", StandardScaler()), ("model", Lasso( alpha=0.04, max_iter=100000, tol=1e-10 )) ]), "弹性网络": Pipeline([ ("scaler", StandardScaler()), ("model", ElasticNet( alpha=0.04, l1_ratio=0.5, max_iter=100000, tol=1e-10 )) ]) } for name, model in models.items(): model.fit(X_train, y_train) print(name, "训练完成")预期输出
线性回归 训练完成 岭回归 训练完成 Lasso 训练完成 弹性网络 训练完成Pipeline可以保证预测新数据时,自动使用训练阶段建立的标准化规则。
十四、比较四种模型的回归系数
coefficient_table = pd.DataFrame( index=feature_names ) for name, pipeline in models.items(): coefficient_table[name] = ( pipeline.named_steps["model"].coef_ ) print(coefficient_table.round(4))预期输出
线性回归 岭回归 Lasso 弹性网络 载荷_kN 2.0392 1.9980 2.0108 1.9728 长度_mm 0.2153 0.2287 0.1779 0.2139 宽度_mm -0.1459 -0.0894 0.0000 0.0000 厚度_mm -0.1504 -0.1054 -0.0070 -0.0253 截面积_mm2 -0.1015 -0.1734 -0.2663 -0.2716 弹性模量_GPa -0.9308 -0.9144 -0.8812 -0.8856这里展示的是标准化特征对应的系数,因此可以比较不同特征的相对影响程度。
从结果可以看到:
载荷系数为正,说明载荷增大时位移增大;
弹性模量系数为负,说明材料刚度提高时位移减小;
截面积系数为负,说明截面增大时结构位移减小;
Lasso将宽度系数压缩为0;
岭回归保留了全部特征,但减小了共线特征的系数波动。
图5-2 四种模型的标准化回归系数
十五、为什么Lasso删除了宽度?
截面积满足:
当模型已经获得、
和
时,这些变量之间存在信息重复。
Lasso发现,在保留截面积和少量厚度信息后,宽度不再提供足够的额外预测价值,因此将其系数压缩为:
但必须注意:
系数为0不等于这个参数在物理上绝对没有作用。
它只表示在当前数据范围、当前特征组合和当前下,该变量没有提供足够的独立预测信息。
如果删除截面积,再重新训练模型,宽度和厚度的系数就可能重新增大。
十六、计算模型评价指标
from sklearn.metrics import ( mean_absolute_error, mean_squared_error, r2_score ) evaluation_records = [] for name, model in models.items(): prediction = model.predict(X_test) mae = mean_absolute_error( y_test, prediction ) rmse = np.sqrt( mean_squared_error( y_test, prediction ) ) r2 = r2_score( y_test, prediction ) evaluation_records.append({ "模型": name, "MAE_mm": mae, "RMSE_mm": rmse, "R2": r2 }) evaluation = pd.DataFrame( evaluation_records ) print( evaluation.to_string( index=False, float_format=lambda value: f"{value:.4f}" ) )预期输出
模型 MAE_mm RMSE_mm R2 线性回归 0.1329 0.1544 0.9947 岭回归 0.1316 0.1566 0.9946 Lasso 0.1227 0.1480 0.9951 弹性网络 0.1312 0.1584 0.9944在本案例中,四种模型都取得了较高精度。其中Lasso的测试集MAE和RMSE略低,并且使用了更少的有效特征。
这并不意味着Lasso在所有问题中都最好,而是说明:
预测精度+模型简洁性+工程可解释性
应当综合考虑。
图5-3 不同模型的测试集误差
十七、正则化强度
的影响
决定模型受到多强的约束。
当
过小时
此时模型接近普通线性回归:
系数约束较弱;
训练误差较小;
可能无法解决过拟合与共线性。
当
过大时
大量系数被压缩;
Lasso可能删除过多特征;
模型表达能力下降;
训练误差和测试误差都可能增大。
这种现象称为欠拟合。
因此,不是越大越好,也不是越小越好,而应通过交叉验证选择。
十八、Lasso筛选出的特征是否可信?
可以查看Lasso保留的特征:
lasso_coefficients = ( models["Lasso"] .named_steps["model"] .coef_ ) selected_features = [ feature for feature, coefficient in zip( feature_names, lasso_coefficients ) if abs(coefficient) > 1e-8 ] removed_features = [ feature for feature, coefficient in zip( feature_names, lasso_coefficients ) if abs(coefficient) <= 1e-8 ] print("保留特征:", selected_features) print("删除特征:", removed_features)预期输出
保留特征: ['载荷_kN', '长度_mm', '厚度_mm', '截面积_mm2', '弹性模量_GPa'] 删除特征: ['宽度_mm']模型筛选结果还需要接受力学知识检查:
载荷被保留:符合结构变形规律;
长度被保留:符合尺寸效应;
弹性模量被保留:符合刚度规律;
截面积被保留:符合截面承载规律;
宽度被删除:可能是因为它的信息已经被截面积吸收。
这种检查过程称为物理一致性验证。
十九、岭回归、Lasso和弹性网络怎么选?
| 方法 | 主要特点 | 适用场景 |
|---|---|---|
| 线性回归 | 不限制系数 | 特征少、共线性弱、数据充足 |
| 岭回归 | 所有系数整体收缩 | 多数特征都有作用、共线性明显 |
| Lasso | 部分系数变为0 | 希望筛选关键参数、建立稀疏模型 |
| 弹性网络 | 同时使用L1与L2 | 特征多且成组相关,需要兼顾筛选和稳定 |
可以使用下面的经验判断:
主要目标是稳定预测:优先尝试岭回归;
主要目标是筛选参数:优先尝试Lasso;
特征很多且相关性复杂:优先尝试弹性网络;
样本和特征都比较简单:普通线性回归可能已经足够。
最终仍应以交叉验证结果和力学合理性为准。
二十、常见错误与排查方法
错误一:正则化前没有标准化
不同单位和数值尺度会造成不公平的系数惩罚。
推荐使用:
Pipeline([ ("scaler", StandardScaler()), ("model", Ridge(alpha=1.0)) ])错误二:使用全部数据计算标准化参数
这会让测试集信息提前进入训练过程,造成数据泄漏。
错误三:认为Lasso删除的特征没有物理作用
Lasso判断的是特征对当前数据和当前模型的独立预测贡献,而不是物理因果关系。
错误四:只比较![]()
还应同时检查:
MAE;
RMSE;
系数稳定性;
特征数量;
残差分布;
物理合理性。
错误五:把正则化系数直接当作物理参数
标准化后的回归系数适合比较相对重要性,但通常不能直接替代具有明确单位的材料参数。
错误六:
设置过大
如果所有系数都接近0,模型可能已经受到过强约束。
二十一、本节练习
基础练习
分别将岭回归的修改为:
0.01 0.1 1.0 10.0 100.0观察回归系数是否随着增大而逐渐减小。
进阶练习
分别将Lasso的设置为:
0.001 0.01 0.04 0.1 0.5记录每种情况下系数为0的特征数量。
物理思考
从数据集中删除“截面积”列,然后重新训练Lasso模型,观察宽度和厚度的系数如何变化,并解释原因。
工程挑战
将输出变量由最大位移改为最大应力,重新思考:
哪些输入特征应该保留?
弹性模量是否仍然重要?
截面积与应力之间应是什么关系?
模型系数符号是否符合力学规律?
二十二、本节小结
本节从多参数力学数据出发,学习了三种重要的正则化回归方法。
岭回归使用L2约束:
使所有系数整体缩小,提高模型稳定性。
Lasso使用L1约束:
能够将部分系数压缩为0,实现特征筛选。
弹性网络同时结合L1和L2:
兼顾模型稀疏性和共线特征下的稳定性。
需要记住的核心思想是:
模型更复杂模型预测一定更可靠
正则化通过牺牲少量训练集拟合能力,换取更稳定的测试表现和更清晰的工程解释。
下一节将进入决策树,学习模型如何通过一系列条件判断,自动发现结构失效、应力突变和裂纹扩展中的关键参数阈值。